Macros ב C הם תכונה רבת עוצמה של שלב עיבוד המאפשר מתכנתים להגדיר קבועים, קוד נייח קוד קוליין, ולבצע איסוף מצבי. כאשר נעשה שימוש ביעילות, הם משפרים באופן משמעותי את יכולת הקוד ואת יכולת המשיכה, המאפשר למפתחים לכתוב תוכניות נקיות יותר גמישות.עם זאת, כוחם מגיע עם סיכונים; שימוש מאקרו לא תקין יכול להציג באגים עדינים ולהפוך את הקוד קשה יותר כדי debu זה מאמר כדי כך.

מה זה Macros?

(הופנה מהדף [[1924]]]], [[1924]]]], [[1924]]]]]], [[1966]], [[1924]]]]]], [[1924]]]]]]]]]], [[1966]]]]]]]], [[1966]]]]]]]]]], [[1924]]]]]]]]]]]]]], [[1924]]]]]]]]]]]]]]]]]], [[1924]]]]]]]]]]]]]]]]]], [[1924]]]]]], [[1924]]]]]]]]]]]]]]]], [[1966]]]]]]]]]]]]]]]]]]]]]], [[1924]]]]]]]]]]]], [[1966]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]], [[1966]], [[1966]], [[1966]], [[1966]], [[1966]], [[1966]], [[1966]], [[1966]], [[1966]], [[1966]], [[[[1966]]]], [[[[1966]]]]]]]]]], [[1966]]]]]]]]]] [[[[[[1966]],

#define PI 3.14159 // object-like macro
#define SQUARE(x) ((x)*(x)) // function-like macro

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

יתרונות של Macros for Code Reusability and Maintenance

כאשר הוא מיושם בחשיבה, מאקרו מספקים מספר יתרונות קונקרטיים בבסיסי קוד גדולים או רגישים לביצוע:

  • (ב) ,0)קוד ReusabilityFLT:1: Define a Common חישוב או snippet פעם ולהשתמש בו לאורך כל התוכנית.
  • (ב) ויקרא י"א): "ה', במקום לפיזור ה''':2 או'לא' (ב') ו'לא' (ב') , ויקרא י') , ו'לא מבדילים את ה''' ועושים כפליים.
  • (FLT:0)Performance GainsFLT:1: מאקרו דמוי פונקציונלי נמנעים מעל פני שיחת פונקציה. עבור פעולות קטנות, לעתים קרובות בשימוש (למשל, מינוס / מקס, מרובע), מאקרו יכול להיות מהיר יותר אפילו פונקציות קו ישר במדור מסוים שבו אין מובטח.
  • (ב) ,0) ,U Obecniho Dumoal DepositFLT: (מקרא: 1) (בשיתוף פעולה עם קוד משותף עם קוד ספציפי פלטפורמה, debug בונה, או תכונה למגירות 6 כדי לכלול או לא לכלול קוד המבוסס על תנאי זמן רב.
  • (FLT:0) הדגימה את ה-ConigurationFIRLT:1: על ידי הגדרת מאקרו עם ערכים שונים בראש יחיד, אתה יכול להתאים את ההתנהגות של בסיס קוד שלם ללא נגיעה בקבצי יישום.

שם הספר Robust Macros: Best Practices

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

תמיד פרדוקסים בגודל הורות וכל ביטוי

כי מאקרו הם החלפת טקסט, מפעיל precedence יכול לשבור אותם מאקרו כמו FLT 7 להרחיב את הביטוי כולו:

#define SQUARE(x) ((x) * (x)) // now SQUARE(3+2) works correctly

להימנע מהערכה מרובה של ארגומנטים

טענות מקארו מוחלשות כ-i.If aטיעון יש תופעות לוואי (למשל, FLT:11), ניתן להעריך יותר מפעם אחת.

#define MAX(a,b) ((a) > (b) ? (a) : (b))
int x = 5;
int max = MAX(x++, 10); // expands to ((x++) > (10) ? (x++) : (10)) // x incremented twice!

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

השתמש ב- Macro Names

על פי האמנה, מאקרו כתובים במכתבים העליונים (למשל, קונסול):13, ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇

סוף Macros with Do-בזמן עבור Multi-statement בלוקים

כאשר מגדירים מאקרו המכיל מספר הצהרות, עוטפים אותן בלולאה של ה-FLT:15, זה מבטיח את המאקרו להתנהג כראוי בכל ההקשרים (למשל, לאחר פרק 16 ללא חזיות):

#define LOG_ERROR(msg) do { \
 fprintf(stderr, "Error: %s\n", msg); \
 exit(1); \
} while (0)

מסמך Macros Thoroughly

מקרוס חסר את האופי העצמי של פונקציות.תמיד להוסיף הערות המתארות את הטיעונים, התנהגות צפויה, וכל מגבלות. השתמש בהערות בסגנון Doxygen בעת המתאים.

טכניקות Macro

C preprocessor מציע מפעילי חזקים מעבר להחלפה פשוטה. Mastering אלה יכולים להפוך את המאקרו שלך אפילו גמיש יותר.

מדרש (ב)

מפעילת ה-FLT:19 הופכת טיעון מאקרו לליטר מיתר.זה שימושי עבור debugging או logging:

#define PRINT_VAR(x) printf(#x " = %d\n", x)
int value = 42;
PRINT_VAR(value); // prints: value = 42

« « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « «

מפעילת ה-FLT:22 מתכנסת שני אסימונים לסימון אחד.זה מאפשר לך ליצור מזהים באופן דינמי בעת יצירת:

#define CREATE_VAR(prefix, index) prefix ## index
int CREATE_VAR(arr, 0) = 10; // becomes int arr0 = 10;

Token Pasting משמש נרחב X מאקרוs ו ליצירת תבניות קוד חוזרות.

Variadic Macros (C99)

ב C99, מאקרו אדריודי מקבל מספר משתנה של טיעונים באמצעות PH:24 זה מאפשר כניסה גמישה מפוצצים:

#define DEBUG_PRINT(fmt, ...) \
 fprintf(stderr, "DEBUG: " fmt, __VA_ARGS__)
DEBUG_PRINT("x = %d, y = %d", x, y);

ב- C11 ואילך, ניתן להשתמש ב-FLT:26 כדי להתמודד עם ריצוף של נוסחאות בטיעונים ריקים, שיפור יכולת הניתוק.

מלכודות נפוצות וכיצד להימנע מהם

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

  • (ב) מדרש (ב"ב) "ה'" (ב"ב)"ב"ה, "ה'" (ב"ב)"ב"ה', "ה')"ה' (ב"ב)"ב"ה', "ה'"ה'" (ב"ב"ב"ב)"ה')"ה'"ה'"ה'"ה'"ה'"ה'"ה'"ה'"ה'"ה'.
  • (ב) ,0) ,5 ,5 , , קדמה להפתעות: תמיד בגודל ההורה - כפי שצוין לעיל.
  • (ב) אם אתה מגדיר מאקרו עם פונקציות של 1:1; אם אתה מגדיר מאקרו עם אותו שם כמו פונקציה בספריה סטנדרטית, זה יכול להקדים אותו בשקט.
  • (ב) ⁇ :0) לא-קונסט ראשוניים (לא-קונסטנטיים) 1 (המכונים מאקרו דמוי אובייקטים משמשים כקבועים, אך הם אינם מטיפוסים.
  • (ב) [ה]ה']: [ה'], [ה'], [ה']'[ה']'[ה']'[ה]']'[ה']'[ה']']'[ה']'[ה']'[ה']'[ה']'[ה']'']'[ה']'[ה'[ה']']']'[ה'[ה']']'[ה']']'[ה'[ה'[ה'[ה'[ה'[ה']']'[ה'[ה'[ה'[ה'[ה']']']']']']']'[ה'[ה'[ה'[ה']']']']'[ה'[ה']']'[ה'[ה'[ה'[ה']']'[ה'[ה']']'[ה'[ה'[ה']']'[ה']']'[ה'[ה']']'[ה'[

חלופות ל Macros: Cont, enum, and Inline Functions

C מודרני מספק חלופות בטוחות יותר כי לעתים קרובות לחסל את הצורך במאקרו:

  • (ב) [ה]] [ה]] [ה] [ה]] [ב]] [ה]] [ה'] [ה']]'[ה]']'[ה']'[ה']'[ה]']'[ה']'[ה']'[ה']'[ה']']'[ה']']'[ה'[ה']']']'[ה']'[ה']'[ה']']'[ה'[ה'[ה'[ה'[ה']']']'[ה'[ה'[ה'[ה']']']']']'[ה']']'[ה'[ה'[ה']']'[ה']']'[ה'[ה']']'[ה'[ה']'[ה']']']'[ה']']']'[ה'[ה'[ה']']'[ה']']'[ה'[ה']']'[ה'[
  • (ב) [ה]ב]: [ה]ב] [ה] [ה]] [ה]] [ה]], [ה]][ה]]]][ה]]]]][ה]]]], [הההההההההההההההההההההההההההההההההתמדהים [התורה] [ה]] [ההתורהרים] [ההה"ב"ב"ה"ה"ה"ה"ה"ב"ה"ה"ה"ה"ב"ב"ה"ה"ה"ה'], ו"ב"ב], ו"ה'], ו"ה'], ו"ה'], ו[ה'], ו[ה'], ו[ה'], ו[ה'], ו[ה'], ו[ה'], ו"ה'], ו"[ה'[ה'], [ה'], [ה'], [ה'], ו"ב[[ה'], ו"ה'[ה
  • (ב) ,0) פונקציות Inline: הציג ב- C99, הפונקציה FLT:35 לספק את הביצועים של מאקרו עם בטיחות מסוג מלא, ניכוי תמיכה, הימנעות מבעיות תופעות לוואי.
static inline int square(int x) {
 return x * x;
}

השתמש בפונקציות קוליין בכל פעם שאתה צריך מאקרו דמוי פונקציה המערכת טענות בדיוק פעם אחת.המקרה היחיד שנותר לשימוש עבור מאקרו פונקציונלי הוא כאשר אתה צריך לפעול על סוגים (למשל, סוג של ב-GNU C) או צריך את היכולת לפתוח יק חדש (כמו do-בזמן idiom).

דוגמאות אמיתיות: דיון וידוי

מקרוז מצטיין בתרחישים מותניים.כאן שתי יישומים מעשיים:

דיון עם Compile-Time control

#ifdef DEBUG
 #define LOG(fmt, ...) fprintf(stderr, "[DEBUG] " fmt, ##__VA_ARGS__)
#else
 #define LOG(fmt, ...) /* no-op */
#endif

מאקרו זה רק כאשר הוא מואסף עם FLT:38, ואת המאקרו ריק גורם אפס מעל פני השטח השחרור נבנה.ה-FLT:39 לפני FLT:40 הוא הרחבה גנו אשר מסיר את המצע כאשר אין שום טענות מסופקות (גם תמיכה ב C20 עם FLT:41).

קוד מידע-Specific Code

#if defined(_WIN32) || defined(_WIN64)
 #define PLATFORM "Windows"
#elif defined(__linux__)
 #define PLATFORM "Linux"
#else
 #define PLATFORM "Unknown"
#endif

דפוס זה מבודד את התלויות של פלטפורמה ללא ציות של פונקציות שלמות. בשילוב עם שומרים FLT:43, זה שומר ראש נקי ושמירה על.

מסקנה

(גרוס נשאר כלי חיוני ב C עבור קידוד תאימות ותחזוקה, במיוחד בהקשרים קריטיים או משובצים שבו כל מחזור נחשב כראוי - עם ההורות נאותה, תופעות לוואי מוגבלות, ושמות מתאימים - הם להפחית את השכפול ואת התצורה המרכזית.עם זאת, המגמה ב C המודרני הוא להחליף מאקרו כמו פונקציות קו או גנרים (באמצעות LTF:44 ב C9) לעתים קרובות לאובייקטיביים ו-Fvtvtvtv-T.

על ידי איזון כוח מאקרו מסורתי עם חלופות בטוחות אלה, אתה יכול לכתוב קוד C כי הוא יעיל וחזק גם.לקריאה נוספת, להתייעץ עם ה-FLT:0GNU C Preprocessor ManualFLT:1 ואת סעיף FPLT:2C ההתייחסות על מאקרוראו מאקרו-FLT 3: , הבנה מאקרו בפירוט הוא מכוסה גם כן ב-F:4leded.com5: