🚀 Nuova versione beta disponibile! Feedback o problemi? Contattaci

Esercizi Macro Preprocessore Avanzate in C

Codegrind TeamJul 12 2024

Ecco degli esercizi avanzati con soluzione per praticare l’uso delle macro del preprocessore in C.

Esercizio 1: Macro per il Logging

Creare una macro per il logging con informazioni di file e linea.
#include <stdio.h>

#define LOG(msg) printf("LOG: %s - %s:%d\n", msg, __FILE__, __LINE__)

int main() {
    LOG("Inizio del programma");
    printf("Esempio di logging\n");
    LOG("Fine del programma");
    return 0;
}

Esercizio 2: Macro Variadiche per il Logging

Creare una macro variadica per il logging che accetti un formato e argomenti variabili.
#include <stdio.h>

#define LOG(fmt, ...) printf("LOG: %s:%d: " fmt "\n", __FILE__, __LINE__, __VA_ARGS__)

int main() {
    LOG("Valore di x: %d", 10);
    LOG("Stringa: %s, Valore di y: %f", "test", 3.14);
    return 0;
}

Esercizio 3: Concatenazione di Token Avanzata

Utilizzare la concatenazione di token per creare identificatori dinamici.
#include <stdio.h>

#define CONCAT(x, y) x##y

int main() {
    int xy = 100;
    printf("Valore di xy: %d\n", CONCAT(x, y));
    return 0;
}

Esercizio 4: Stringificazione di Token Avanzata

Utilizzare la stringificazione di token per creare messaggi di errore personalizzati.
#include <stdio.h>

#define STRINGIFY(x) #x
#define ERROR_MSG(msg) printf("Errore: %s\n", STRINGIFY(msg))

int main() {
    ERROR_MSG(C'è stato un errore);
    return 0;
}

Esercizio 5: Macro per il Controllo delle Condizioni

Creare una macro per controllare le condizioni e stampare un messaggio di errore se la condizione non è soddisfatta.
#include <stdio.h>

#define CHECK(cond) do { if (!(cond)) printf("Errore: %s non soddisfatta in %s:%d\n", #cond, __FILE__, __LINE__); } while (0)

int main() {
    int x = 5;
    CHECK(x == 10);
    return 0;
}

Esercizio 6: Macro per il Rilascio della Memoria

Creare una macro per il rilascio della memoria e impostare il puntatore a NULL.
#include <stdio.h>
#include <stdlib.h>

#define FREE(ptr) do { free(ptr); ptr = NULL; } while (0)

int main() {
    int *p = (int *)malloc(sizeof(int) * 10);
    if (p == NULL) {
        perror("Errore di allocazione della memoria");
        return 1;
    }
    FREE(p);
    if (p == NULL) {
        printf("Puntatore impostato a NULL\n");
    }
    return 0;
}

Esercizio 7: Macro per la Misurazione del Tempo di Esecuzione

Creare una macro per misurare il tempo di esecuzione di un blocco di codice.
#include <stdio.h>
#include <time.h>

#define TIME_BLOCK_START() clock_t start = clock()
#define TIME_BLOCK_END() do { clock_t end = clock(); printf("Tempo di esecuzione: %lf secondi\n", (double)(end - start) / CLOCKS_PER_SEC); } while (0)

int main() {
    TIME_BLOCK_START();
    for (volatile int i = 0; i < 1000000; ++i); // Codice di esempio
    TIME_BLOCK_END();
    return 0;
}

Esercizio 8: Macro per la Gestione degli Errori di File

Creare una macro per gestire gli errori durante l'apertura di un file.
#include <stdio.h>

#define OPEN_FILE(file, filename, mode) do { file = fopen(filename, mode); if (file == NULL) { perror("Errore nell'apertura del file"); return 1; } } while (0)

int main() {
    FILE *file;
    OPEN_FILE(file, "testo.txt", "r");
    // Esegui operazioni sul file
    fclose(file);
    return 0;
}