C: المعاملات والتعبيرات

المعاملات أشبه بأدوات المطبخ - تستخدم السكين للتقطيع والمقلاة للقلي. مكونات مختلفة تحتاج أدوات مختلفة، وحسابات مختلفة تحتاج معاملات مختلفة.

1. المعاملات الحسابية

توفر C سبعة معاملات حسابية أساسية لأكثر الحسابات الرياضية شيوعا.

المعامل المعنى مثال النتيجة
+ الجمع 5 + 3 8
- الطرح 5 - 3 2
* الضرب 5 * 3 15
/ القسمة 7 / 2 3
% باقي القسمة 7 % 2 1
+ إيجابي أحادي +5 5
- سلبي أحادي -5 -5

(1) فخ القسمة الصحيحة

عند قسمة عددين صحيحين، النتيجة أيضا عدد صحيح - يُتجاهل الجزء الكسري ببساطة، بدون تقريب.

C
#include <stdio.h>

int main(void) {
    int a = 7;
    int b = 2;
    printf("%d / %d = %d\n", a, b, a / b);
    printf("%d %% %d = %d\n", a, b, a % b);
    return 0;
}
TEXT 📖 للعرض فقط
7 / 2 = 3
7 % 2 = 1
💡 نصيحة: للحصول على نتيجة بكسور عشرية، اجعل أحد المعاملات عددا عشريا على الأقل: 7.0 / 2 تعطي 3.5.

(2) استخدامات معامل باقي القسمة

معامل باقي القسمة % يعمل فقط مع الأعداد الصحيحة. له عدة حالات استخدام عملية جدا:

C
#include <stdio.h>

int main(void) {
    int n = 12345;
    printf("آخر رقم: %d\n", n % 10);
    printf("زوجي: %s\n", n % 2 == 0 ? "نعم" : "لا");
    return 0;
}
TEXT 📖 للعرض فقط
آخر رقم: 5
زوجي: لا

2. معاملات الزيادة والنقصان

معامل الزيادة ++ يضيف 1 إلى متغير، و -- يطرح 1. لكل منهما شكلان: سابقي ولاحق، يختلفان فيما يُرجعه التعبير.

(1) السابقي مقابل اللاحق

الشكل الاسم التأثير قيمة التعبير
++i زيادة سابقة i تزداد بـ 1 القيمة الجديدة (المزادة)
i++ زيادة لاحقة i تزداد بـ 1 القيمة القديمة (الأصلية)
--i نقصان سابقي i تنقص بـ 1 القيمة الجديدة (المنقصة)
i-- نقصان لاحق i تنقص بـ 1 القيمة القديمة (الأصلية)
C
#include <stdio.h>

int main(void) {
    int a = 5;
    int b = ++a;
    printf("سابقي: a=%d, b=%d\n", a, b);

    int c = 5;
    int d = c++;
    printf("لاحق: c=%d, d=%d\n", c, d);
    return 0;
}
TEXT 📖 للعرض فقط
سابقي: a=6, b=6
لاحق: c=6, d=5
⚠️ ملاحظة: لا تستخدم ++ أو -- على نفس المتغير عدة مرات داخل تعبير واحد، مثل a = ++a + a++. السلوك غير معرف، والمترجمات المختلفة ستعطي نتائج مختلفة.


3. معاملات العلاقات

تقارن معاملات العلاقات بين قيمتين، وتُرجع "صحيح" (1) أو "خطأ" (0).

المعامل المعنى مثال النتيجة
== يساوي 5 == 5 1
!= لا يساوي 5 != 3 1
< أصغر من 3 < 5 1
> أكبر من 3 > 5 0
<= أصغر من أو يساوي 5 <= 5 1
>= أكبر من أو يساوي 3 >= 5 0
C
#include <stdio.h>

int main(void) {
    int a = 10;
    int b = 20;
    printf("a == b: %d\n", a == b);
    printf("a != b: %d\n", a != b);
    printf("a < b:  %d\n", a < b);
    return 0;
}
TEXT 📖 للعرض فقط
a == b: 0
a != b: 1
a < b:  1
⚠️ ملاحظة: == للمقارنة، = للإسناد. الخلط بينهما يحول المقارنة إلى إسناد لن يُنتج خطأ. عادة جيدة: ضع الثابت على اليسار: 5 == a - إذا كتبت بالخطأ 5 = a، سيكشف المترجم الخطأ.


4. المعاملات المنطقية

تجمع المعاملات المنطقية بين شروط متعددة، وتُرجع أيضا 1 (صحيح) أو 0 (خطأ).

المعامل المعنى مثال النتيجة
&& و المنطقية 1 && 0 0
` ` أو المنطقية
! نفي المنطقية !0 1

(1) جدول الصواب

| A | B | A && B | A || B | !A | |---|---|--------|--------|----| | 0 | 0 | 0 | 0 | 1 | | 0 | 1 | 0 | 1 | 1 | | 1 | 0 | 0 | 1 | 0 | | 1 | 1 | 1 | 1 | 0 |

(2) التقييم قصير الدائرة

مع &&، إذا كان الطرف الأيسر خطأ، لا يُقيّم الطرف الأيمن أبدا. مع ||، إذا كان الطرف الأيسر صحيحا، يُتجاوز الطرف الأيمن. هذه الميزة يمكن استخدامها لتجنب العمليات غير القانونية:

C
#include <stdio.h>

int main(void) {
    int divisor = 0;
    int value = 10;
    if (divisor != 0 && value / divisor > 5) {
        printf("الشرط متحقق\n");
    } else {
        printf("الشرط غير متحقق، ولا قسمة على صفر\n");
    }
    return 0;
}
TEXT 📖 للعرض فقط
الشرط غير متحقق، ولا قسمة على صفر
💡 نصيحة: في C، 0 هو خطأ وأي قيمة غير صفرية هي صحيح (بما فيها السالبة). لذا -5 "صحيحة" في سياق منطقي.


5. معاملات الإسناد

معامل الإسناد الأساسي = يخزن القيمة في الطرف الأيمن في متغير الطرف الأيسر. توفر C أيضا معاملات إسناد مركبة تجمع بين عملية وإسناد.

المركبة المكافئة
a += b a = a + b
a -= b a = a - b
a *= b a = a * b
a /= b a = a / b
a %= b a = a % b
C
#include <stdio.h>

int main(void) {
    int score = 80;
    score += 10;
    printf("بعد المكافأة: %d\n", score);
    score -= 25;
    printf("بعد العقوبة: %d\n", score);
    score *= 2;
    printf("بعد المضاعفة: %d\n", score);
    return 0;
}
TEXT 📖 للعرض فقط
بعد المكافأة: 90
بعد العقوبة: 65
بعد المضاعفة: 130

6. المعامل الشرطي (المعامل الثلاثي)

المعامل الشرطي ?: هو المعامل الثلاثي الوحيد في C. صياغته:

TEXT 📖 للعرض فقط
condition ? expression1 : expression2

إذا كان الشرط صحيحا، يُقيّم expression1؛ وإلا يُقيّم expression2. هو اختصار لـ if-else.

C
#include <stdio.h>

int main(void) {
    int age = 20;
    char *status = age >= 18 ? "بالغ" : "قاصر";
    printf("العمر %d، %s\n", age, status);

    int a = 15, b = 28;
    int max = a > b ? a : b;
    printf("القيمة الأكبر: %d\n", max);
    return 0;
}
TEXT 📖 للعرض فقط
العمر 20، بالغ
القيمة الأكبر: 28

7. معامل الفاصلة

معامل الفاصلة , يُقيّم كل تعبير من اليسار إلى اليمين، وقيمة تعبير الفاصلة بالكامل هي قيمة آخر تعبير.

C
#include <stdio.h>

int main(void) {
    int a, b, c;
    c = (a = 1, b = 2, a + b);
    printf("a=%d, b=%d, c=%d\n", a, b, c);
    return 0;
}
TEXT 📖 للعرض فقط
a=1, b=2, c=3
⚠️ ملاحظة: معامل الفاصلة يمتلك أقل أسبقية بين جميع المعاملات. لا تخلط بين معامل الفاصلة والفواصل بين وسائط الدوال - تلك ليست معاملات فاصلة.


8. معامل sizeof

sizeof تُرجع عدد البايتات التي يشغلها نوع بيانات أو متغير في الذاكرة. يُقيّم وقت الترجمة، وليس وقت التشغيل.

C
#include <stdio.h>

int main(void) {
    printf("char:   %zu bytes\n", sizeof(char));
    printf("int:    %zu bytes\n", sizeof(int));
    printf("float:  %zu bytes\n", sizeof(float));
    printf("double: %zu bytes\n", sizeof(double));

    int arr[5] = {1, 2, 3, 4, 5};
    printf("الحجم الكلي للمصفوفة: %zu bytes\n", sizeof(arr));
    printf("عدد عناصر المصفوفة: %zu\n", sizeof(arr) / sizeof(arr[0]));
    return 0;
}
TEXT 📖 للعرض فقط
char:   1 bytes
int:    4 bytes
float:  4 bytes
double: 8 bytes
الحجم الكلي للمصفوفة: 20 bytes
عدد عناصر المصفوفة: 5
💡 نصيحة: sizeof تتطلب أقواسا لأسماء الأنواع (sizeof(int)) لكن ليس للمتغيرات (sizeof a). ومع ذلك، للاتساق، من الأفضل استخدام الأقواس دائما.


9. أسبقية المعاملات

عندما يحتوي تعبير على معاملات متعددة، يُقيّم ذو الأسبقية الأعلى أولا. الجدول أدناه يسردها من الأعلى إلى الأدنى:

