informatica:sol:laboratorio11:esercitazioni:esercitazione3
Differenze
Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.
| Entrambe le parti precedenti la revisioneRevisione precedenteProssima revisione | Revisione precedente | ||
| informatica:sol:laboratorio11:esercitazioni:esercitazione3 [01/03/2011 alle 16:54 (15 anni fa)] – [Esercizio 1. Liste generiche in C] Susanna Pelagatti | informatica:sol:laboratorio11:esercitazioni:esercitazione3 [21/03/2011 alle 16:01 (15 anni fa)] (versione attuale) – [Esercizio 5. Approfondiamo l'uso di valgrind (e alcune opzioni utili di gcc ...)] Susanna Pelagatti | ||
|---|---|---|---|
| Linea 1: | Linea 1: | ||
| + | ====== Esercitazione 3 ====== | ||
| + | |||
| + | Dove si approfondisce la conoscenza delle fasi di preprocessing, | ||
| + | |||
| ===== Esercizio 1: Getting started -- Preprocessing, | ===== Esercizio 1: Getting started -- Preprocessing, | ||
| - | 0.1) Compilare ed eseguire il seguente programma: | + | 1) Compilare ed eseguire il seguente programma: |
| <code c> | <code c> | ||
| #include < | #include < | ||
| Linea 18: | Linea 22: | ||
| Chi segnala un errore? E' fallita la fase di preprocessing, | Chi segnala un errore? E' fallita la fase di preprocessing, | ||
| - | 0.2) Cosa accade se eliminiamo la linea | + | 2) Cosa accade se eliminiamo la linea |
| <code c> | <code c> | ||
| #include < | #include < | ||
| Linea 24: | Linea 28: | ||
| ? A questo punto cosa va storto? Sapete interpretare i messaggi a video e stabilire chi li ha scritti e perche'? | ? A questo punto cosa va storto? Sapete interpretare i messaggi a video e stabilire chi li ha scritti e perche'? | ||
| - | 0.3) Generare il modulo oggetto con | + | 3) Generare il modulo oggetto con |
| < | < | ||
| gcc -Wall -pedantic -c ff.c | gcc -Wall -pedantic -c ff.c | ||
| Linea 31: | Linea 35: | ||
| Utilizzare //objdump, nm, readelf// per capire cosa contengono la tabella di rilocazione, | Utilizzare //objdump, nm, readelf// per capire cosa contengono la tabella di rilocazione, | ||
| - | 0.4) Usare l' | + | 4) Usare l' |
| - | ===== Esercizio 2: Makefile per la libreria di liste ===== | ||
| - | Con riferimento agli esercizi 1 e 3 della [[informatica: | ||
| - | * le regole per generare correttamente main.o e lista.o | ||
| - | * la regola PHONY '' | ||
| - | * la regola per generare l' | ||
| - | * un target PHONY '' | ||
| - | utilizzare dove possibile le regole implicite, le variabili e le convenzioni viste a lezione. Usare '' | ||
| - | ===== Esercizio | + | |
| + | ===== Esercizio | ||
| Usare le macro con parametri per definire una macro che somma (operatore +) i propri argomenti | Usare le macro con parametri per definire una macro che somma (operatore +) i propri argomenti | ||
| <code c> | <code c> | ||
| Linea 54: | Linea 52: | ||
| - | ===== Esercizio | + | ===== Esercizio |
| 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 | 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 | ||
| Linea 65: | Linea 63: | ||
| FATTORIALE(FATTORIALE(4+1)) | FATTORIALE(FATTORIALE(4+1)) | ||
| </ | </ | ||
| + | ===== Esercizio 4. 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 | ||
| + | <code c> | ||
| + | typedef struct elem { | ||
| + | /** chiave */ | ||
| + | void * key; | ||
| + | /** informazione */ | ||
| + | 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 *); | ||
| + | } list_t; | ||
| + | </ | ||
| + | la prima struttura ('' | ||
| + | La seconda struttura ('' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | Si chiede di realizzare le funzioni che permettono di creare/ | ||
| + | Realizzare un main di test che prova ad istanziare la lista in due versioni: una prima a valori interi usando le seguenti funzioni per il confronto e la copia: | ||
| + | <code c> | ||
| + | /** funzione di confronto per lista di interi | ||
| + | \param a puntatore intero da confrontare | ||
| + | \param b puntatore intero da confrontare | ||
| + | | ||
| + | \retval 0 se sono uguali | ||
| + | \retval p (p!=0) altrimenti | ||
| + | */ | ||
| + | int compare_int(void *a, void *b) { | ||
| + | int *_a, *_b; | ||
| + | _a = (int *) a; | ||
| + | _b = (int *) b; | ||
| + | return ((*_a) - (*_b)); | ||
| + | } | ||
| + | /** funzione di copia di un intero | ||
| + | \param a puntatore intero da copiare | ||
| + | |||
| + | \retval NULL se si sono verificati errori | ||
| + | \retval p puntatore al nuovo intero allocato (alloca memoria) | ||
| + | */ | ||
| + | void * copy_int(void *a) { | ||
| + | int * _a; | ||
| + | |||
| + | if ( ( _a = malloc(sizeof(int) ) ) == NULL ) return NULL; | ||
| + | |||
| + | *_a = * (int * ) a; | ||
| + | |||
| + | return (void *) _a; | ||
| + | } | ||
| + | </ | ||
| + | e una seconda che ha come chiavi stringhe usando analoghe funzioni per la copia ed il confronto. | ||
| + | |||
| + | ===== Esercizio 5. Approfondiamo l'uso di valgrind (e alcune opzioni utili di gcc ...) ===== | ||
| + | Compilare ed eseguire il codice seguente usando valgrind | ||
| + | <code c> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #define N 5 | ||
| + | |||
| + | int main(void) | ||
| + | { | ||
| + | int * a; | ||
| + | int i; | ||
| + | |||
| + | if ( ( a = malloc(N*sizeof(int))) == NULL ) | ||
| + | return EXIT_FAILURE; | ||
| + | srand(time(NULL)); | ||
| + | i=0; | ||
| + | while (i<N) | ||
| + | { | ||
| + | |||
| + | a[++i]=rand()%2; | ||
| + | printf(" | ||
| + | } | ||
| + | printf(" | ||
| + | return EXIT_SUCCESS; | ||
| + | } | ||
| + | </ | ||
| + | che problemi vengono segnalati ? Perche' | ||
| + | |||
| + | Provare a compilare (dopo averlo salvato in file.c) usando le seguenti opzioni di " | ||
| + | < | ||
| + | bash$ gcc -O -pedantic -Wall -Wextra -Wformat=2 -ggdb -o exe file.c | ||
| + | </ | ||
| + | viene segnato qualcosa ? Perche' | ||
| + | |||
| + | Utilizzare le opzioni sopra e valgrind per analizzare il comportamento dei programmi in {{: | ||
| + | |||
| + | Attenzione: | ||
| + | * non confondete l' | ||
| + | * la '' | ||
| + | * L' | ||
| + | |||
| + | Il '' | ||
| + | comando) come default a seconda della compilazione a cui il compilatore stesso e` stato sottoposto. Mentre il risultato della compilazione - di | ||
| + | un programma corretto ;) - non viene influenzato da un punto di vista funzionale, l'uso di opzioni diverse o di versioni diverse del | ||
| + | compilatore puo` comportare una maggiore o minore capacita` di rilevazione di possibili " | ||
| + | (come anche una diversa capacita` di ottimizzazione - nel tempo o nello spazio - dell' | ||
| + | comportamento funzionalmente diverso se il codice sorgente contiene errori. | ||
| + | |||
| + | |||
informatica/sol/laboratorio11/esercitazioni/esercitazione3.1298998469.txt.gz · Ultima modifica: 01/03/2011 alle 16:54 (15 anni fa) da Susanna Pelagatti
