Questa è una vecchia versione del documento!
Indice
Esercizio 0: Getting started -- Preprocessing, compilazione e linking
0.1) Compilare ed eseguire il seguente programma:
#include <stdio.h> #include <math.h> int main (void) { double x=3.0; printf("Radice = %f\n",sqrt(x)); return 0; }
salvato nel file ff.c con
gcc -Wall -pedantic ff.c
Chi segnala un errore? E' fallita la fase di preprocessing, la compilazione o il linking? Cosa contine il modulo oggetto se specifico l'opzione -c? Come si risolve il problema?
0.2) Cosa accade se eliminiamo la linea
#include <math.h>
? A questo punto cosa va storto? Sapete interpretare i messaggi a video e stabilire chi li ha scritti e perche'? Viene generato l'eseguibile?
0.3) Generare il modulo oggetto con
gcc -Wall -pedantic -c ff.c
Utilizzare objdump, nm, readelf per capire cosa contengono la tabella di rilocazione, la tabella dei simboli esportati ed esterni, le sezioni data, BSS e codice. (utilizzare il man e cercare su google).
0.4) Usare l'opzione -E e la -S del gcc: che cosa succede? Cosa accade specificando il flag -g assieme a -S?
Esercizio 1. Liste generiche in C
In questo esercizio si richiede di realizzare alcune funzioni che lavorano su liste generiche in C una lista generica e' rappresentata con la seguenti struct
typedef struct elem { /** chiave */ void * key; /** informazione */ void * payload; /** puntatore elemento successivo */ struct elem * next; } elem_t; typedef struct { /** la testa della lista */ elem_t * head; /** la funzione per confrontare due chiavi */ int (* compare) (void *, void *); /** la funzione per copiare una chiave */ void * (* copyk) (void *); /** la funzione per copiare un payload*/ void * (* copyp) (void *); } list_t;
la prima struttura (elem_t
) rappresenta un nodo della lista generica. Ogni nodo contiene una chiave (key
non e' possibile avere chiavi duplicate nella lista) e un campo di informazioni per quella chiave (payload
).
La seconda struttura (list_t
) permette di definire una particolare lista a partire da quella generica. Per farlo bisogna fornire tre funzioni:
compare
permette di confrontare due chiavi, ritorna 0 se sono uguali ed un valore diverso da 0 altrimenticopyk,copyp
– creano una copia di una chiave o un payload (allocando la memoria necessaria) e ritornano il puntatore alla copia (se tutto e' andato bene) o NULL (se si e' verificato un errore)
Si chiede di realizzare alcuni funzioni per manipolare la lista generica ed un main che ne testi il funzionamento.
Nel file tar-file ese1.tar potete trovare il file genList.h
con le definizioni delle strutture dati e dei prototipi delle funzioni richieste. I commenti all'interno del file sono in fomato doxygen. Sempre nel tar e' presente il file Doxyfile
che pilota la generazione della documentazione fomato HTML. Per generarla basta invocare
bash$ doxygen
e poi visualizzare il file ../html/index.html
con un browser.
Esercizio 4: Macro con parametri, macro di somma
Usare le macro con parametri per definire una macro che somma (operatore +) i propri argomenti
#define SOMMA(X,Y,Z) ......
e testarla in un opportuno main. Valutare le differenze con una funzione di prototipo
int SOMMA(int X,int Y, int Z);
Esercizio 5: Macro con parametri, macro fattoriale
Scrivere una macro con parametri che calcoli il fattoriale di un numero N, passato come parametro e ne stampi il risultato. Ad esempio, posso utilizzare la macro per calcolare il fattoriale di 4+1 con
FATTORIALE(4+1)
La macro non deve fare assunzioni su come verranno passati i parametri. Che accade annidando due chiamate della macro? Ad esempio
FATTORIALE(FATTORIALE(4+1))