לדלג לתוכן

3.7 הpreprocessor פתרון

שלב 1 – תרגול עם #define ו־#undef

  1. הגדירו מקרו בשם PI עם הערך 3.14. לאחר מכן חשבו את שטח מעגל בעזרת PI, למשל:
#define PI 3.14

int main() {
    float r = 5.0;
    float area = PI * r * r;
    return 0;
}
  1. בטלו את המקרו בעזרת #undef PI לפני השימוש וראו שהקומפיילר מתלונן. נסו להריץ גם עם וגם בלי #undef.

שלב 2 – פונקציות מקרו

  1. הגדירו פונקציית מקרו בשם MAX(a, b) שמחזירה את המספר הגדול מבין שניים. נסו להריץ אותה בקוד כמו:
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main() {
    int x = 5, y = 9;
    int m = MAX(x, y);
    return 0;
}
  1. נסו להריץ MAX(x++, y++) ובדקו מה קרה ל־x ו־y. תראו שהם הוגדלו יותר מפעם אחת — זאת בעיה נפוצה במקרו שמכפיל קוד.

שלב 3 – תנאים בקומפילציה

  1. הגדירו בקובץ version.h את הערך VERSION:
#define VERSION 2
  1. בקובץ הראשי:
#include "version.h"

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

שנו את VERSION ובדקו מה הערך של config.


שלב 4 – הגנות על קבצי Header

  1. כתבו קובץ myheader.h כך:
#ifndef MYHEADER_H
#define MYHEADER_H

int x = 42;

#endif
  1. בקובץ .c, כללו אותו פעמיים:
#include "myheader.h"
#include "myheader.h"

int main() {
    return x;
}

הקומפיילר לא יתלונן – הקובץ הוכלל רק פעם אחת בזכות ההגנה.

  1. נסו להחליף ל־#pragma once וראו שהתוצאה זהה.

שלב 5 – תנאים וסביבת קומפילציה

  1. כתבו את הקוד הבא:
#ifdef DEBUG
#define DEBUG_PRINT() int a = 5
#else
#define DEBUG_PRINT()
#endif

int main() {
    DEBUG_PRINT();
    return 0;
}
  1. קומפלו עם:
gcc -DDEBUG program.c -o program

ובלעדיו. בדקו אם משתנה a קיים בכל אחת מהגרסאות.


שלב 6 – שימוש ב־#error

  1. כתבו:
#define VERSION 1

#if VERSION < 2
#error "גרסה ישנה מדי!"
#endif
  1. קומפלו וראו שהקומפילציה נעצרת עם שגיאה.

  2. שנו את VERSION ל־3 וראו שהבעיה נפתרת.


שלב 7 – שימוש ב־#include עם הגדרות מוקדמות

  1. כתבו קובץ buffer.h כך:
#ifndef BUFFER_SIZE
#define BUFFER_SIZE 1024
#endif
  1. כתבו קובץ main.c כך:
#define BUFFER_SIZE 2048
#include "buffer.h"

int buffer[BUFFER_SIZE];

int main() {
    return 0;
}

בדקו בעזרת sizeof(buffer) אם ההגדרה הייתה 2048 כמו שציפיתם.


שלב 8 – תנאים לפי מערכת הפעלה

  1. כתבו בקובץ os.h:
#ifdef _WIN32
#define OS_NAME "Windows"
#elif __linux__
#define OS_NAME "Linux"
#else
#define OS_NAME "Unknown"
#endif
  1. כתבו בתוכנית הראשית:
#include "os.h"

int main() {
    char *name = OS_NAME;
    return 0;
}
  1. קומפלו במערכות שונות או בעזרת הגדרת מאקרו:
gcc -D__linux__ main.c -o main

אם תרצו, ניתן להריץ gcc -E כדי לראות מה עושה בדיוק ה־Preprocessor:

gcc -E main.c

תוכלו לראות את התוצאה אחרי שהמאקרואים התבצעו וכל הקבצים הוכללו.