Laboratorio di Programmazione. AA 2007/08.
Esercitazione n. 6

Scopo di questa esercitazione è di familiarizzarsi con la compilazione separata di files diversi  contenenti functions, e  con  puntatori e array .

Al solito, si suggerisce di creare una directory apposita per i files relativi a questa esercitazione.
Per i primi due esercizi, si consiglia di usare l' opzione -Wall nel compilare i files (in modo da ottenere tutti i messaggi di errore, a qualsiasi livello  di gravita').


  1. Facciamo riferimento alla function toup dell'  esercizio n.3  della precedente sessione di laboratorio. Lasciare nel file .c del precedente esercizio solo il codice relativo al main (con la dichiarazione globale della function, posizionandola  cioè prima del main). Cambiare nome al file chiamandolo prog.c (ricordiamo come si fa usando la shell ?).Quindi scrivere un secondo file (chiamandolo ad esempio fun.c) contenente solo il codice relativo alla function. E' possibile compilare separatamente i due files e creare un unico eseguibile mediante il comando
       gcc -std=c99 -pedantic -Wall prog.c fun.c -o prog.x
    Il cui effetto e' di leggere i due files prog.c e fun.c, compilarli e creare dai rispettivi codici un file eseguibile dal nome prog.x. Provare a compilare ed eseguire.

    E' anche possibile compilare in momenti diversi i due files. Il comando 

     
    gcc -std=c99 -pedantic -Wall -c fun.c
    compila il solo file fun.c senza tentare di eseguire le operazioni di linking. Il risultato di tale compilazione sarà un file di nome fun.o che contiene codice macchina non rilocato (non eseguibile). Questo potra' utilizzato per creare il file eseguibile, per esempio contestualmente alla compilazione di prog.c, con il comando
    gcc -std=c99 -pedantic -Wall -o prog.x prog.c fun.o


  2. Dato il seguente programma
       #include <stdio.h>

    int main(void){

    float a= 1.30, *ip, *iq;

    ip = &a;

    iq = ip;

    printf("valore di a: %f,\

    indirizzo di a: %p \n", a, &a);

    return 0;

    }

    Aggiungere anche la scrittura di
     *ip, &ip, ip
    con i convertitori di formato  corretti  ( %p per i puntatori e %f per i float ). (N.B. per scrivere il valore di un puntatore mediante printf sarebbe più  corretto  passare alla printf un cast esplicito del puntatore  a puntatore void. Tuttavia, in assenza del cast, al peggio gcc  scrive un messaggio di warning).


  3. Qual e' l' output di questo programma ?
     
    #include <stdio.h>
    void fun(int, int *);

    int main(void)
    {
    int u,v;
    u=5;
    v=2;
    fun(u,&v);
    printf("%d %d \n",u,v);
    return 0;
    }
    void fun(int x, int *y)
    {
    int u=-10,v;
    v = x + *y;
    x = v - *y;
    *y = x - u;
    return;
    }

  4. Usare l' operatore sizeof  per ricavare l' occupazione di memoria di: un puntatore a interi, un puntatore a float, uno a double e un puntatore a char.


  5. Nel seguente programma si vorrebbero scrivere i  valori dei puntatori e delle rispettive indirezioni  per ciascuna variabile. C'è però  un errore grave. Compilare il programma così com' è ed eseguirlo. Dopo aver individuato l' errore, correggerlo e vedere quale è l'output corretto. Cosa è cambiato rispetto a prima ?
    #include <stdio.h>


    int main(void)
    {
    int i=10,*ip;
    float r=22.45,*rp;
    double d=3.1416,*dp;
    char c='a',*cp;


    printf(" puntatore = %p, val= %d \n",ip,*ip);
    printf(" puntatore = %p, val= %f \n",rp,*rp);
    printf(" puntatore = %p, val= %lf \n",dp,*dp);
    printf(" puntatore = %p, val= %c \n",cp,*cp);

    return 0;
    }


  6. Dato il seguente programma
       #include <stdio.h>
    int main(void){
    float a[]= { 1.30, 2.30, 3.30, 14.60}, *ip, *iq;
    ip = &a[0];
    iq = ip;
    printf("valore di a[0]: %f,indirizzo di a[0]: %p \n", a[0], &a[0]);
    return 0;
    }
    Aggiungere anche la scrittura di
     *ip, &ip, ip, a (con gli opportuni convertitori di formato)
    e interpretare i risultati. Aggiungere quindi anche la stampa di
     *ip + 3 e  *(ip+3)
    ed interpretare anche questi risultati.

  7. Scrivere un programma che dichiari un array float di 10 elementi e poi legga i valori e ne calcoli la somma delle radici quadrate (e la scriva).

  8. Scrivere una function che utilizzi un puntatore a interi per modificare una variabile intera  del programma chiamante,  moltiplicandone il valore per 5. La function deve avere come argomento  un puntatore ad interi  e non tornare nulla esplicitamente.