Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/wikka.php on line 315 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/libs/Wakka.class.php on line 176 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/libs/Wakka.class.php on line 463 Deprecated: Function set_magic_quotes_runtime() is deprecated in /home/demetres/public_html/didattica/ae/wikka.php on line 120 Deprecated: Function ereg() is deprecated in /home/demetres/public_html/didattica/ae/libs/Wakka.class.php on line 648 Ingegneria degli Algoritmi: Esercizi sul linguagggio C

Ingegneria degli Algoritmi

Corso di Laurea in Ingegneria Informatica e Automatica - A.A. 2014-2015

HomePage | Avvisi | Diario lezioni | Programma | Materiale didattico | Esami | Forum | Login
Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/safehtml.php on line 308 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 159 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 161 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 162 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 163 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 165 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 166 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 167 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 243 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 250 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 259 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 266 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 273 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 280 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 467 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 469 Deprecated: Assigning the return value of new by reference is deprecated in /home/demetres/public_html/didattica/ae/3rdparty/core/safehtml/classes/HTMLSax.php on line 471

Esercizi sul linguagggio C


Esercizio 1

Scrivere una funzione alloc_array che alloca dinamicamente un blocco di memoria di dimensione in byte specificata dal chiamante. Il puntatore al blocco allocato deve essere passato al chiamante per indirizzo come primo parametro. La funzione deve restituire 0 se l'allocazione è andata a buon fine (malloc restituisce un puntatore diverso da NULL), e -1 altrimenti. Scrivere il programma in modo da poter compilare con successo il seguente programma di prova:

#include <stdio.h>
#include <stdlib.h>

// inserire qui la definizione della funzione alloc_array

int main() {
    char* p;
    int errcode = alloc_array(&p, 256); // alloca blocco di 256 byte
    if (!errcode) free(p);
    return errcode;
}


Esercizio 2

Dopo aver consultato gli specificatori di formato della funzione printf, dire cosa stampa il seguente programma e perché:

#include <stdio.h>

int main(){
    unsigned short x = 65535;
    printf("%hu\n", x);
    printf("%hd\n", x);
    return 0;
}


Esercizio 3

Si compili ed esegua il seguente programma C:

main.c
#include <stdio.h>

int main(){
    printf("char %u\n", (unsigned)sizeof(char));
    printf("short %u\n", (unsigned)sizeof(short));
    printf("int %u\n", (unsigned)sizeof(int));
    printf("long %u\n", (unsigned)sizeof(long));
    printf("long long %u\n", (unsigned)sizeof(long long));
    printf("float %u\n", (unsigned)sizeof(float));
    printf("double %u\n", (unsigned)sizeof(double));
    printf("long double %u\n", (unsigned)sizeof(long double));
    printf("void* %u\n", (unsigned)sizeof(void*));
    printf("int* %u\n", (unsigned)sizeof(int*));
    printf("int** %u\n", (unsigned)sizeof(int**));
    return 0;
}


riportare il modello di computer (CPU, sistema operativo e compilatore) e i risultati ottenuti.

Esercizio 4

Usare il seguente programma per determinare il verso di crescita della stack dei record di attivazione della propria piattaforma di calcolo:

#include <stdio.h>

void r(int n) {
    if (n < 1) return;
    printf("%lu\n", (unsigned long)&n);
    r(n-1);
}

int main() {
    r(10);
    return 0;
}


Compilare il programma in gcc con l'opzione -O0 e riportare l'output dell'esecuzione del programma.

Esercizio 5

Sia x una variabile di tipo int, p una variabile di tipo int* e q una variabile di tipo int**. Per ciascuna delle seguenti espressioni C:

  1. x
  2. x+1
  3. &x
  4. &(x+1)
  5. &&x
  6. *x
  7. *&x
  8. &*q
  9. *&*&x
  10. &p
  11. *p
  12. *p+x
  13. **q
  14. &**q
  15. &q

dire:

  1. se è una espressione valida
  2. in caso affermativo determinarne:

Ad esempio, l'espressione *p-5 è un Rvalue di tipo int.

Esercizio 6

Scrivere una funzione C get_min che, dato un array di interi e la sua dimensione, restituisce l'indirizzo del primo byte della cella contenente il minimo dell'array. La funzione deve avere il seguente prototipo:

int* get_min(int* v, int n);


Dove v è l'array e n la sua dimensione.

Scrivere inoltre un main di prova che alloca dinamicamente un array di n=1000 elementi, lo inizializza in modo tale che v[i]=55+(n-i) % 100, chiama la funzione get_min e stampa il valore del minimo calcolato. Verificare con memcheck che non ci siano errori nell'uso della memoria.

Esercizio 7

Scrivere una funzione get_bit_array che, dato un numero x a 64 bit senza segno, restituisce un array v di 64 char allocato dinamicamente tale che v[i] vale 1 se e solo il bit i-esimo di x, con i compreso tra 0 (bit meno significativo) e 63 (bit più significativo), è settato a 1, e 0 altrimenti. Scrivere il programma in modo da poter compilare correttamente il seguente programma di prova:

#include <stdio.h>
#include <stdlib.h>

// inserire qui la definizione della funzione get_bit_array

int main() {
    int i;
    unsigned long x = 5234971543233487563;
    char* v = get_bit_array(x);
    for (i=63; i>=0; i--) printf("%d", v[i]);
    printf("\n");
    free(v);
    return 0;
}


Il programma deve stampare: 0100100010100110010110101110000111101011101101011110001011001011.

Esercizio 8

Scrivere una funzione int cerca(int* v, int n, int x) che, dato un array ordinato di interi v di dimensione n e un intero x, restituisce 1 se x è presente nell'array, e 0 altrimenti. La funzione deve richiedere tempo O(log n). Scrivere un main di prova per testare la correttezza della funzione realizzata. Produrre una variante iterativa e una ricorsiva della funzione.

Esercizio 9

Scrivere una funzione void bubblesort(int* v, int n) che ordina l'array v di n interi passato come parametro usando l'algoritmo di ordinamento a bolle (bubblesort). Scrivere un main di prova per testare la correttezza della funzione realizzata.

Esercizio 10

Scrivere una funzione void merge(int* v, int i, int m, int j, int* temp) che, dato un array v, fonde le due porzioni da v[i] a v[m-1] e da v[m] a v[j-1], che si assume siano internamente ordinate, in modo che i j-i interi inizialmente presenti nelle due porzioni appaiano alla fine ordinati nella porzione dell'array che va da v[i] a v[j-1]. Usare come appoggio l'array temp, che si assume sia di dimensione almeno j-i. La realizzazione di questo esercizio è preliminare all'esercizio 8. Scrivere un main di prova per testare la correttezza della funzione realizzata.

Ad esempio, consideriamo l'array:

v={5, 6, 9, 12, 1, 4, 7}

e gli indici i=0, m=4 e j=7. Le due porzioni internamente ordinate sono {5, 6, 9, 12} (indici da 0 a 3) e {1, 4, 7} (indici da 4 a 6). Dopo l'esecuzione della funzione merge, l'array deve essere:

v={1, 4, 5, 6, 7, 9, 12}

La funzione deve richiedere tempo O(j-i).

Esercizio 11

Scrivere una funzione void mergesort(int* v, int n) che ordina l'array v di n interi passato come parametro usando l'algoritmo di ordinamento per fusione (mergesort). Scrivere un main di prova per testare la correttezza della funzione realizzata.

Esercizio 12

Scrivere una funzione void get_freq(int* v, int n, int* most_freq, int* less_freq) che, dato un array v di interi di dimensione n, restituisce in most_freq l'elemento più frequente di v (cioè quello che occorre il maggior numero di volte) e in less_freq l'elemento meno frequente. L'algoritmo deve essere il più possibile efficiente asintoticamente e certamente meno che quadratico. Scrivere un programma di prova per testare la correttezza della funzione scritta.

