enum – ערכי ברירת מחדל, פערים וחשבון
ב-enum ברירת המחדל מתחילה מ-0 ועולה ב-1. אם מציבים ערך מפורש, הערכים הבאים ממשיכים ממנו. במבחנים, שאלות enum דורשות לעקוב אחרי הערך המספרי של כל איבר.
#include <stdio.h> enum Color { RED, GREEN, BLUE }; int main() { printf("%d %d %d\n", RED, GREEN, BLUE); return 0; } // פלט: 0 1 2
#include <stdio.h> enum Rank { A = 5, B, C = 20, D, E }; int main() { printf("A=%d B=%d C=%d D=%d E=%d\n", A, B, C, D, E); return 0; } // פלט: A=5 B=6 C=20 D=21 E=22 // B ממשיך מ-A (5+1=6), D ממשיך מ-C (20+1=21)
#include <stdio.h> enum Vals { X = 3, Y = 7, Z }; int main() { int result = X + Y + Z; printf("%d\n", result); return 0; } // Z = 7+1 = 8 // result = 3 + 7 + 8 = 18 // פלט: 18
#include <stdio.h> enum Level { LOW = 0, MED = 0, HIGH }; int main() { printf("%d %d %d\n", LOW, MED, HIGH); printf("%d\n", LOW == MED); return 0; } // פלט: // 0 0 1 // 1 // שני איברים יכולים לחלוק את אותו ערך! // HIGH = MED+1 = 0+1 = 1
enum| הגדרה | ערכים | הסבר |
|---|---|---|
{ A, B, C } |
0, 1, 2 |
ברירת מחדל – מתחיל מ-0 |
{ A=5, B, C } |
5, 6, 7 |
B ו-C ממשיכים מ-5 |
{ A, B=10, C } |
0, 10, 11 |
A=0 (ברירת מחדל), C ממשיך מ-10 |
{ A=3, B=3, C } |
3, 3, 4 |
ערכים כפולים מותרים |
{ A=1, B=5, C=2, D } |
1, 5, 2, 3 |
D ממשיך מ-C (2+1=3) – לא חייב סדר עולה |
{ A=-2, B, C } |
-2, -1, 0 |
ערכים שליליים מותרים |
struct – אתחול, גישה, sizeof ו-packed#include <stdio.h> struct Point { int x; int y; }; int main() { struct Point p = {10, 20}; p.x += 5; printf("%d %d\n", p.x, p.y); return 0; } // פלט: 15 20
#include <stdio.h> struct A { char c; // 1 byte + 3 bytes padding int i; // 4 bytes char d; // 1 byte + 3 bytes padding }; struct B { int i; // 4 bytes char c; // 1 byte char d; // 1 byte + 2 bytes padding }; int main() { printf("sizeof(A) = %lu\n", sizeof(struct A)); printf("sizeof(B) = %lu\n", sizeof(struct B)); return 0; } // פלט: // sizeof(A) = 12 (1+3+4+1+3) // sizeof(B) = 8 (4+1+1+2) // סדר השדות משפיע על הגודל!
#include <stdio.h> struct __attribute__((__packed__)) Packed { char c; // 1 byte int i; // 4 bytes char d; // 1 byte }; int main() { printf("sizeof(Packed) = %lu\n", sizeof(struct Packed)); return 0; } // פלט: sizeof(Packed) = 6 (1+4+1, ללא padding)
#include <stdio.h> struct Inner { int a; int b; }; struct Outer { struct Inner in; int c; }; int main() { struct Outer o = { {1, 2}, 3 }; printf("%d %d %d\n", o.in.a, o.in.b, o.c); return 0; } // פלט: 1 2 3
#include <stdio.h> #include <string.h> struct Data { int x; int y; }; int main() { struct Data a = {10, 20}; struct Data b; memcpy(&b, &a, sizeof(struct Data)); b.x = 99; printf("a: %d %d\n", a.x, a.y); printf("b: %d %d\n", b.x, b.y); return 0; } // פלט: // a: 10 20 (a לא השתנה – memcpy יוצר העתק) // b: 99 20
union – שיתוף זיכרון ובדיקת בתים#include <stdio.h> union Val { int i; float f; char c; }; int main() { union Val v; v.i = 65; printf("i=%d c=%c\n", v.i, v.c); return 0; } // פלט: i=65 c=A // כל השדות חולקים את אותו זיכרון. // v.c קורא את הבית הראשון של v.i, שהוא 65 = 'A'
#include <stdio.h> union Mix { float f; int i; }; int main() { union Mix m; m.f = 3.14f; printf("i=%d\n", m.i); return 0; } // פלט: i=1078523331 (ייצוג IEEE 754 של 3.14 כ-int) // קריאת שדה שונה מהשדה שנכתב אליו – UB (התנהגות לא מוגדרת) // אבל ברוב המימושים: מקבלים את הביטים כפי שהם
#include <stdio.h> union ByteCheck { int num; unsigned char bytes[4]; }; int main() { union ByteCheck bc; bc.num = 0x41424344; printf("bytes: %c %c %c %c\n", bc.bytes[0], bc.bytes[1], bc.bytes[2], bc.bytes[3]); return 0; } // ב-Little-Endian (רוב המחשבים): // bytes[0]=0x44='D', bytes[1]=0x43='C', // bytes[2]=0x42='B', bytes[3]=0x41='A' // פלט: bytes: D C B A
num = 0x41424344, מה bytes[0] ב-Little-Endian? תשובה: 0x44 = 'D'. הבית הנמוך (LSB) נשמר בכתובת הנמוכה ביותר.
ב-Little-Endian (x86, כמעט כל מחשב PC), הבית הנמוך ביותר (LSB) נשמר בכתובת הנמוכה ביותר. זה הפוך מהסדר שאנחנו כותבים בקוד.
// המספר 0x41424344 בזיכרון (Little-Endian): // // כתובת: [0] [1] [2] [3] // ערך: 0x44 0x43 0x42 0x41 // ASCII: 'D' 'C' 'B' 'A' // // שימו לב: 44 (הבית הנמוך) נמצא בכתובת [0]
#include <stdio.h> union Endian { int val; unsigned char byte; }; int main() { union Endian e; e.val = 1; // 0x00000001 if (e.byte == 1) printf("Little-Endian\n"); else printf("Big-Endian\n"); return 0; } // פלט (במחשב רגיל): Little-Endian // כי הבית הראשון (byte) מקבל את ה-LSB שהוא 0x01
#include <stdio.h> union HexView { unsigned int val; unsigned char b[4]; }; int main() { union HexView h; h.val = 0xAABBCCDD; printf("%02X %02X %02X %02X\n", h.b[0], h.b[1], h.b[2], h.b[3]); return 0; } // פלט (Little-Endian): DD CC BB AA
switch – fall-through, קיבוץ cases ו-default#include <stdio.h> int main() { int x = 2; switch (x) { case 1: printf("one "); case 2: printf("two "); case 3: printf("three "); default: printf("end"); } printf("\n"); return 0; } // פלט: two three end // נכנס ב-case 2, ואז נופל דרך case 3 ו-default (אין break!)
#include <stdio.h> int main() { char grade = 'B'; switch (grade) { case 'A': case 'B': printf("Excellent\n"); break; case 'C': printf("Good\n"); break; default: printf("Other\n"); } return 0; } // פלט: Excellent // 'B' נופל ל-case 'A' ושם רואים שאין break, אז ממשיך ל-case 'B' // שניהם חולקים את אותו הקוד
#include <stdio.h> int main() { int n = 1; switch (n) { case 1: printf("A"); case 2: printf("B"); break; case 3: printf("C"); default: printf("D"); } printf("\n"); return 0; } // פלט: AB // case 1 → הדפסת A, אין break → נופל ל-case 2 → הדפסת B → break! // case 3 ו-default לא מגיעים
#include <stdio.h> int main() { int x = 5; switch (x) { case 1: printf("1 "); break; default: printf("def "); case 2: printf("2 "); break; case 3: printf("3 "); } printf("\n"); return 0; } // פלט: def 2 // x=5 לא תואם אף case → נכנס ל-default → הדפסת "def " // אין break ב-default → נופל ל-case 2 → הדפסת "2 " → break
switch| מצב | קוד | מה מודפס (x=2) |
|---|---|---|
| עם break בכל case | case 1: ..break; case 2: ..break; case 3: ..break; |
רק הפלט של case 2 |
| בלי break בשום case | case 1: .. case 2: .. case 3: .. default: .. |
פלט case 2 + case 3 + default |
| break רק ב-case 3 | case 1: .. case 2: .. case 3: ..break; default: .. |
פלט case 2 + case 3 (ועצירה) |
| cases מקובצים (ללא קוד) | case 1: case 2: case 3: ..break; |
הפלט המשותף (case 1-3 חולקים קוד) |
| x לא תואם + default בלי break | default: .. case 5: ..break; |
default + פלט case 5 |
char/ASCII – אריתמטיקה על תווים#include <stdio.h> int main() { char c = 'A'; printf("%c %d\n", c, c); printf("%c %d\n", c + 1, c + 1); printf("%c %d\n", c + 25, c + 25); return 0; } // פלט: // A 65 // B 66 // Z 90
#include <stdio.h> int main() { char a = 'd'; char b = 'a'; printf("%d\n", a - b); char upper = a - 32; // 'a'-'A' = 97-65 = 32 printf("%c\n", upper); return 0; } // פלט: // 3 ('d'=100, 'a'=97, 100-97=3) // D (100-32=68='D')
#include <stdio.h> int main() { char x = '0'; // '0' = 48 (לא 0!) char y = 5; printf("%c\n", x + y); printf("%d\n", x + y); return 0; } // פלט: // 5 (48+5=53='5') // 53
'A'=65, 'Z'=90, 'a'=97, 'z'=122, '0'=48, '9'=57. ההפרש בין אות גדולה לקטנה הוא תמיד 32.
long – פורמט ואריתמטיקה#include <stdio.h> int main() { long a = 100000L; long b = 200000L; long c = a * b; printf("%ld\n", c); printf("sizeof(long) = %lu\n", sizeof(long)); return 0; } // פלט (64-bit Linux): // 20000000000 // sizeof(long) = 8 // // פלט (32-bit / Windows): // overflow (long הוא 4 bytes) // sizeof(long) = 4
%ld להדפסת long. שימוש ב-%d במקום %ld עלול לגרום לפלט שגוי.
atoi – המרה חלקית ומלאה#include <stdio.h> #include <stdlib.h> int main() { printf("%d\n", atoi("42")); printf("%d\n", atoi("123abc")); printf("%d\n", atoi("abc")); printf("%d\n", atoi("-99")); printf("%d\n", atoi(" 55")); printf("%d\n", atoi("0x1A")); return 0; } // פלט: // 42 (המרה מלאה) // 123 (עוצר ב-'a' – תו לא מספרי) // 0 (אין ספרות – מחזיר 0) // -99 (מזהה סימן מינוס) // 55 (מדלג על רווחים בהתחלה) // 0 (עוצר ב-'x' – לא מזהה hex)
#include <stdio.h> int main() { unsigned int a = 0x0F; // 00001111 unsigned int b = a << 4; // 11110000 = 0xF0 unsigned int c = a | b; // 11111111 = 0xFF printf("a=0x%X b=0x%X c=0x%X\n", a, b, c); return 0; } // פלט: a=0xF b=0xF0 c=0xFF
#include <stdio.h> int main() { unsigned int val = 0xABCD; unsigned int low_byte = val & 0xFF; // 0xCD unsigned int high_byte = (val >> 8) & 0xFF; // 0xAB printf("low=0x%X high=0x%X\n", low_byte, high_byte); return 0; } // פלט: low=0xCD high=0xAB
#include <stdio.h> int main() { unsigned char x = 0x0F; // 00001111 unsigned char y = ~x; // 11110000 = 0xF0 printf("x=0x%02X y=0x%02X\n", x, y); return 0; } // פלט: x=0x0F y=0xF0
#include <stdio.h> int main() { unsigned int flags = 0; // הדלקת ביט 2 (ספירה מ-0) flags |= (1 << 2); // flags = 0x4 = 00000100 printf("0x%X\n", flags); // הדלקת ביט 0 flags |= (1 << 0); // flags = 0x5 = 00000101 printf("0x%X\n", flags); // כיבוי ביט 2 flags &= ~(1 << 2); // flags = 0x1 = 00000001 printf("0x%X\n", flags); return 0; } // פלט: // 0x4 // 0x5 // 0x1
#define – הנושא הנבחן ביותר!זה הנושא שמופיע הכי הרבה בשאלות הקוד. מאקרו הוא החלפת טקסט מילולית – ללא סוגריים, סדר הפעולות ישתנה. המפתח לפתרון: הרחיבו את המאקרו ידנית ורק אז חשבו.
#include <stdio.h> #define MUL(a, b) a * b int main() { int r = MUL(2+3, 2); printf("%d\n", r); return 0; } // הרחבה: r = 2+3 * 2 // סדר פעולות: כפל לפני חיבור → 2 + 6 = 8 // פלט: 8 (ולא 10!)
#include <stdio.h> #define MUL(a, b) ((a) * (b)) int main() { int r = MUL(2+3, 2); printf("%d\n", r); return 0; } // הרחבה: r = ((2+3) * (2)) // חישוב: (5) * (2) = 10 // פלט: 10 (נכון!)
#include <stdio.h> #define SQR(x) x * x int main() { printf("%d\n", SQR(3+1)); printf("%d\n", 10 / SQR(2)); return 0; } // שורה 1: SQR(3+1) → 3+1 * 3+1 = 3+3+1 = 7 (לא 16!) // שורה 2: 10/SQR(2) → 10/2*2 = 5*2 = 10 (לא 2!) // פלט: // 7 // 10
#include <stdio.h> #define SQR(x) ((x) * (x)) int main() { printf("%d\n", SQR(3+1)); printf("%d\n", 10 / SQR(2)); return 0; } // שורה 1: SQR(3+1) → ((3+1) * (3+1)) = 4*4 = 16 ✓ // שורה 2: 10/SQR(2) → 10/((2)*(2)) = 10/4 = 2 ✓ // פלט: // 16 // 2
#include <stdio.h> #define ADD(a, b) (a) + (b) int main() { int r = 2 * ADD(3, 4); printf("%d\n", r); return 0; } // הרחבה: r = 2 * (3) + (4) // סדר פעולות: 2*3 + 4 = 6 + 4 = 10 // פלט: 10 (ולא 14!) // עם #define ADD(a,b) ((a)+(b)) → 2 * ((3)+(4)) = 2*7 = 14
| מאקרו | קריאה | הרחבה | תוצאה | נכון? |
|---|---|---|---|---|
#define MUL(a,b) a*b |
MUL(2+3, 2) |
2+3*2 |
8 |
שגוי (צפוי 10) |
#define MUL(a,b) ((a)*(b)) |
MUL(2+3, 2) |
((2+3)*(2)) |
10 |
נכון |
#define SQR(x) x*x |
SQR(3+1) |
3+1*3+1 |
7 |
שגוי (צפוי 16) |
#define SQR(x) ((x)*(x)) |
SQR(3+1) |
((3+1)*(3+1)) |
16 |
נכון |
#define SQR(x) x*x |
10/SQR(2) |
10/2*2 |
10 |
שגוי (צפוי 2) |
#define SQR(x) ((x)*(x)) |
10/SQR(2) |
10/((2)*(2)) |
2 |
נכון |
#define ADD(a,b) (a)+(b) |
2*ADD(3,4) |
2*(3)+(4) |
10 |
שגוי (צפוי 14) |
#define ADD(a,b) ((a)+(b)) |
2*ADD(3,4) |
2*((3)+(4)) |
14 |
נכון |
#define HALF(x) x/2 |
HALF(4+2) |
4+2/2 |
5 |
שגוי (צפוי 3) |
#define HALF(x) ((x)/2) |
HALF(4+2) |
((4+2)/2) |
3 |
נכון |
#define F(x) ((x)*2). בשאלות מבחן, הרחיבו את המאקרו ידנית לפני שמחשבים.
SQR(++a) ו-UB#include <stdio.h> #define SQR(x) ((x) * (x)) int main() { int a = 3; int r = SQR(a++); printf("r=%d a=%d\n", r, a); return 0; } // הרחבה: r = ((a++) * (a++)) // a++ מבוצע פעמיים! → Undefined Behavior // תוצאה אפשרית: r=9 a=5 או r=12 a=5 (תלוי מהדר)
#include <stdio.h> #define DOUBLE_M(x) ((x) + (x)) static inline int double_f(int x) { return x + x; } int main() { int a = 5; int r1 = DOUBLE_M(++a); // ((++a) + (++a)) = UB! printf("macro: r=%d a=%d\n", r1, a); int b = 5; int r2 = double_f(++b); // b הופך ל-6, ואז 6+6=12 printf("func: r=%d b=%d\n", r2, b); return 0; } // פלט מאקרו: לא ניתן לחזות (UB) // פלט פונקציה: r=12 b=6 (מוגדר וצפוי)
#include <stdio.h> #define SWAP(a, b) do { \ int temp = (a); \ (a) = (b); \ (b) = temp; \ } while(0) int main() { int x = 5, y = 10; SWAP(x, y); printf("x=%d y=%d\n", x, y); return 0; } // פלט: x=10 y=5
#include <stdio.h> #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) int main() { printf("%d\n", MIN(3, 7)); printf("%d\n", MAX(3, 7)); printf("%d\n", MIN(2+1, 4)); return 0; } // פלט: // 3 // 7 // 3 (MIN((2+1),(4)) = MIN(3,4) = 3)
#include <stdio.h> #define SET_FLAG(val, bit) ((val) |= (1 << (bit))) #define CLEAR_FLAG(val, bit) ((val) &= ~(1 << (bit))) #define CHECK_FLAG(val, bit) ((val) & (1 << (bit))) int main() { unsigned int f = 0; SET_FLAG(f, 0); // f = 0x1 = 00000001 SET_FLAG(f, 3); // f = 0x9 = 00001001 printf("0x%X\n", f); CLEAR_FLAG(f, 0); // f = 0x8 = 00001000 printf("0x%X\n", f); printf("%d\n", CHECK_FLAG(f, 3) ? 1 : 0); printf("%d\n", CHECK_FLAG(f, 0) ? 1 : 0); return 0; } // פלט: // 0x9 // 0x8 // 1 (ביט 3 דלוק) // 0 (ביט 0 כבוי)
do-while(0) – מאקרו בטוח
למה do { ... } while(0)? כדי שהמאקרו יתנהג כהוראה בודדת ויהיה בטוח בתוך if ללא סוגריים.
// ❌ בלי do-while(0): #define LOG_BAD(msg) printf("LOG: "); printf(msg); if (error) LOG_BAD("fail\n"); // רק printf הראשון בתוך ה-if! // printf השני ירוץ תמיד! // ✓ עם do-while(0): #define LOG_GOOD(msg) do { printf("LOG: "); printf(msg); } while(0) if (error) LOG_GOOD("fail\n"); // שתי ההדפסות בתוך ה-if ✓
# – Stringify
אופרטור # בתוך מאקרו ממיר פרמטר למחרוזת. מחרוזות צמודות ב-C מתמזגות אוטומטית.
#include <stdio.h> #define STR(s) #s #define PRINT_VAR(x) printf(#x " = %d\n", x) int main() { printf("%s\n", STR(hello)); printf("%s\n", STR(3+4)); int count = 42; PRINT_VAR(count); int total = 100; PRINT_VAR(total); return 0; } // פלט: // hello (STR(hello) → "hello") // 3+4 (STR(3+4) → "3+4" – לא מחשב!) // count = 42 (PRINT_VAR(count) → printf("count" " = %d\n", count)) // total = 100
#include <stdio.h> #define SHOW(expr) printf(#expr " = %d\n", expr) int main() { int a = 3, b = 4; SHOW(a + b); SHOW(a * b); return 0; } // הרחבה: // printf("a + b" " = %d\n", a + b); → "a + b = 7" // printf("a * b" " = %d\n", a * b); → "a * b = 12" // פלט: // a + b = 7 // a * b = 12
## – Token Pasting
אופרטור ## מצמיד שני טוקנים למזהה חדש בזמן קומפילציה.
#include <stdio.h> #define CONCAT(a, b) a##b int main() { int CONCAT(my, Var) = 42; // → int myVar = 42; printf("%d\n", myVar); return 0; } // פלט: 42
#include <stdio.h> #define MAKE_FUNC(name) \ void func_##name() { printf("called: %s\n", #name); } MAKE_FUNC(init) // → void func_init() { printf("called: %s\n", "init"); } MAKE_FUNC(close) // → void func_close() { printf("called: %s\n", "close"); } int main() { func_init(); func_close(); return 0; } // פלט: // called: init // called: close
#include <stdio.h> #define VAR(n) var_##n int main() { int VAR(1) = 10; // → int var_1 = 10; int VAR(2) = 20; // → int var_2 = 20; printf("%d %d\n", var_1, var_2); return 0; } // פלט: 10 20
#ifdef / #ifndef / #if – קומפילציה מותנית#include <stdio.h> #define DEBUG int main() { #ifdef DEBUG printf("debug on\n"); #endif #ifndef RELEASE printf("not release\n"); #endif #ifdef VERBOSE printf("verbose\n"); #endif return 0; } // פלט: // debug on (DEBUG מוגדר) // not release (RELEASE לא מוגדר) // (verbose לא מודפס – VERBOSE לא מוגדר)
#include <stdio.h> int main() { printf("A\n"); #if 0 printf("B\n"); // קוד "מבוטל" – לא ייכלל בקומפילציה printf("C\n"); #endif printf("D\n"); return 0; } // פלט: // A // D // (B ו-C לא מודפסים – נמצאים בתוך #if 0)
#include <stdio.h> #define SIZE 3 int main() { #if SIZE == 1 printf("small\n"); #elif SIZE == 3 printf("medium\n"); #else printf("large\n"); #endif return 0; } // פלט: medium // SIZE==3 תואם את ה-#elif השני
#include <stdio.h> #define DEBUG 2 int main() { #if DEBUG >= 2 printf("detailed debug\n"); #elif DEBUG >= 1 printf("basic debug\n"); #else printf("no debug\n"); #endif return 0; } // פלט: detailed debug // DEBUG=2 → 2 >= 2 → true → הענף הראשון
#undef – ביטול והגדרה מחדש#include <stdio.h> #define VAL 10 int main() { printf("%d\n", VAL); #undef VAL #define VAL 20 printf("%d\n", VAL); #undef VAL #define VAL 30 printf("%d\n", VAL); return 0; } // פלט: // 10 // 20 // 30
#include <stdio.h> #define FEATURE_X int main() { #ifdef FEATURE_X printf("X on\n"); #endif #undef FEATURE_X #ifdef FEATURE_X printf("X still on\n"); #else printf("X off\n"); #endif return 0; } // פלט: // X on (FEATURE_X מוגדר בשלב הזה) // X off (אחרי #undef, FEATURE_X כבר לא מוגדר)
inline – השוואה למאקרו
פונקציית static inline מייצרת קוד יעיל כמו מאקרו, אבל עם בדיקת טיפוסים מלאה ובלי בעיות הערכה כפולה.
#include <stdio.h> #define MAX_M(a, b) ((a) > (b) ? (a) : (b)) static inline int max_f(int a, int b) { return a > b ? a : b; } int main() { int x = 3, y = 7; // שניהם מחזירים 7 printf("%d\n", MAX_M(x, y)); printf("%d\n", max_f(x, y)); // אבל עם ++: int a = 3, b = 7; printf("%d\n", max_f(a++, b++)); // בטוח: a=4,b=8, מחזיר 7 // MAX_M(a++, b++) → UB! (b++ מוערך פעמיים) return 0; } // פלט: // 7 // 7 // 7
argc/argv – פרסור שורת פקודה עם atoi#include <stdio.h> int main(int argc, char *argv[]) { printf("argc = %d\n", argc); for (int i = 0; i < argc; i++) printf("argv[%d] = %s\n", i, argv[i]); return 0; } // הרצה: ./prog hello 42 // פלט: // argc = 3 // argv[0] = ./prog // argv[1] = hello // argv[2] = 42
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { if (argc > 1) { int n = atoi(argv[1]); printf("n = %d\n", n); printf("n*2 = %d\n", n * 2); } else { printf("No argument\n"); } return 0; } // הרצה: ./prog 15 // פלט: // n = 15 // n*2 = 30 // // הרצה: ./prog // פלט: No argument
argv[0] הוא תמיד שם התוכנית. argc כולל את שם התוכנית בספירה. לכן argc == 1 אומר שאין ארגומנטים נוספים.
במדריך זה עברנו על כל הנושאים שמופיעים בשאלות קוד C במבחנים – עם דגש על מעקב קוד וחיזוי פלט. הנקודות החשובות ביותר:
++/-- במאקרו = UB. השתמשו ב-inline במקום.#x הופך ל-"x", a##b הופך ל-ab.'A'=65, 'a'=97, '0'=48. אריתמטיקה על תווים עובדת כי char הוא מספר.| להדלקה, & ~ לכיבוי, << להזזה. פורמט hex: %X.0x41424344 → [44,43,42,41].atoi("123abc") = 123.מדריך זה מכסה את כל הנושאים שנבחנים בשאלות קוד הכנה למיונים. שליטה בנושאים אלה תעניק יתרון משמעותי למי שמתכונן לגאמא סייבר, מיון סייבר או תפקידים ביחידה 8200. התרגלו לעקוב אחרי ביצוע הקוד שורה אחרי שורה – זו המיומנות המרכזית שנדרשת.