לדלג לתוכן

3.7 הpreprocessor הרצאה

מה זה Preprocessor?

כאשר אנחנו מקמפלים תוכנית ב־C, יש שלבים:

  1. Preprocessing – מבצע פעולות שונות לפני הקימפול

  2. Compilation – תרגום הקוד לשפת מכונה.

  3. Linking - חיבור כל הקבצים השונים לקובץ הרצה אחד

ה־Preprocessor פועל לפני שהקומפיילר רואה את הקוד.
הוא לא "מבין" את שפת C – הוא רק מחפש הנחיות שמתחילות ב־# ומבצע פעולות טקסטואליות.
לפני שהקומפיילר מתחיל להמיר את הקוד לשפת מכונה, הוא עובר על כל השורות שמתחילות עם הסימן # ומבצע אותן.

לאחר מכן, הקומפיילר מתחיל לעבוד, הוא מקמפל את כל הקבצים לקבצי אובייקט.

ואז הלינקר נכנס לפעולה (linker), הוא יודע לקחת את כל קבצי האובייקט שלנו ולעשות להם לינקוג' (linking)- בעצם לחבר אותם ביחד לקובץ הרצה.


פקודות עיקריות של ה־Preprocessor

1. #include – הכללת קבצים

הוראה שמכניסה קובץ קוד אחר לקובץ הנוכחי.

#include <stdio.h>     // קובץ מערכת (בתוך angle brackets)
#include "myheader.h"  // קובץ מקומי (בתוך מרכאות)

בפועל – תוכן הקובץ פשוט מועתק לקובץ הנוכחי בשלב ה־Preprocessing.

כאשר אנחנו עושים include לקבצי header, אנחנו בעצם אומרים לקומפיילר- "אל תדאג, הפונקציות והמשתנים שאנחנו משתמשים מוגדרים פה- ובזמן לינקוג', (בזמן שהלינקר יעבוד אחרייך) הלינקר ידע לחבר את כל התוכנה ביחד."

2. #define – מקרו/הגדרה קבועה

מגדיר תחליפים טקסטואליים בקוד.

#define PI 3.14159

לאחר הגדרה כזו, כל מופע של PI בקוד יוחלף ב־3.14159.

זה לא משתנה – אלא החלפת טקסט פשוטה לפני הקומפילציה.

למעשה, אפשר גם ככה להגדיר פונקציות "מקרו"

#define MAX(a, b) ((a) > (b) ? (a) : (b))

פונקציות מקרו הן פונקציות קטנות שקורות בזמן preprocessing, ויודעות לבצע פעולות פשוטות. (למשל, פונקציית sizeof היא מקרו.)

3. #undef – ביטול הגדרה

מבטל מקרו שהוגדר קודם.

#undef PI

תנאים בזמן Preprocessing

4. #if, #ifdef, #ifndef, #else, #elif, #endif

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

#define DEBUG

#ifdef DEBUG
    printf("Debug mode\n");
#endif
#ifndef MAX_SIZE
#define MAX_SIZE 100
#endif
#if VERSION == 2
    // קוד לגרסה 2
#elif VERSION == 3
    // קוד לגרסה 3
#else
    // קוד ברירת מחדל
#endif

מטרה נפוצה: לשנות קוד לפי מערכת הפעלה, גרסה, או מצב (debug/release).


מניעת הכללה כפולה:

#ifndef MY_HEADER_H
#define MY_HEADER_H

// תוכן הקובץ

#endif

או בקיצור (בתוך קובצי .h מודרניים):

#pragma once

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


#error ו־#warning

הוראות שמפסיקות את הקומפילציה עם הודעה (או מציגות אזהרה):

#error "This code requires C99 or later"
#warning "This feature is experimental"

סיכום

הוראה תיאור
#include הכללת קובץ
#define יצירת מקרו
#undef מחיקת מקרו
#ifdef / #ifndef בדיקה אם מקרו מוגדר / לא מוגדר
#if / #elif / #else / #endif תנאים
#error / #warning הפסקת קומפילציה / אזהרה