Esercizio 13

Confrontare sperimentalmente il tempo richiesto dalla soluzione all'esercizio 8 compilata:


usare il comando time per misurare le prestazioni, facendo la media dei tempi real ottenuti su esecuzioni diverse e verificando che il tempo speso da processi in background è il più basso possibile. L'array di input dovrebbe contenere almeno 1 milione di interi. Riportare insieme alle misurazioni le caratteristiche software/hardware della piattaforma usata (CPU, memoria, sistema operativo, compilatore, ecc.)

Esercizio 14

Scrivere una funzione int codifica(short a, short b) che, dati due short a e b, restituisce un opportuno int da cui sia possibile in seguito ricostruire i due interi a e b. Scrivere poi una seconda funzione void decodifica(int x, short* ap, short* bp) che, dato un intero x precedentemente restituito da codifica, restituisce in *ap e in *bp gli interi a e b originari codificati in x.

Si assuma che sizeof(int)==2*sizeof(short).

Si consideri ad esempio il seguente programma di prova:

main.c
#include <stdio.h>

int main(){
    short a, b;
    int x = codifica(971, 1080);
    decodifica(x, &a, &b);
    printf("a=%hd, b=%hd\n", a, b); // stampa a=971, b=1080
}


Esercizio 15

Scrivere una funzione int** allocaMatriceInt(unsigned int r, unsigned int c) che alloca dinamicamente una matrice di interi con r righe e c colonne e restituisce l'indirizzo della matrice. Allocare separatamente le righe e restituire un array di puntatori alle righe. Scrivere la corrispondente funzione void deallocaMatriceInt(int** m, int r) che libera la memoria precedentemente allocata con allocaMatriceInt, assumendo che la matrice abbia r righe. Scrivere un programma di prova per verificare la correttezza delle funzioni scritte.

Esercizio 16

Si scrivano le seguenti funzioni per la gestione di matrici di oggetti di dimensione arbitraria:


Si consideri ad esempio il seguente programma di prova:

testMatrici.c
int main(){
    void* m = newMatrix(10, 20, sizeof(double));
    double x = 3.14, y;
    setCell(m, 2, 4, &x);
    getCell(m, 2, 4, &y);
    printf("la cella (2,4) contiene il valore: %f\n", y);
    printf("la cella (2,4) contiene il valore: %f\n", *(double*)cellAt(m, 2, 4));
    *(double*)cellAt(m, 3, 1) = 2.56;
    getCell(m, 3, 1, &y);
    printf("la cella (3,1) contiene il valore: %f\n", y);
    deleteMatrix(m);
    return 0;
}


Suggerimento: in newMatrix allocare un unico blocco contiguo di 2*sizeof(unsigned)+r*c*k byte contenente:

Nota: unsigned è equivalente in C a unsigned int.

Esercizio 17

Scrivere una funzione C che, data una stringa, restituisce una nuova stringa ottenuta da quella di partenza rovesciandola. Si consideri ad esempio il seguente programma di prova:

main.c
#include <stdio.h>

int main(){
    char* s = rovescia("roma");
    printf("%s\n", s); // stampa amor
    free(s);
}


Nota: lo specificatore di formato %s serve per stampare una stringa il cui indirizzo è passato come argomento alla printf.

Esercizio 18

Modificare la funzione scritta nell'esercizio 17 in modo che non dia l'indirizzo della nuova stringa come valore restituito, ma come parametro passato per riferimento. Si veda il seguente programma di prova:

main.c
#include <stdio.h>

int main(){
    char* s;
    rovescia("roma", &s);
    printf("%s\n", s); // stampa amor
    free(s);
}


Esercizio 19

Scrivere una funzione void concat(char* s1, char* s2, char** p) per concatenare due stringhe in un nuovo blocco restituito per parametro.

Esercizio 20

Scrivere una funzione C void occorrenze(char* s, char c, char*** occp, int* np) che, data una stringa s e un carattere c, conta il numero di occorrenze di c in s, che viene restituito in *np, e restituisce in *occp l'indirizzo di un nuovo array di char* contentente gli indirizzi di ciascuna delle occorrenze di c in s.