الأسبقية المعاملات التجميع
1 (الأعلى) () [] -> . من اليسار لليمين
2 ! ~ ++ -- +(أحادي) -(أحادي) *(تgunref) &(أخذ العنوان) sizeof من اليمين لليسار
3 * / % من اليسار لليمين
4 + - من اليسار لليمين
5 << >> من اليسار لليمين
6 < <= > >= من اليسار لليمين
7 == != من اليسار لليمين
8 & من اليسار لليمين
9 ^ من اليسار لليمين
10 ` `
11 && من اليسار لليمين
12 `
13 ?: من اليمين لليسار
14 = += -= *= /= %= إلخ من اليمين لليسار
15 (الأدنى) , من اليسار لليمين
🔥 خطأ شائع: لا يمكنك حفظ جدول الأسبقية؟ لا تتعب نفسك - عند الشك، أضف أقواسا. لها دائما الأولوية القصوى وتجعل شفرتك أوضح.

▶ مثال

اجمع معاملات متنوعة لحساب مجموع أرقام عدد مكون من ثلاثة أرقام:

C
#include <stdio.h>

int main(void) {
    int num = 952;
    int hundreds = num / 100;
    int tens = (num / 10) % 10;
    int ones = num % 10;
    int sum = hundreds + tens + ones;

    printf("العدد: %d\n", num);
    printf("مئات: %d، عشرات: %d، آحاد: %d\n", hundreds, tens, ones);
    printf("مجموع الأرقام: %d\n", sum);
    return 0;
}
▶ جرّب الكود
TEXT 📖 للعرض فقط
العدد: 952
مئات: 9، عشرات: 5، آحاد: 2
مجموع الأرقام: 16

▶ مثال

استخدم المعاملات المنطقية ومعاملات العلاقات لتحديد ما إذا كانت سنة كبيسة:

C
#include <stdio.h>

int main(void) {
    int year = 2024;
    int is_leap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);

    printf("%d %sسنة كبيسة\n", year, is_leap ? "" : "ليست ");
    return 0;
}
▶ جرّب الكود
TEXT 📖 للعرض فقط
2024 سنة كبيسة

10. تحويل الأنواع

(1) التحويل الضمني

عند خلط أنواع مختلفة في تعبير، يُحوّل المترجم تلقائيا النوع ذو الدقة الأدنى إلى النوع ذو الدقة الأعلى:

C
#include <stdio.h>

int main(void) {
    int a = 5;
    double b = 2.0;
    double c = a / b;
    printf("5 / 2.0 = %f\n", c);

    char ch = 'A';
    int code = ch + 1;
    printf("'A' + 1 = %c (ASCII %d)\n", code, code);
    return 0;
}
TEXT 📖 للعرض فقط
5 / 2.0 = 2.500000
'A' + 1 = B (ASCII 66)

اتجاه التحويل: charintlongdouble، intunsignedlongdouble.

(2) التحويل الصريح

استخدم (type_name) لإجبار قيمة على نوع محدد:

C
#include <stdio.h>

int main(void) {
    int a = 7, b = 2;
    double result = (double)a / b;
    printf("مع التحويل: %f\n", result);
    return 0;
}
TEXT 📖 للعرض فقط
مع التحويل: 3.500000
⚠️ ملاحظة: التحويل لا يغير قيمة أو نوع المتغير الأصلي - بل يُنتج فقط قيمة جديدة مؤقتة.


❓ أسئلة شائعة

س هل هناك فرق بين a++ و ++a عند استخدامهما في سطر منفصل؟
ج لا. الفرق يظهر فقط عند استخدام القيمة المرجعة داخل تعبير. بمفردهما، التأثير متماثل، رغم أن الزيادة السابقة أسريعا نظريا بقليل.
س كيف أميز بين = و ==؟
ج = للإسناد ("يصبح")، == للمقارنة ("هل يساوي؟"). كتابة if (a = 0) بالخطأ لن تسبب خطأ لكنها تغير المنطق تماما. عادة جيدة: ضع الثابت على اليسار - if (0 == a) - ليُكشف خطأ الكتابة مثل if (0 = a) من قبل المترجم.
س هل يمكن استخدام المعامل % مع أعداد الفاصلة العائمة؟
ج لا. % يعمل فقط مع الأنواع الصحيحة. لباقي قسمة الفاصلة العائمة، استخدم الدالة fmod() من #include <math.h>.
س هل أحتاج لحفظ جدول أسبقية المعاملات بالكامل؟
ج لا. فقط تذكر أن الضرب/القسمة/باقي القسمة تأتي قبل الجمع/الطرح، والنفي المنطقي يسبق و المنطقية التي تسبق أو المنطقية. لكل شيء آخر، أضف أقواسا - إنه أكثر أمانا.

📖 ملخص

📝 تمارين

  1. اكتب برنامجا يأخذ عددا من الثواني (مثلا 3661) ويستخدم / و % لحساب الساعات والدقائق والثواني المقابلة، ثم يُخرج النتيجة.
  2. اكتب برنامجا يأخذ عددين صحيحين ويستخدم المعامل الثلاثي لإيجاد وإخراج القيمتين الأكبر والأصغر.
  3. اكتب برنامجا يستخدم sizeof لطباعة أحجام short و int و long و long long على حاسوبك ولاحظ النتائج.
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%