Menu

הערות ב-C: הסבר על // ועל /* */

ל-C יש שני סגנונות הערות, // לשורה אחת ו-/* */ לכמה שורות, עם היסטוריה שונה ומלכודת קינון אחת. הנה איך להשתמש בשניהם, ומה שווה להעיר עליו ומה לא.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

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

שתי הצורות

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

// נמשכת עד סוף השורה הפיזית. שום דבר לא יכול לבוא אחריה באותה שורה, כך שזה לא עובד כמו שזה נראה:

int x = 5;  // set x to five  int y = 6;   /* y is never declared */

/* ... */ מסתיימת ב-*/ הראשון, איפה שהוא לא יהיה. היא יכולה להתחיל ולהסתיים באמצע שורה, וזה לפעמים שימושי:

int total = price /* before tax */ + shipping;

למה קיימים שני סגנונות

/* */ היא C המקורית, מ-1972. // הגיעה מ-C++ ונוספה רשמית ל-C רק ב-C99. ההיסטוריה הזו מסבירה משהו שתשימו לב אליו כשתקראו קוד ישן: ספריות שנכתבו כדי להיות ניידות ל-C89 משתמשות ב-/* */ גם להערות של שורה אחת, כי // הייתה נכשלת בקומפילציה בכלים הישנים שהן עדיין תמכו בהם.

היום כל קומפיילר שסביר שתשתמשו בו מקבל את שתיהן. השתמשו ב-// להערות רגילות וב-/* */ כשהערה באמת מתפרסת על כמה שורות. אם אתם מכוונים לקומפיילר משובץ ישן מאוד, בדקו לפני שאתם סומכים על //.

אי אפשר לקנן הערות

זו המלכודת האמיתית היחידה:

/* Disable this section for now
   int a = compute();
   /* the classic helper - keep an eye on it */
   int b = a * 2;
*/

הערת הבלוק מסתיימת ב-*/ הראשון, זה שבשורה 3. שורות 4 ו-5 הן אז שוב קוד פעיל, וה-*/ שבסוף שורה 6 הוא שגיאת תחביר. ההודעה של הקומפיילר מצביעה על השורה האחרונה ולא עוזרת בכלל להבין את הסיבה.

הפתרון הוא להשתמש במקום זה בקדם-המעבד, שכן יודע לטפל בקינון:

#if 0
    int a = compute();
    /* the classic helper - keep an eye on it */
    int b = a * 2;
#endif

#if 0 אף פעם לא אמת, כך שקדם-המעבד מוחק את כל מה שעד #endif לפני שהקומפיילר רואה אותו. זה שורד הערות, מירכאות ובלוקים אחרים של #if בפנים, וקל לחפש את זה כשמנקים.

הפיכת קוד להערה בזמן דיבאג

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

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

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

הערות תיעוד

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

כלים כמו Doxygen קוראים הערות מובנות כאלה ומפיקים מהן תיעוד עיון. הסגנון של Doxygen עצמו משתמש ב-/** ... */ עם התגיות @param ו-@return:

/**
 * Converts Celsius to Fahrenheit.
 * @param c temperature in Celsius
 * @return the same temperature in Fahrenheit
 */
double celsius_to_fahrenheit(double c);

שתי האפשרויות בסדר לקוד שלכם. מה שחשוב הוא שההערה תהיה ליד ההצהרה שאנשים קוראים, בדרך כלל בקובץ הכותרת (header), ולא קבורה במימוש.

על מה שווה להעיר

הכלל ששורד מפגש עם בסיסי קוד אמיתיים: העירו על ה"למה", לא על ה"מה".

i++;  // increment i          <- says nothing the code did not
/* Skip the BOM: files exported by the old system start with
   three bytes that are not part of the data. */
offset += 3;

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

דברים שבאמת שווים הערה, ב-C במיוחד:

  • של מי הזיכרון הזה. אם פונקציה מחזירה מצביע שמי שקורא לה חייב לעשות לו free, כתבו את זה. ל-C אין דרך לבטא את זה בטיפוס.
  • יחידות וטווחים. int timeout; דו-משמעי: שניות או מילישניות?
  • נכונות לא מובנת מאליה. למה הלולאה עוצרת ב-n - 1, למה ההמרה הזו בטוחה, למה החוצץ בגודל 256 בתים.
  • מוזרות מכוונת. קוד שנראה כמו באג אבל אינו באג מושך "תיקונים" מקוראים עתידיים, אלא אם מסמנים אותו.

ההערה הזו מצדיקה את מקומה: השורה שמתחתיה נראית מיותרת, והיא לא.

הערות בתוך מחרוזות אינן הערות

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

שתי השורות מודפסות במלואן. הקומפיילר מפרק מחרוזות ליחידות לפני שהוא מחפש הערות, כך ש-// בתוך מירכאות הם פשוט שני תווים. (ה-%% בשורה הראשונה הוא הדרך להדפיס סימן אחוז מילולי עם printf: % לבדו פותח מציין פורמט.)

שאלות נפוצות

איך כותבים הערה ב-C?

בשתי דרכים. // this is a comment נמשכת עד סוף השורה. /* this is a comment */ יכולה להתפרס על כל מספר של שורות ומסתיימת ב-*/ הסוגר. שתיהן מוסרות לפני הקומפילציה, כך שהן אף פעם לא משפיעות על התוכנית.

האם C תומכת בהערות //?

כן, מאז C99. הן נלקחו מ-C++ ונתמכות היום בכל מקום. רק קומפיילרים עתיקים באמת של C89 דוחים אותן, ולכן קוד ישן מאוד משתמש ב-/* */ לכל דבר, אפילו להערות של שורה אחת.

אפשר לקנן הערות ב-C?

לא. /* outer /* inner */ still outer */ מסתיימת ב-*/ הראשון, ומשאירה את still outer */ כקוד שבור. כדי לנטרל בלוק שכבר מכיל הערות /* */, השתמשו במקום זה ב-#if 0 ... #endif, שתומך בקינון כמו שצריך.

איך הופכים בלוק קוד להערה ב-C?

עטפו אותו ב-/* */ אם אין בתוכו הערות בלוק, או הוסיפו // בתחילת כל שורה. האפשרות העמידה לאזורים גדולים היא #if 0 לפני ו-#endif אחרי: קדם-המעבד מסיר את כל מה שביניהם, וזה שורד הערות ומירכאות שבפנים.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל