Conceptes generals de programació

De Cacauet Wiki
Salta a la navegació Salta a la cerca

...intro...

Codi font i executable

Tipus de codi:

  • Codi font: conjunt d'arxius de text amb instruccions d'alt nivell, fàcilment llegible per humans, no executable per la computadora. L'objectiu és facilitar la tasca als programadors.
  • Codi màquina o executable: conjunt d'instruccions directament executables per un microprocessador o CPU. Alta complexitat. Instruccions molt específiques que realitzen tasques de molt baix nivell.

Característiques:

  • El procés per generar codi executable a partir del codi font és la compilació.
  • No és possible (o seria altíssimament complex) deduïr un codi font a partir d'un executable. D'aquí la importància del "codi lliure".
  • Una sola instrucció de codi font pot produïr centenars o milers d'instruccions màquina.
  • Una compilació és específica per una màquina i arquitectura. Els executables no són portables (tot i que sí es podrien executar amb un emulador).


Llenguatges compilats vs. interpretats

Distingirem entre:

Llegiu els articles de la Wikipèdia al respecte.

Algunes notes addicionals:

  • El llenguatge compilat revisa la correcció del tot el codi abans de generar l'executable.
  • El llenguatge interpretat agafa una instrucció a cada moment i no comprova la totalitat, només el què està a punt d'executar.
  • El compilador només tradueix un sol cop a codi màquina. A partir d'aquí l'execució del codi màquina (executable) és directa.
  • Un intèrpret ha de traduïr de cou el programa cada cop que s'executa.
  • Els llenguatges interpretats solen ser típicament 10 cops més lents que els executables.
  • Els llenguatges compilats permeten la ocultació del codi font. Els interpretats no.


Avantatges de cadascun:

  • Compilats = rendiment: uns 10 cops més ràpids.
  • Interpretats = portabilitat: el mateix codi pot funcionar el diverses plataformes amb diferent hardware.


Compiladors i intèrprets

De fet, no son tan diferents. Consten de les següents parts, quasi totes comunes menys la darrera part.

  • Preprocessador: expandeixen macros, substitueixen constants, etc.
  • Anàlisi lèxica: separen els tokens (elements del llenguatge).
  • Anàlisi sintàctica: comprovació dels tipus
  • Anàlisi semàntica: (semàntica = significat) es decideix què fa la instrucció.
  • Generació/execució:
    • El compilador enllaça les llibreries (linker) i genera un arxiu executable.
    • L'intèrpret executa directament les instruccions.


Codi intermig i màquines virtuals

Jvm-arquitectura.png

Hi ha un seguit de llenguatges com Java que venen a ser híbrids. Java es compila (arxiu *.class) però no sobre l'arquitectura de la màquina en què treballem, sinó sobre l'arquitectura de la Java Virtual Machine:

Així, el codi resultant no es pot executar directament sobre el nostre hardware, sinó que cal una màquina virtual que realitzi la traducció final. L'objectiu és aconseguir un codi multiplataforma, fent que aquest codi sigui exectuable en qualsevol plataforma que implementi la JVM (Java Virtual Machine).

Accelerant les VMs: JIT i d'altres

La JVM fa que l'execució sigui molt més lenta, però l'aparició de l'intèrpret del la JVM anomenat JIT (Just In Time) va accelerar molt el rendiment. El què fa el JIT és permetre la reutiltizació del codi executable sobre la plataforma, tenint rendiments propers als del codi natiu.

Llegir més a JIT a Wikipèdia.

Python, té un altre model, no té una VM com el Java, sinó un intèrpret clàssic. Però també implementa un sistema per millorar el rendiment realitzant traduccions al C del codi Python, que es poden compilar sobre la plataforma. Això ho realitza automàticament (com el JIT) i és transparent al desenvolupador.

És per aquest motiu que en determinats frameworks podeu trobar arxius *.pyc al cosat del vostre *.py


Tipatge estàtic i dinàmic

Amb el tipatge ens referim a si les variables emprades en el llenguatge contenen un tipus de dades prefixat des de la seva definició (sencer, string, etc.) o si una mateixa variable pot contenir diferents tipus de dades segons com l'emprem.

  • Tipatge estàtic (Java, C/C++): la variable conté un tipus de dada fixat (pot canviar el valor, però no el tipus)
  • Tipatge dinàmic (PHP, Python): la mateixa variable pot contenir un tipus de dades diferents segons com l'emprem.

Exemple en Java (tipus estàtic)

Observa i posa en pràctica aquest exemple:

class suma
{  
    public static void main(String args[])
    {
        // Creem string del missatge
        String missatge = new String("Hola! el resultat de la suma és = ");
        int primer, segon, resultat;
        
        // Comprovem l'entrada de paràmetres
        if (args.length!=2) {
            System.out.println( "ERROR: has de passar 2 nombres" );
            return;
        }
        
        // Capturem els paràmetres entrats i calculem
        primer = Integer.parseInt( args[0] );
        segon = Integer.parseInt( args[1] );
        resultat = primer + segon; // aquí "+" és suma
        
        // mostrem per consola
        System.out.println( missatge + resultat ); // aquí "+" és concatenació (String)
    }
}


  1. Crea el programa anterior en un fitxer suma.java
  2. Compila'l amb:
    $ javac suma
  3. Apareixerà un arxiu suma.class . Executa'l amb:
    $ java suma
    (et donarà un error perquè no has posat arguments)
  4. Executa'l amb paràmetres:
    $ java suma 10 6

Exemple amb Python (tipus dinàmic)

En aquest cas no cal indicar de quin tipus son les variables al definir-les.

import sys

# Definim la funcio main()
def main():
    msg = "El resultat es = "
    
    if len(sys.argv)!=3:
        print("Has d'introduir 2 nombres")
        return False
    
    primer = int(sys.argv[1])
    segon = int(sys.argv[2])
    resultat = primer + segon
        
    print( msg + str(resultat) )

if __name__=="__main__":
    main()


Exercicis

  1. Realitza els exemples anteriors però canviant els integers per floats.