Strumenti Utente

Strumenti Sito


informatica:sol:laboratorio11:esercitazioni:esercitazione3

Questa è una vecchia versione del documento!


Esercizio 1: 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 2: Makefile per la libreria di liste

Con riferimento agli esercizi 1 e 3 della esercitazione 1 , definire un file Makefile che contenga

  • le regole per generare correttamente main.o e lista.o
  • la regola PHONY lib per generare correttamente la libreria libList.a
  • la regola per generare l'eseguibile a partire da oggetti e librerie
  • un target PHONY cleanall che elimini gli oggetti e gli eseguibili

utilizzare dove possibile le regole implicite, le variabili e le convenzioni viste a lezione. Usare gcc -MM per generare automaticamente le liste di dipendenze per i target relativi ai moduli oggetto.

Esercizio 3: 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 4: 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)) 

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 */
  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 (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 altrimenti
  • copyk,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 le funzioni che permettono di creare/distruggere una lista generica e quelle per inserire ed estrarre un elemento generico. 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:

/** 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 poi con delle stringhe usando analoghe funzioni per la copia ed il confronto.

informatica/sol/laboratorio11/esercitazioni/esercitazione3.1298998506.txt.gz · Ultima modifica: 01/03/2011 alle 16:55 (15 anni fa) da Susanna Pelagatti

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki