This page needs a recent browser (with SharedArrayBuffer support). Please update Chrome, Edge, Firefox or Safari to the latest version. · تحتاج هذه الصفحة إلى متصفح حديث (يدعم SharedArrayBuffer). يرجى تحديث Chrome أو Edge أو Firefox أو Safari إلى أحدث إصدار.
Every C program starts in main. #include <stdio.h> pulls in a header 头文件 so you can use printf to print. A function 函数 is a named block you can call; \n starts a new line. main returns 0 to mean "success".
العربية
يبدأ كل برنامج C في main. #include <stdio.h> يستدعي ملف header لتتمكن من استخدام printf للطباعة. الدالة هي كتلة ذات اسم يمكنك استدعاؤها؛ \n يبدأ سطرًا جديدًا. main تُرجع 0 تعني "النجاح".
#include <stdio.h>
void greet(void) {
printf("Hello, world!\n");
}
int main(void) {
greet();
printf("I am learning C.\n");
return 0;
}
كل برنامج C يعمل من main بعد تضمين ملفات header
1.2
المتغيرات، الأنواع والحسابات
English
C needs a type for every variable: int (integer 整数), double (floating-point 浮点数), char (one character). printf uses a format specifier 格式说明符 — %d, %f, %c — for each value. / between two ints is integer division; % is the remainder 余数.
The format string drives both printing and reading:
Specifier
Type
Example output
%d
int
17
%f
double (%.2f = 2 decimal places)
3.14
%c
char
A
%s
a string
Mei
%zu
a size (from sizeof / strlen)
3
%x
int, printed in base 16
ff
scanf("%d", &n) reads keyboard input with the same specifiers (note the &). Its sibling sscanf parses values out of a string, so it runs anywhere:
العربية
C يحتاج نوعًا لكل متغير: int (عدد صحيح)، double (نقطة عائمة)، char (حرف واحد). printf يستخدم محدد تنسيق — %d، %f، %c — لكل قيمة. / بين عددين صحيحين هو قسمة صحيحة؛ % هو الباقي.
#include <stdio.h>
int main(void) {
int n = 17;
double pi = 3.14;
char grade = 'A';
printf("%d %.2f %c\n", n, pi, grade); // 17 3.14 A
printf("%d %d\n", 7 / 2, 7 % 2); // 3 1
return 0;
}
سلسلة التنسيق توجه الطباعة والقراءة أيضًا:
المحدد
النوع
مثال الإخراج
%d
int
17
%f
double (%.2f = 2 منازل عشرية)
3.14
%c
char
A
%s
نص
Mei
%zu
حجم (من sizeof / strlen)
3
%x
int، مطبوعة بالأساس 16
ff
scanf("%d", &n) تقرأ إدخال لوحة المفاتيح بنفس المحددات (مع ملاحظة الـ &). شقيقتها sscanf تحلل القيم من نص، لذا تعمل في أي مكان:
#include <stdio.h>
int main(void) {
char line[] = "Mei 88";
char name[20];
int score;
sscanf(line, "%19s %d", name, &score); // parse text -> values
printf("%s scored %d\n", name, score); // Mei scored 88
return 0;
}
1.3
التعليقات والأسلوب
English
A comment 注释 is a note for humans; the compiler ignores it. Use // for one line and /* ... */ for a block. Good indentation 缩进 and clear names make code easy to read.
Common mistakes
Every statement ends with ;, and main should return int (return 0;).
printf needs a format string: %d for int, %f for double, and \n for a new line.
A wrong format like %d for a double prints garbage — match the type.
العربية
التعليق هو ملاحظة للبشر؛ المترجم يتجاهله. استخدم // لسطر واحد و/* ... */ لكتلة. المسافات البادئة الجيدة والأسماء الواضحة تجعل الكود سهل القراءة.
#include <stdio.h>
int main(void) {
// a single-line comment
/* a block
comment */
int total = 3 + 4; // clear names help
printf("%d\n", total); // 7
return 0;
}
أخطاء شائعة
كل تعليمة تنتهي بـ ;، وmain يجب أن تُرجع int (return 0;).
printf تحتاج سلسلة تنسيق: %d لـ int، %f لـ double، و\n لسطر جديد.
صيغة خاطئة مثل %d لـ double تطبع فوضى — طابق النوع.
An if runs a block when a condition 条件 is true. C has no real boolean 布尔值 type by default: 0 is false and any non-zero value is true. Chain choices with else if and else. Compare with ==, !=, <, >, <=, >=.
العربية
تنفذ if كتلة عندما تكون الشرط صحيحًا. C ليس لديها نوع منطقي حقيقي افتراضيًا: 0 خطأ وأي قيمة غير صفرية صحيحة. اربط الخيارات مع else if وelse. قارن بـ ==، !=، <، >، <=، >=.
#include <stdio.h>
int main(void) {
int score = 72;
if (score >= 90) {
printf("A\n");
} else if (score >= 60) {
printf("Pass\n");
} else {
printf("Fail\n");
}
return 0;
}
if تختفر الفرع الصحيح؛ else الفرع الخطأ
2.2
switch
English
A switch picks one case by an integer value. Each case needs a break to jump out 跳出 — without it, C "falls through" into the next case. default runs when nothing matches.
Common mistakes
if (x = 5) assigns and is always true; use == to compare.
Each switch case needs a break;, or it falls through to the next.
0 is false and any non-zero value is true in a condition.
العربية
الأمر switch يختار case بقيمة عدد صحيحة. كل case يحتاج إلى أمر break للقفز خارج — بدون هذا الأمر، "يسقط" C في الحالة التالية. يعمل default عندما لا يتطابق شيء.
#include <stdio.h>
int main(void) {
int day = 3;
switch (day) {
case 1: printf("Mon\n"); break;
case 2: printf("Tue\n"); break;
case 3: printf("Wed\n"); break;
default: printf("Other\n");
}
return 0;
}
أخطاء شائعة
if (x = 5) تُعين وتكون دائمًا صحيحة؛ استخدم == للمقارنة.
كل حالة switch تحتاج إلى break;، وإلا ستنتقل إلى الحالة التالية.
A loop 循环 repeats a block. A while loop runs as long as a condition is true. A for loop packs the start, the test, and the increment 自增 (i++) into one line — best when you know how many times to repeat.
العربية
الحلقة تكرر كتلة من الكود. حلقة while تعمل طالما أن الشرط صحيح. حلقة for تجمع البداية، والاختبار، والزيادة (i++) في سطر واحد — الأفضل عندما تعرف عدد المرات التي تريد تكرارها.
#include <stdio.h>
int main(void) {
int i = 1;
while (i <= 3) {
printf("%d ", i);
i++;
}
printf("\n"); // 1 2 3
for (int j = 0; j < 5; j++) {
printf("%d ", j);
}
printf("\n"); // 0 1 2 3 4
return 0;
}
while يتحقق من شرط؛ for يعد بخطوة
3.2
التراكم
English
A common pattern: start an accumulator 累加器 at 0, then add to it inside a loop. The same idea counts items or finds a running total.
العربية
نمط شائع: ابدأ بمجمع عند 0، ثم أضف إليه داخل الحلقة. نفس الفكرة يُستخدم لعدّ العناصر أو إيجاد المجموع المتراكم.
#include <stdio.h>
int main(void) {
int total = 0;
for (int i = 1; i <= 5; i++) {
total += i; // 1 + 2 + 3 + 4 + 5
}
printf("%d\n", total); // 15
return 0;
}
3.3
الحلقات المتداخلة والأنماط
English
A loop inside another loop is a nested 嵌套 loop. The inner loop finishes fully for each step of the outer loop — perfect for grids and patterns.
Common mistakes
for (i = 0; i < n; i++) runs n times; a semicolon right after for (...) makes an empty loop.
A while whose condition never becomes false loops forever.
Declare the counter (int i) before or inside the for header.
العربية
حلقة داخل حلقة أخرى هي حلقة متداخلة. تنتهي الحلقة الداخلية بالكامل لكل خطوة من الحلقة الخارجية — مثالية للصفائح والأنماط.
#include <stdio.h>
int main(void) {
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
printf("*");
}
printf("\n");
}
return 0;
}
أخطاء شائعة
for (i = 0; i < n; i++) يعمل n مرة؛ فاصلة منقوطة مباشرة بعد for (...) تُكوّن حلقة فارغة.
حلقة while إذا لم يصبح شرطها خاطئاً أبداً ستعمل إلى ما لا نهاية.
A function takes parameters 参数 (inputs) and gives back a return value 返回值. The return type comes first (int, double, …); void means it returns nothing.
العربية
الدالة تأخذ معاملات (مدخلات) وتُرجع قيمة إرجاع. نوع الإرجاع يأتي أولاً (int، double، ...)؛ void يعني أنها لا تُرجع شيئاً.
#include <stdio.h>
int square(int x) { // x is a parameter
return x * x; // hand back a value
}
int main(void) {
int r = square(5);
printf("%d\n", r); // 25
return 0;
}
المعاملات دخول؛ قيمة الإرجاع خروج
4.2
النماذج الأولية والنطاق
English
C reads top to bottom, so a function must be known before it is called. A prototype 函数原型 — the header line plus ; — declares it early so you can keep main first. A variable's scope 作用域 is the block it lives in: it is local 局部 and disappears when the block ends.
Common mistakes
A function used before it is defined needs a prototype above main.
Arguments are passed BY VALUE — changes inside a function do not affect the caller unless you pass a pointer.
A variable declared inside a function is local to it.
العربية
C يقرأ من الأعلى إلى الأسفل، لذا يجب معرفة الدالة قبل استدعاءها. النموذج الأولي — سطر الرأس بالإضافة إلى ; — يعلن عنها مبكراً حتى تتمكن من وضع main في البداية. نطاق المتغير هو الكتلة التي يعيش فيها: هو محلي ويختفي عند انتهاء الكتلة.
#include <stdio.h>
int add(int a, int b); // prototype: declared before use
int main(void) {
printf("%d\n", add(3, 4)); // 7
return 0;
}
int add(int a, int b) { // definition comes later
int sum = a + b; // sum is local to add
return sum;
}
أخطاء شائعة
الدالة المستخدمة قبل تعريفها تحتاج إلى نموذج أعلى main.
يتم تمرير الحجج بالقيمة — التغييرات داخل الدالة لا تؤثر على المُدعي إلا إذا مررت مؤشراً.
An array 数组 holds several values of one type. Index 索引 from 0. C does not store an array's length, so a common trick computes the element 元素 count: sizeof(a) / sizeof(a[0]).
العربية
المصفوفة تحتفظ بعدة قيم من نوع واحد. الفهرسة تبدأ من 0. C لا يخزن طول المصفوفة، لذا خدعة شائعة تحسب عدد العناصر: sizeof(a) / sizeof(a[0]).
#include <stdio.h>
int main(void) {
int scores[3] = {88, 71, 95};
printf("%d\n", scores[0]); // 88
scores[1] = 100;
printf("%d\n", scores[1]); // 100
int n = sizeof(scores) / sizeof(scores[0]);
printf("%d\n", n); // 3
return 0;
}
أماكن المصفوفة مُفهرسة من 0
5.2
خوارزميات المصفوفات
English
Traverse 遍历 an array with a for loop to find a max, a total, or a count. Always loop from 0 up to n - 1.
العربية
تتبع المصفوفة باستخدام حلقة for لإيجاد الحد الأقصى، أو المجموع، أو العدد. always loop from 0 up to n - 1.
#include <stdio.h>
int main(void) {
int a[] = {3, 9, 2, 7};
int n = sizeof(a) / sizeof(a[0]);
int max = a[0], total = 0;
for (int i = 0; i < n; i++) {
if (a[i] > max) max = a[i];
total += a[i];
}
printf("%d %d\n", max, total); // 9 21
return 0;
}
5.3
مصفوفات 2-A
English
A 2-D array is a grid of rows 行 and columns 列: grid[row][col]. Use two nested loops to visit every cell.
Common mistakes
C does NOT check array bounds: writing a[n] in a size-n array is undefined behaviour.
Valid indexes run from 0 to n - 1.
The array name is a pointer to its first element; sizeof only gives the size in the array's own scope.
العربية
مصفوفة 2-A هي شبكة من الصفوف والأعمدة: grid[row][col]. استخدم حلقتين متداخلتين لزيارة كل خلية.
#include <stdio.h>
int main(void) {
int grid[2][3] = {{1, 2, 3}, {4, 5, 6}};
printf("%d\n", grid[1][2]); // 6
for (int r = 0; r < 2; r++) {
for (int c = 0; c < 3; c++) {
printf("%d ", grid[r][c]);
}
}
printf("\n"); // 1 2 3 4 5 6
return 0;
}
أخطاء شائعة
C لا يتحقق من حدود المصفوفة: كتابة a[n] في مصفوفة بحجم n سلوك غير محدد.
الفهارس الصالحة تمتد من 0 إلى n - 1.
اسم المصفوفة هو مؤشر إلى عنصرها الأول؛ sizeof يعطي الحجم فقط في نطاق المصفوفة الخاص بها.
A pointer 指针 stores the address 地址 of a variable. &x gives the address of x; *p dereferences 解引用 the pointer — it reads or writes the value stored there. Passing a pointer lets a function change the caller's variable (pass-by-pointer).
The classic use is a swap function. Passing values only copies them — the swap is lost. Passing pointers lets the function reach the caller's variables:
An array name acts as a pointer to its first element, and pointer arithmetic 指针运算 steps by whole elements:
NULL is the pointer that points at nothing — check for it before you dereference.
Common mistakes
&x is the address of x; *p is the value stored at p.
Never use *p on an uninitialised or NULL pointer — it crashes or corrupts memory.
To change a caller's variable, pass its address and write through the pointer.
العربية
المؤشر يحفظ عنوان متغير. &x يعطي عنوان x؛ *p يفك تشفير المؤشر — يقرأ أو يكتب القيمة المخزنة هناك. تمرير المؤشر يسمح للدالة بتغيير متغير المُدعي (التمرير بالمؤشر).
المؤشر يحفظ عنواناً؛ فك تشفيره يتبع السهم إلى القيمة
#include <stdio.h>
void addOne(int *p) { // p holds an address
*p = *p + 1; // change the value at that address
}
int main(void) {
int x = 10;
int *ptr = &x; // & takes the address of x
printf("%d\n", *ptr); // * reads the value: 10
addOne(&x);
printf("%d\n", x); // 11 — changed through the pointer
return 0;
}
الاستخدام الكلاسيكي هو دالة التبادل. تمرير القيم ينسخها فقط — يُفقد التبادل. تمرير المؤشرات يسمح للدالة بالوصول إلى متغيرات المُدعي:
#include <stdio.h>
void swap_values(int a, int b) { // copies: the caller sees nothing
int t = a; a = b; b = t;
}
void swap_pointers(int *a, int *b) { // addresses: the swap is real
int t = *a; *a = *b; *b = t;
}
int main(void) {
int x = 1, y = 2;
swap_values(x, y);
printf("%d %d\n", x, y); // 1 2 (unchanged!)
swap_pointers(&x, &y);
printf("%d %d\n", x, y); // 2 1 (swapped)
return 0;
}
اسم المصفوفة يعمل كمؤشر إلى عنصرها الأول، وحساب المؤشرات يقفز بعناصر كاملة:
#include <stdio.h>
int main(void) {
int a[] = {10, 20, 30};
int *p = a; // same as &a[0]
printf("%d\n", *p); // 10
printf("%d\n", *(p + 2)); // 30 — same as a[2]
return 0;
}
NULL هو المؤشر الذي لا يشير إلى شيء — تحقق منه قبل فك تشفيره.
أخطاء شائعة
&x هو عنوان x؛ *p هي القيمة المخزنة في p.
لا تستخدم أبداً *p على مؤشر غير مبدء أو NULL —它会 causing crash or corrupting memory.
لتغيير متغير المُدعي، مرر عنوانه واكتب عبر المؤشر.
A C string 字符串 is an array of char. Every string ends with a hidden null terminator 空终止符'\0', which marks where it stops. strlen (from <string.h>) counts characters up to that '\0'. Print a whole string with %s and one character 字符 with %c.
You can traverse a string by looping until you reach '\0'.
العربية
سلسلة C هي مصفوفة من char. كل سلسلة تنتهي بمختتم null مخفي '\0'، والذي يحدد أين تتوقف. strlen (من <string.h>) يعدّ الأحرف حتى ذلك '\0'. اطبع السلسلة كاملة باستخدام %s وحرفاً واحداً باستخدام %c.
#include <stdio.h>
#include <string.h>
int main(void) {
char name[] = "Mei"; // 'M', 'e', 'i', '\0'
printf("%s\n", name); // Mei
printf("%zu\n", strlen(name)); // 3 (stops at '\0')
printf("%c\n", name[0]); // M
return 0;
}
سلسلة C هي مصفوفة أحرف تنتهي بمختتم null مخفي
يمكنك تتبع السلسلة عن طريق الدوران حتى تصل إلى '\0'.
#include <stdio.h>
int main(void) {
char word[] = "banana";
int count = 0;
for (int i = 0; word[i] != '\0'; i++) {
if (word[i] == 'a') count++;
}
printf("%d\n", count); // 3
return 0;
}
7.2
مكتبة string.h
English
#include <string.h> gives you the everyday string tools:
Function
Does
strlen(s)
the length, not counting the terminator
strcpy(dst, src)
copy — dst must be big enough
strcat(dst, src)
append src onto the end of dst
strcmp(a, b)
compare: 0 when equal, else negative / positive
strcmp returns 0 for equal, so the test is strcmp(a, b) == 0 — never a == b.
The destination array must have room for the result plus the terminator.
Common mistakes
A C string needs one extra byte for the \0 terminator: a 5-letter word needs char[6].
Copy and compare strings with strcpy / strcmp, not = / ==.
Forgetting the \0 makes printf("%s", ...) run past the end of the text.
العربية
#include <string.h> يوفر لك أدوات السطور اليومية:
الدالة
تقوم بـ
strlen(s)
الطول، دون احتساب المختتم
strcpy(dst, src)
نسخ — dst يجب أن تكون كبيرة بما يكفي
strcat(dst, src)
إضافة src في نهاية dst
strcmp(a, b)
مقارنة: 0 عند التساوي، وإلا سالب / موجب
#include <stdio.h>
#include <string.h>
int main(void) {
char full[40];
strcpy(full, "Mei"); // full is now "Mei"
strcat(full, " Chen"); // append -> "Mei Chen"
printf("%s (%zu)\n", full, strlen(full)); // Mei Chen (8)
printf("%d\n", strcmp("apple", "apple") == 0); // 1 (equal)
return 0;
}
strcmp تُرجع 0 للتساوي، لذا الاختبار هو strcmp(a, b) == 0 — لا تستخدم أبداً a == b.
مصفوفة الوجه يجب أن تحتوي على مساحة للنتيجة بالإضافة إلى المختتم.
أخطاء شائعة
سلسلة C تحتاج بايت إضافي واحد للمختتم \0: كلمة مكونة من 5 أحرف تحتاج char[6].
انسخ وقارن السلاسل باستخدام strcpy / strcmp، لا = / ==.
نسيان \0 يجعل printf("%s", ...) يتجاوز نهاية النص.
A struct 结构体 groups related values into one type. Each value is a member 成员. typedef gives the struct a short name so you can write Dog instead of struct Dog. Use . on a struct value, but -> on a pointer to a struct.
Common mistakes
Use . on a struct value and -> on a struct pointer.
typedef lets you drop the word struct when declaring; without it you write struct Point p;.
Assigning one struct to another copies all its fields.
العربية
الـ struct يجمع قيمًا ذات صلة في نوع واحد. كل قيمة هي عضو. typedef يمنح الـ struct اسماً مختصراً بحيث يمكنك كتابة Dog بدلاً من struct Dog. استخدم . على قيمة struct، ولكن -> على مؤشر إلى struct.
#include <stdio.h>
typedef struct {
char name[20];
int age;
} Dog;
int main(void) {
Dog d = {"Rex", 3};
printf("%s is %d\n", d.name, d.age); // Rex is 3 (. on a value)
Dog *p = &d;
p->age = 4; // -> on a pointer
printf("%s is %d\n", d.name, d.age); // Rex is 4
return 0;
}
أخطاء شائعة
استخدم . على قيمة مجموعة و -> على مؤشر لمجموعة.
typedef يسمح لك بتجاهل كلمة struct عند الإعلان؛ بدونه تكتب struct Point p;.
malloc allocates 分配 memory on the heap 堆 at run time and returns a pointer to it. realloc resizes that block; free gives it back. Every malloc needs a matching free, or you get a memory leak 内存泄漏. These live in <stdlib.h>.
calloc(n, size) allocates an array like malloc AND fills it with zeros.
Common mistakes
Every malloc needs a matching free; forgetting to free leaks memory.
Using memory after free (a "use-after-free") is a serious bug.
Check that malloc did not return NULL before you use the memory.
العربية
malloc تخصص ذاكرة على الهيد (heap) وقت التشغيل وترجع مؤشراً إليها. realloc يعيد حجم تلك الكتلة؛ free يُعيدها. كل malloc يحتاج match with free، أو تحصل على تسرب للذاكرة. هذه توجد في <stdlib.h>.
المتغيرات المحلية تعيش في المكدس؛ ذاكرة malloc تعيش في الكومة حتى تقوم بإفراج عنها
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n = 3;
int *a = malloc(n * sizeof(int)); // room for 3 ints
for (int i = 0; i < n; i++) a[i] = i * 10;
a = realloc(a, 4 * sizeof(int)); // grow to 4 ints
a[3] = 30;
for (int i = 0; i < 4; i++) printf("%d ", a[i]);
printf("\n"); // 0 10 20 30
free(a); // hand the memory back
return 0;
}
calloc(n, size) تخصص مصفوفة مثل malloc AND يملؤها بالصفر.
أخطاء شائعة
كل malloc يحتاج إلى free مقابلة؛ نسيان الإفراج يسبب تسرب الذاكرة.
استخدام الذاكرة بعد free ("استخدام-بعد-إفراج") هو خطأ جسيم.
تحقق من أن malloc لم يعِد NULL قبل استخدام الذاكرة.
A linked list 链表 is a chain of nodes 节点. Each node holds a value and a pointer to the next node; the last one points to NULL. Unlike an array it grows one node at a time with malloc. Always free every node when done.
العربية
القائمة المرتبطة هي سلسلة من العقد. كل عقدة تحمل قيمة ومؤشر إلى العقدة next؛ العقدة الأخيرة تشير إلى NULL. على عكس المصفوفة، فإنها تنمو بإضافة عقدة واحدة في كل مرة مع malloc. يجب always free كل عقدة عند الانتهاء.
قائمة مترابطة: كل عقدة تحتفظ بقيمة ومؤشر إلى التالية، وتنتهي بـ NULL
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int value;
struct Node *next;
} Node;
int main(void) {
Node *head = NULL;
for (int v = 10; v <= 30; v += 10) { // prepend 10, 20, 30
Node *n = malloc(sizeof(Node));
n->value = v;
n->next = head;
head = n;
}
for (Node *p = head; p != NULL; p = p->next) {
printf("%d ", p->value); // 30 20 10
}
printf("\n");
while (head != NULL) { // free the whole list
Node *t = head;
head = head->next;
free(t);
}
return 0;
}
10.2
المكدسات والطوابير
English
A stack 栈 is LIFO 后进先出 (last in, first out): push and pop at the same end. A queue 队列 is FIFO 先进先出 (first in, first out): add at the back, remove from the front. Both are easy to build on an array with index variables.
Common mistakes
In a linked list, never lose the head pointer, or the whole list is unreachable.
Free every node when you are done, walking the list before you unlink.
Check for an empty list (a NULL head) before you pop.
العربية
المكدس LIFO (آخر دخول، أول خروج): دفع وإخراج من نفس النهاية. الطابور FIFO (أول دخول، أول خروج): إضافة من الخلف، إزالة من الأمام. كلاهما سهل البناء على مصفوفة باستخدام متغيرات الفهرس.
#include <stdio.h>
int main(void) {
int stack[10];
int top = 0; // next free slot
stack[top++] = 1; // push
stack[top++] = 2;
stack[top++] = 3;
while (top > 0) {
printf("%d ", stack[--top]); // pop: 3 2 1
}
printf("\n");
return 0;
}
#include <stdio.h>
int main(void) {
int queue[10];
int front = 0, back = 0;
queue[back++] = 1; // enqueue
queue[back++] = 2;
queue[back++] = 3;
while (front < back) {
printf("%d ", queue[front++]); // dequeue: 1 2 3
}
printf("\n");
return 0;
}
أخطاء شائعة
في القائمة المرتبطة، لا تفقد أبداً المؤشر head، وإلا تصبح القائمة بأكملها غير قابلة للوصول.
قم بإفراج عن كل عقدة عندما تنتهي، مع تجول القائمة قبل فصل الروابط.
Linear search 线性查找 checks each element in turn — it works on any array. Binary search 二分查找 is far faster but needs a sorted 已排序 array: it checks the middle and discards half each step. Both return the index, or -1 if missing.
العربية
البحث الخطي يفحص كل عنصر بالتتابع — يعمل على أي مصفوفة. البحث ثنائي التفرع أسرع بكثير لكنه يتطلب مصفوفة مرتبة: يفحص المنتوى ويستبعد النصف في كل خطوة. كلاهما يعيد الفهرس، أو -1 إذا كان مفقودًا.
#include <stdio.h>
int linear(int a[], int n, int target) {
for (int i = 0; i < n; i++)
if (a[i] == target) return i;
return -1;
}
int binary(int a[], int n, int target) {
int lo = 0, hi = n - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (a[mid] == target) return mid;
else if (a[mid] < target) lo = mid + 1;
else hi = mid - 1;
}
return -1;
}
int main(void) {
int a[] = {2, 5, 8, 12, 16, 23};
int n = sizeof(a) / sizeof(a[0]);
printf("%d %d %d\n", linear(a, n, 12), binary(a, n, 12), binary(a, n, 9));
return 0; // 3 3 -1
}
Bubble sort 冒泡排序 repeatedly compares neighbours and swaps 交换 any pair that is out of order. After each pass the largest value "bubbles" to the end.
العربية
فرز الفقاعات يقارن الجيران بشكل متكرر ويبدل أي زوج غير مرتب. بعد كل دورة "تصعد" القيمة الأكبر إلى النهاية.
#include <stdio.h>
int main(void) {
int a[] = {5, 2, 9, 1, 7};
int n = sizeof(a) / sizeof(a[0]);
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (a[j] > a[j + 1]) {
int t = a[j]; a[j] = a[j + 1]; a[j + 1] = t;
}
}
}
for (int i = 0; i < n; i++) printf("%d ", a[i]);
printf("\n"); // 1 2 5 7 9
return 0;
}
11.3
الاستدعاء المتكرر
English
Recursion 递归 is a function that calls itself. It needs a base case 基准情形 to stop, and a recursive call that steps toward it. Without a base case it never ends.
Common mistakes
Binary search needs a sorted array; recursion needs a base case.
Each recursive call must move closer to the base case, or the stack overflows.
Bubble and insertion sort are O(n²) — fine to learn, slow at scale.
العربية
التراجع هو دالة تستدعي نفسها. تحتاج إلى حالة أساسية للتوقف، واستدعاء تراجعي يقترب منها. بدون حالة أساسية لن تنتهي أبدًا.
#include <stdio.h>
int factorial(int n) {
if (n <= 1) return 1; // base case
return n * factorial(n - 1); // recursive call
}
int main(void) {
printf("%d\n", factorial(5)); // 120
return 0;
}
أخطاء شائعة
البحث ثنائي التفرغ يحتاج مصفوفة مرتبة؛ التراجع يحتاج حالة أساسية.
يجب أن يقترب كل استدعاء تراجعي أكثر من الحالة الأساسية، أو يمتلئ المكدس.
فرز الفقاعات وفرز الإدراج هما O(n²) — جيد للتعلم، بطيء على النطاق الواسع.
fopen returns a file pointer 文件指针; the mode 模式 string says what to do — "w" write, "r" read, "a" append. Write with fprintf, read with fscanf, and always fclose when done.
العربية
fopen يعيد مؤشر ملف؛ نص الوضع يقول ما يجب فعله — "w" كتابة، "r" قراءة، "a" إرفاق. اكتب باستخدام fprintf، اقرأ باستخدام fscanf، Always fclose عند الانتهاء.
#include <stdio.h>
int main(void) {
FILE *out = fopen("scores.txt", "w"); // open for writing
fprintf(out, "Alice 80\nBob 95\n");
fclose(out);
FILE *in = fopen("scores.txt", "r"); // open for reading
char name[20];
int score;
while (fscanf(in, "%s %d", name, &score) == 2) {
printf("%s -> %d\n", name, score);
}
fclose(in);
return 0;
}
fopen → قراءة/كتابة → fclose
12.2
معالجة الأخطاء مع رموز الإرجاع
English
C has no exceptions. Instead a function signals failure with a return code 返回码 — by convention 0 means success and non-zero means an error. The caller checks the code before trusting the result. (fopen follows the same idea: it returns NULL when it fails.)
Common mistakes
Check that fopen did not return NULL before reading or writing.
Always fclose a file when you are done.
Return a non-zero code from main to signal an error to the caller.
العربية
C لا تحتوي على استثناءات. بدلاً من ذلك، تشير الدالة إلى الفشل برمز إرجاع — بالعادة 0 تعني النجاح وغير صفري يعني خطأ. المتصل يفحص الرمز قبل الوثوق في النتيجة. (fopen يتبع نفس الفكرة: يعيد NULL عند الفشل.)
#include <stdio.h>
// returns 0 on success, -1 if the divisor is 0
int safe_divide(int a, int b, int *result) {
if (b == 0) return -1; // error code
*result = a / b;
return 0; // success
}
int main(void) {
int r;
if (safe_divide(10, 2, &r) == 0)
printf("10 / 2 = %d\n", r); // 10 / 2 = 5
if (safe_divide(10, 0, &r) != 0)
printf("cannot divide by zero\n"); // error reported
return 0;
}
أخطاء شائعة
تحقق من أن fopen لم يُرجع NULL قبل القراءة أو الكتابة.
Always fclose الملف عندما تنتهي.
أعد رمزًا غير صفري من main للإشارة إلى خطأ للمتصل.
A bit 位 is a single 0 or 1; numbers are stored in binary 二进制. Bitwise 按位 operators work on the bits directly: & AND, | OR, ^ XOR, << shift left (×2 each step), >> shift right (÷2).
Hexadecimal 十六进制 (base 16) writes binary compactly: one hex digit is exactly four bits. Write hex literals with 0x; print with %x:
العربية
البت هو 0 أو 1 واحد؛ تُخزن الأرقام بصيغة ثنائية. عوامل البت تعمل على البتات مباشرة: & AND، | OR، ^ XOR، << إزاحة لليسار (×2 في كل خطوة)، >> إزاحة لليمين (÷2).
#include <stdio.h>
int main(void) {
int a = 12; // 1100
int b = 10; // 1010
printf("%d\n", a & b); // 8 AND -> 1000
printf("%d\n", a | b); // 14 OR -> 1110
printf("%d\n", a ^ b); // 6 XOR -> 0110
printf("%d\n", a << 1); // 24 left shift
printf("%d\n", a >> 1); // 6 right shift
return 0;
}
السادس عشرية (الأساس 16) تكتب الثنائيات بكثافة: رقم سادس عشري واحد يساوي أربع بتات بالضبط. اكتب الثوابت السادسة عشرية باستخدام 0x؛ اطبع باستخدام %x:
#include <stdio.h>
int main(void) {
printf("%d\n", 0xFF); // 255 (0x marks a hex literal)
printf("%x\n", 255); // ff
printf("%x\n", 12); // c
return 0;
}
عملات البت تعمل على بتات الأعداد الصحيحة
13.2
ترميز طول التسلسل
English
Run-length encoding (RLE) is a simple compression 压缩 method: replace each run 游程 of repeated characters with a count and the character. It is lossless 无损 — the original is fully recoverable.
Common mistakes
& is bitwise AND and && is logical AND — do not confuse them.
A left shift << 1 doubles a value; a right shift >> 1 halves it.
Bit n has value 1 << n (C has no ** power operator); check a bit with (x >> n) & 1.
العربية
ترميز طول التسلسل (RLE) هو طريقة ضغط بسيطة: استبدل كل تسلسل من الأحرف المكررة بعدد والحرف. إنه غير قابل للفقدان — يمكن استعادة الأصل بالكامل.
#include <stdio.h>
#include <string.h>
int main(void) {
char *s = "aaabbc";
int n = strlen(s);
for (int i = 0; i < n; ) {
char c = s[i];
int run = 0;
while (i < n && s[i] == c) { run++; i++; }
printf("%d%c", run, c); // 3a2b1c
}
printf("\n");
return 0;
}
أخطاء شائعة
& هو AND للبتات و&& هو AND المنطقي — لا تخلط بينهما.
The preprocessor 预处理器 runs before compiling. #define makes a macro 宏 — plain text replaced everywhere. const makes a constant 常量 that cannot change. static inside a function keeps a variable's value between calls. An enum (enumeration 枚举) names a set of integers starting at 0.
Bigger programs split across files: declarations go in a header 头文件 file (mine.h), included with #include "mine.h" — quotes mean your own file, < > means the standard library. An include guard (#ifndef MINE_H / #define MINE_H / #endif) stops a header being included twice.
Common mistakes
#define does plain text replacement with no type checking; wrap macro bodies and arguments in parentheses.
A const value cannot be changed after it is set.
A static local variable keeps its value between calls to the function.
العربية
المعالج المسبق يعمل قبل الترجمة. #define يصنع ماكرو — استبدال نص عادي في كل مكان. const يصنع ثابتًا لا يمكن تغييره. static داخل دالة يحافظ على قيمة متغير بين الاستدعاءات. enum (تعداد) يسمي مجموعة من الأعداد الصحيحة تبدأ من 0.
#include <stdio.h>
#define MAX 100 // macro: text replaced before compiling
enum Color { RED, GREEN, BLUE }; // named integers 0, 1, 2
int next_id(void) {
static int count = 0; // keeps its value between calls
count++;
return count;
}
int main(void) {
const double PI = 3.14; // cannot be changed
printf("%d %.2f\n", MAX, PI); // 100 3.14
printf("%d %d %d\n", RED, GREEN, BLUE); // 0 1 2
int a = next_id();
int b = next_id();
printf("%d %d\n", a, b); // 1 2
return 0;
}
البرامج الأكبر تتوزع على ملفات متعددة: Declarations توضع في ملف رأس (mine.h)، يتم تضمينه باستخدام #include "mine.h" — علامات التنصيص تعني ملفك الخاص، بينما < > تعني المكتبة القياسية. حارس التضمين (#ifndef MINE_H / #define MINE_H / #endif) يمنع تضمين الرأس مرتين.
أخطاء شائعة
#define يقوم باستبدال نص عادي دون فحص أنواع; غلف أجسام الماكرو وحججها بين أقواس.
لا يمكن تغيير قيمة const بعد تعيينها.
متغير محلي static يحتفظ بقيمته بين استدعاءات الدالة.
#define, const, enum, و static يحافظون على وضوح الكود
Pick one and the site follows you — notes, papers, videos and practice all open on it. · اختر واحدًا وسيتبعك الموقع — الملاحظات، الأوراق، الفيديوهات والتدريب جميعها تفتح عليه.
Type to search notes, lessons, code, vocabulary and past-paper questions across every subject. · اكتب للبحث عن ملاحظات، دروس، أكواد، مفردات وأسئلة امتحانات سابقة عبر جميع المواد.