Si consideri ad esempio il seguente programma di prova:

main.c
#include <stdio.h>

int main(){
    int i, n;
    char** occ;
    occorrenze("ingegneria", 'g', &occ, &n);
    for (i=0; i<n; ++i) printf("%s\n", occ[i]); // stampa gegneria e gneria
    free(occ);
}


Esercizio 21

Scrivere una funzione int tokenize(char* s, char* f, char*** tp, int* np) che, data una stringa s, crea un array di stringhe che contiene tutti i token di s separati da un qualche carattere della stringa f. La funzione deve passare al chiamante in *tp l'indirizzo dell'array dei token creato e in *np la sua dimensione. Inoltre, deve restituire 0 se l'operazione ha avuto successo e -1 altrimenti. La funzione deve richiedere tempo O(strlen(s)*strlen(f)) e usare spazio O(strlen(s)+strlen(f)).

Si consideri ad esempio il seguente programma di prova:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char** t;
    int n, i;
    if (tokenize("uno, due, tre:\n fante cavallo e re", " ,:\n", &t, &n)==-1)
        exit((fprintf(stderr, "error in tokenize\n"), 1));
    for (i=0; i<n; i++) { printf("%s\n", t[i]); free(t[i]); }
    free(t);
    return 0;
}


Il programma dovrebbe stampare:

uno
due
tre
fante
cavallo
e
re


Esercizio 22

Scrivere una funzione void short2binary(short x, char* s) che, dato uno short x e un puntatore s a un buffer (cioè zona di memoria libera) di almeno 8*sizeof(short)+1 byte, scrive in quel buffer una stringa C formata dai caratteri '0' e '1' corrispondenti ai bit di x, con s[0] il bit più significativo di x.

Si consideri ad esempio il seguente programma di prova:

short2binary.c
#include <stdio.h>
#include <stdlib.h>

int main(){
    char* s = malloc(8*sizeof(short)+1);
    short2binary(22971, s);
    printf("%s\n", s); // stampa: 0101100110111011
    free(s);
}


Esercizio 23

In base alle regole di precedenza e associatività degli operatori C, scrivere per ciascuna delle seguenti espressioni un'espressione equivalente che usa parentesi per esplicitare l'ordine di valutazione degli operatori (es: x+y*z => x+(y*z)):

  1. *p++
  2. y = ~x - x + z / 2 * k ^ w
  3. x = y = z
  4. x < y + z
  5. x == y < z
  6. x + y << z ? 1 : x, y
  7. x < y <= z
  8. *p == NULL ? -1 : 0
  9. p = malloc(n*sizeof(int)) == NULL

Esercizio 24

Completare il seguente programma in modo che stampi su schermo i parametri passati al programma (ad esempio da riga di comando):

main.c
int main(int argc, char** argv) {
    ...
    return 0;
}


Si tenga presente che:

  1. argv è un array di stringhe che contiene i parametri passati al programma;
  2. argc è la dimensione di argv.

Sctrivere la soluzione in modo da ottenere il seguente risultato:

$ gcc main.c
$ ./a.out pippo paperino pluto
pippo
paperino
pluto


Esercizio 25

Si consideri la seguente dichiarazione di un nodo di una lista collegata di interi:

typedef struct node {
    int elem;
    struct node* next;
} node;


  1. Scrivere una funzione nodo* add(int elem, node* list) che, dato un puntatore al primo nodo di una lista, o NULL per indicare una lista vuota, inserisce in testa alla lista un nuovo nodo contenente il dato elem, e restituisce il puntatore al nodo creato.
  2. Scrivere una funzione void print(node* list) che, data una lista, ne stampa il contenuto nel formato: [elem1, elem2, elem3, ...].
  3. Scrivere una funzione void delete(node* list) che, data una lista, ne dealloca tutti i nodi.

Usare il seguente programma di prova:

