Laboratorio di  Programmazione.
AA 2007/08.

Esercitazione n. 2

Scopo di questa  sessione  è di continuare ad  esercitarsi   con l' interprete di comandi (bash)  in ambiente UNIX, apprendere il ciclo  basilare  di  scrittura  di semplici programmi C, loro compilazione ed esecuzione. I programmi si limitano a leggere un input e mostrare l' output, eventualmente dopo semplici elaborazioni Già così si dispone di un potente strumento di calcolo.

  1. Creare una directory di nome Labo2  e ridefinirla come directory di default  (comando cd, v. esercitazione n.1).

  2.  
  3. Creare mediante l' editor un file di testo di nome primo.c  (nella directory Labo2)  contenente il seguente programma C che legge un carattere in input dalla tastiera e lo mostra su schermo.
  4. #include  <stdio.h>
    int main()
    {
        char inputchar; /* input è il nome di una variabile di tipo carattere*/
        scanf("%c",&inputchar); /* istruzione di lettura da stdin */
        printf(" %c \n",inputchar); /* istruzione di scrittura su stdout */
        return 0;
    }
    Verificare con in comando ls quali sono i files presenti nella directory. Compilare il programma con il comando
    gcc -std=c99 -pedantic primo.c
    Verificare con il comando
          man gcc     

      qual è  il significato dei modificatori.
  5. Verificare  di nuovo  mediante il comando
    ls -l
    quali sono e quanto sono grandi i files presenti.


  6. Cambiare il nome del file a.out in primo.x
  7.    
  8. Eseguire il file primo.x digitandone il nome  preceduto da ./  (che è il modo per indicare che il file in questione risiede nella directory corrente),  Es:  ./primo.x,  e premendo "invio". Attenzione, quando il programma viene eseguito, la prima istruzione "aspetta" silenziosamente un input da tastiera. L' input termina quando si preme il tasto "invio".

  9.  
  10. Modificare il programma precedente in modo che scriva su schermo un' informazione sul fatto che e' in attesa di input. Per ottenere questo, occorre inserire prima dell' istruzione scanf una printf(" scritta "); . Scrivere la versione modificata su un secondo file di nome secondo.c, ricompilare ed eseguire.

    ATTENZIONE: si puo' fare in modo che il compilatore generi il file eseguibile direttamente con un nome assegnato (invece del default a.out) mediante l' istruzione

    gcc -std=c99 -pedantic -o secondo.x secondo.c

  11. Dissezione dei 3 stadi del compilatore C
  12. gcc e' un comando che gestisce le tre fasi necessarie per passare dal codice sorgente (C) al codice macchina: PRECOMPILAZIONE - COMPILAZIONE - LINKING. E' possibile spezzare le tre fasi mediante la seguente sequenza di comandi:
    cpp primo.c primo.i
    cpp e'il preprocessore che legge il file primo.c per generare il file sorgente C,  primo.i,  in cui le direttive del proprocessore sono state eseguite.
    gcc -c primo.i
    viene generato da primo.i (senza più passare per il preprocessore) un file primo.o che contiene le istruzioni macchina relative al solo sorgente e quindi non eseguibili (provare ad eseguire primo.o).
    gcc primo.o
    viene generato il file a.out contenente le istruzioni macchina in forma eseguibile.
     
  13. Nella directory Labo2  creare una sottodirectory di nome dir   e  scrivervi  5 files con nomi a piacere.  Usare  quindi i seguenti comandi di shell (bash):
  14. cd ~/Labo2/dir                 # cambia la working directory
    ls -l # lista tutti files presenti
    n=0 # azzera la variabile n (contatore)
    elenco_files=* # il carattere speciale * viene sostituito dai
    # nomi di tutti i files presenti nella directory
    # corrente
    for nome in $elenco_files # itera su tutti i nomi dei files (ogni volta
    # la variabile "nome" assume un diverso valore)
    do
    if ( [ ! -d $nome ] ) # quel che segue fino a fi viene eseguito solo
    then # se il file di nome $nome NON (!) e'una dir
    n=$[$n+1] # il contatore viene incrementato
    mv $nome $nome.$n # si cambia nome a ciascun file aggiungendo al vecchio nome un intero progressivo
    fi
    done # fine del blocco da iterare
    pwd # scrive la dir corrente
    a=4 # attribuisce 4 come valore della variabile a
    echo $[$a*2] # valuta il prodotto del valore di a per 2 e lo mostra su schermo

  15. Quale e'  la directory corrente  dopo aver eseguito i comandi precedenti (pwd)?  Inserire le linee precedenti in un file di nome script nella directory di default, dare in permesso di esecuzione a quel file ( chmod u+x script ) ed eseguirlo dalla directory di default  (./script   ricordare di premettere  ./ come  indicazione che il file da eseguire risiede nella directory corrente).   L' output e' uguale ?  Quale e' la directory corrente dopo l'esecuzione dello script ?

I seguenti punti sono suggeriti come esercizi da svolgere autonomamente:
  1. Scrivere un programma C che risolva l' equazione generica di primo grado a coefficienti reali ( ax+b = 0,  nell' ipotesi che a sia diverso da zero). Compilare ed eseguire il programma con input diversi e verificare i risultati ottenuti.

    Nella lettura e scrittura di dati corrispondenti a numeri reali, le istruzioni scanf e printf richiedono un descrittore di conversione %f (o %e) invece di %c, come nel programma primo.c, o di %d, come nel caso di lettura e scrittura di interi.
     

  2. Scrivere un programma che legga un valore di x (reale) e calcoli il valore della funzione 1/x. Utilizzare il programma per studiare il limite della funzione per x -> 0. Che succede ?

    (Suggerimento: per immettere valori reali molto grandi o molto piccoli e' preferibile usare la notazione scientifica per le costanti: 2.3 1035 in C si scrive 2.3e35, 7 10-23 diviene 7e-23)