לדלג לתוכן

3.7 הpreprocessor תרגול

תרגול – שלב 1: זיהוי תחליפים

  1. כתבו קוד שמדפיס את השטח של עיגול, תוך שימוש במקרו PI:

    #define PI 3.14
    

    שאלות:

    • מה קורה אם תעשו #undef PI לפני השימוש?

    • האם PI משתנה בזמן ריצה?

  2. הגדירו פונקציית מקרו בשם MAX(x, y) שמחזירה את הגדול מבין שני ערכים.
    נסו להריץ את הקוד הבא:

    int a = 3, b = 7;
    int max_val = MAX(a, b);
    

    שאלות:
    - מה יקרה אם תשתמש במקרו MAX(x++, y++)?


תרגול – שלב 2: תנאים והגנות

  1. כתבו קובץ .h עם ההגדרה הבאה:

    #define VERSION 2
    

    ואז בקובץ אחר כתוב:

    #if VERSION == 1
    int config = 100;
    #elif VERSION == 2
    int config = 200;
    #else
    int config = 300;
    #endif
    

    שאלות:

  2. האם תוכלו לשנות את הערך של config רק על ידי שינוי המקרו?

  3. מה יקרה אם תשכח להגדיר את VERSION?

  4. כתבו קובץ header עם הגנה כפולה רגילה (#ifndef ...) וגם קובץ עם #pragma once.
    הוכיחו שהם מונעים הכללה כפולה ע"י הכללת אותו קובץ פעמיים בתוכנית.


תרגול – שלב 3: שימושים מורכבים

  1. הגדירו מקרו בשם DEBUG_MODE בקובץ הראשי.
    בקובץ .c אחר, כתוב בלוק קוד שנראה כך:

    #ifdef DEBUG_MODE
        // הדפס הודעה כל פעם שהפונקציה מופעלת
    #endif
    

    שאלות:

    • איך תוכלו לקמפל את הקוד עם DEBUG_MODE מופעל – בלי לערוך את הקובץ?
      (רמז: השתמש ב־gcc -DDEBUG_MODE)
  2. כתבו קוד שמשתמש ב־#error כדי למנוע קומפילציה אם VERSION קטן מ־2.

    #if VERSION < 2
    #error "Minimum version required is 2"
    #endif
    

    ודא שהקומפיילר באמת עוצר עם הודעת שגיאה.


תרגול – שלב 4: יצירת קוד גנרי

  1. כתוב קובץ שבו יש הגדרה כללית של משתנה, כך:

    #ifndef BUFFER_SIZE
    #define BUFFER_SIZE 1024
    #endif
    

    עכשיו תכתוב קובץ main.c שמכיל:

    #define BUFFER_SIZE 2048
    #include "buffer.h"
    

    בדוק איזה ערך מתקבל בפועל, ומתי כל אחד "מנצח".


  1. כתבו קובץ config.h שמכיל תנאים שונים לפי מערכת ההפעלה או הגדרות קומפילציה.
    לדוגמה:

    #ifdef _WIN32
    #define OS_NAME "Windows"
    #elif __linux__
    #define OS_NAME "Linux"
    #else
    #define OS_NAME "Unknown OS"
    #endif
    

    שאלות:
    - באיזו מערכת הקוד הזה רץ?
    - איך תוכלו לבדוק את הערך של OS_NAME בלי להשתמש ב־printf?