main.c
#include <stdio.h>

typedef struct node {
    int elem;
    struct node* next;
} node;

// mettere qui la definizione delle funzioni add, print e delete

int main() {
    node* list = add(5, add(3, add(2, add(7, add(4, add(1, add(6, NULL)))))));
    print(list); // stampa: [5, 3, 2, 7, 4, 1, 6]
    delete(list);
    return 0;
}


Verificare con memcheck (Valgrind) che il programma usi la memoria correttamente.

Esercizio 26 (espressioni di tipo)

Si traduca in C la seguente dichiarazione di variabile usando le regole sulla specifica di espressioni di tipo (si veda [P2]):

"v è un array di 64 puntatori a puntatori a funzione che prende come parametro un puntatore a funzione senza argomenti che restituisce un puntatore a un array di 16 float, e restituisce un puntatore a funzione con due argomenti int che restituisce void."

Esercizio 27 (espressioni di tipo)

Si traduca in italiano la seguente dichiarazione C:

int (*(*p)[7])(int *(*f[20])(float** m, int r), void* q[20]);

Esercizio 28 (espressioni di tipo)

Si traducano in italiano le seguenti dichiarazioni C:

  1. char ****q[30];
  2. char **(**q)[30];
  3. int (x)[];
  4. long (*a[])( char, char );
  5. int *(*(*(*b)())[10])();
  6. char *strprt( char (*)( int ), unsigned char );
  7. int (*ab[])( unsigned int );

Esercizio 29 (puntatori a funzione)

Si fornisca una propria definizione della funzione standard qsort di ordinamento, usando un algoritmo a scelta. La funzione ha il seguente prototipo dichiarato nella header stdlib.h:

void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));

dove:

Esercizio 29 (preprocessore)

Cosa stampa il seguente programma e perché?

#include <stdio.h>

#define STAMPA_SE_POSITIVO(x) if ((x) > 0) printf("%d\n", x)

int main() {
    int x = 0;
    STAMPA_SE_POSITIVO(++x);
    return 0;
}


Si ricordi che, se una variabile intera x vale k, l'espressione ++x vale k+1 e la sua valutazione incrementa x di 1 come effetto collaterale (side-effect).

Esercizio 30 (preprocessore)

Cosa stampa questo programma?

scambia1.c
#include <stdio.h>

#define SCAMBIA(a, b)  temp=a; a=b; b=temp;

int x = 5, y = 10, temp;

int main() {

    if (x > y) SCAMBIA(x, y);

    printf("x=%d, y=%d\n", x, y);

    return 0;
}


Il risultato è quello che ci si aspetta? In caso contrario, correggere il programma senza toccare il main.

Esercizio 31 (preprocessore)

Si provi a compilare il seguente programma:

scambia2.c
#define SCAMBIA(a, b)  { int temp=a; a=b; b=temp; }

int x = 10, y = 5, z = 4;

int main() {

    if (x < 0)
        SCAMBIA(x, y);
    else
        SCAMBIA(x, z);

    return 0;
}


Che errore viene segnalato? Correggere il programma senza toccare il main.

Esercizio 32 (preprocessore)

Fornire una soluzione alternativa all'esercizio 14 in cui codifica e decodifica sono macro piuttosto che funzioni C. Usare il seguente programma di prova che misura il tempo necessario per 100 milioni di invocazioni di codifica e decodifica:

main.c
#include <stdio.h>
#include <time.h>

int main(){
    int i;
    long start = clock();
    for (i=0; i<100000000; i++){
        short a, b;
        int x = codifica(971, 1080);
        decodifica(x, &a, &b);
    }
    printf("elapsed time: %f sec\n", (clock()-start)/(double)CLOCKS_PER_SEC);
}


Che differenze di tempi si riscontrano definendo codifica e decodifica come macro C piuttosto che come funzioni C?


Esercizio 33 (tipi di dato astratti)

Realizzare in C un tipo di dato astratto pila di interi (stack) definendo un opportuno tipo intstack, con le seguenti operazioni:


In particolare:

  1. Creare una header intstack.h contenente:
    • la dichiarazione di un tipo intstack come alias di una struttura incompleta struct intstack
    • i prototipi delle funzioni del tipo di dato matrice previste dall'esercizio
  2. Creare un file intstack.c contenente:
    • la dichiarazione del tipo struct intstack completo di tutti i campi richiesti da un oggetto intstack
    • la definizione delle funzioni che operano su oggetti intstack usando una lista collegata semplice
  3. Creare un file intstack_test.c contenente un programma di prova per testare il funzionamento del codice scritto

Esercizio 34 (tipi di dato astratti)

Realizzare in C un tipo di dato astratto stack analogo a quello definito nell'esercizio 9, ma in cui il tipo degli elementi è generico:


Scrivere un programma di prova per testare il funzionamento del codice scritto.

Suggerimento: usare la funzione memcpy definita in <string.h> per copiare i byte dei valori da leggere/scrivere nella pila.

Esercizio 35 (tipi di dato astratti)

Realizzare in C un tipo di dato astratto matrice di interi definendo un opportuno tipo intmat, con le seguenti operazioni:


In particolare:

  1. Creare una header intmat.h contenente:
    • la dichiarazione di un tipo intmat come alias di una struttura incompleta struct intmat
    • i prototipi delle funzioni del tipo di dato matrice previste dall'esercizio
  2. Creare un file intmat.c contenente:
    • la dichiarazione del tipo struct intmat completo di tutti i campi richiesti da un oggetto intmat (es. numero righe, numero colonne, puntatore alla matrice dei dati)
    • la definizione delle funzioni che operano su oggetti intmat
  3. Creare un file intmat_test.c contenente un programma di prova per testare il funzionamento del codice scritto

Suggerimento: la matrice deve essere allocata dinamicamente, usando un array di puntatori alle righe della matrice, ciascuna allocata indipendentemente come array di interi (come avviene in Java).

Esercizio 36 (tipi di dato astratti, puntatori a funzione)

Realizzare in C un tipo di dato astratto matrice analogo a quello definito nell'esercizio 10, ma in cui il tipo degli elementi è generico:


Scrivere un programma di prova per testare il funzionamento del codice scritto.

Suggerimento: usare la funzione memcpy definita in <string.h> per copiare i byte dei valori da leggere/scrivere nelle celle della matrice.

Esercizio 37

Si scriva un makefile per compilare in modo incrementale un programma formato dai seguenti file, in modo che ogni modifica a un file implichi il minimo numero di passi di ricompilazione dell'intero programma. Il file eseguibile di output deve chiamarsi versione1.

F.h
#ifndef _F_
#define _F_

#ifndef MESSAGE
#define MESSAGE "[versione 1] "
#endif

#define PRINT(x) printf("%s%s", MESSAGE, x)

#endif

A.h
#ifndef _A_
#define _A_

#include "F.h"

void a();

#endif

A.c
#include <stdio.h>
#include "A.h"
#include "B.h"

void a() {
    PRINT("a\n");
    b();
}

B.h
#ifndef _B_
#define _B_

#include "F.h"

void b();

#endif

B.c
#include <stdio.h>
#include "B.h"

void b() {
    PRINT("b\n");
}

main.c
#include <stdio.h>
#include "A.h"

int main() {
    PRINT("main\n");
    a();
    return 0;
}


Esercizio 38

Senza modificare in alcun modo i file .c e .h dell'esercizio 1, si estenda il makefile in modo che vengano create due versioni del programma:


Esercizio 39

Si crei una directory di lavoro progetto con la seguente struttura contenente i file dell'esercizio 2:

Senza modificare in alcun modo i file .c e .h, si estenda quindi il makefile dell'esercizio 2 adattandolo alla nuova struttura in modo che i file oggetto (.o) e i file eseguibili prodotti vengano a trovarsi nella directory bin.

Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by Wikka Wakka Wiki 1.1.6.3
Page was generated in 0.1497 seconds