العمليات الحسابية في البرمجة
السلام عليكم ورحمة الله وبركاته
الفهرس
المقدمة
في أي لغة برمجة ستجدها تقدم لك امكانيات لتقوم بعمليات حسابية متنوعة
سواء جمع وطرح وضرب وغيرها من العمليات المختلفة
وهنا أنواع متنوعة من العمليات التي يمكنك أن تقوم بها من ضمنها
- عمليات حسابية على مستوى الأرقام مثل الجمع و الطرح و الضرب و القسمة و باقي القسمة
وهي العمليات البسيطة والتي نعرفها مثل
5 + 3
و2 * 5
و10 / 2
- عمليات حسابية على مستوي القيم المنطقية
boolean
والتي تشمل:- مثل المقارنات مثل أكبر من و أصغر من و يساوي و لا يساوي
ووهي عمليات المقارنة الاعتيادية مثل5 > 3
و2 == 2
و10 != 2
سنشرح كل شيء بالتفصيل لاحقًا - عمليات بالبوابات المنطقية مثل
AND
وOR
وNOT
وXOR
وهي العمليات التي تستخدم في القيم الشرطية وسنستخدمها بكثرة في البرمجة مثلtrue && false
وtrue || false
وبالطبع سنشرح هذا
- مثل المقارنات مثل أكبر من و أصغر من و يساوي و لا يساوي
- عمليات حسابية على مستوى الأرقام الثنائية
Binary Number
مثل0
و1
وباستخدام عمليات مثلAND
وOR
وXOR
وNOT
وSHIFT
وهي عمليات دقيقة جدا وتستخدم في التعامل مع الأرقام على مستوى0
و1
مثل1010 & 1100
و1010 | 1100
وغيرها
العمليات الحسابية البسيطة
العمليات الحسابية التي كنت تقوم بها في الرياضيات ستجدها كما هي في لغات البرمجة البرمجة ولكن مع بعض الاختلافات والاضافات الطفيفة
معظم لغات اللبرمجة ستجدها تقدم لك العمليات الحسابية الأساسية مثل:
الجمع +
في أي لغة برمجة نستخدم +
لكي تجمع مجموعة من الأرقام
int sum_1 = 5 + 3 + 10; // 18
float sum_2 = 5.5 + 3.5 + 10.5; // 19.5
الأمر بسيط كما ترى هنا جمعنا الأرقام 5
و 3
و 10
ثم خزنا الناتج وهو 18
في متغير sum_1
نوعه int
وفي السطر الثاني جمعنا الأرقام 5.5
و 3.5
و 10.5
وحصلنا على الناتج 19.5
وخزناه في متغير sum_2
نوعه float
لكن سؤال هنا هل يمكننا جمع قيم من نوعين مختلفين؟
الإجابة نعم في معظم اللغات لكن ستقابلك مشكلة أثناء التخزين
int sum = 5 + 3.5;
هنا قمنا بجمع العددين 5
و 3.5
ستجد أن الناتج هو 8.5
ولكن عند محاولة تخزينه في متغير من نوع int
ستجد أن الجزء الكسري تم حذفه وتم تخزين القيمة 8
فقط وليس 8.5
التحويل الذي حصل يسمى casting
وهي عملية تحويل القيم من نوع إلى نوع آخر
في المثال السابق تم تحويل القيمة 8.5
التي كانت من نوع float
إلى 8
وأصبحت من نوع int
بعض اللغات تسمع لك بالقيام بعمليات الجمع بين المتغيرات النصية من نوع string
وهنا يتم دمج النصوص معًا وليس جمع الأرقام
string first_name = "Ahmed";
string last_name = "El-Tabarani";
string name = first_name + ' ' + last_name;
لدينا متغيرين من نوع string
الأول first_name
والثاني last_name
ثم قمنا بجمع المتغيرين مع مسافة بينهما وحصلنا على الناتج النهائي Ahmed El-Tabarani
في المتغير name
الطرح -
في أي لغة برمجة نستخدم -
لكي نقوم بعملية الطرح
int sub_1 = 10 - 5; // 5
float sub_2 = 10.2 - 5.5; // 4.7
هنا قمنا بطرح العددين 10
و 5
وحصلنا على الناتج 5
وخزناه في متغير sub_1
وفي السطر الثاني قمنا بطرح العددين 10.2
و 5.5
وحصلنا على الناتج 4.7
وخزناه في متغير sub_2
وتذكر أن هنا ستحدث نفس الشيء عند محاولة تخزين قيمة من نوع float
كـ 4.7
في متغير من نوع int
سيتم تخزين القيمة كـ 4
فقط
int sub = 10.2 - 5.5; // 4
الضرب *
في لغات البرمجة نستخدم *
لكي نقوم بعملية الضرب
int mul_1 = 5 * 3; // 15
float mul_2 = 5.5 * 3.5; // 19.25
هنا قمنا بضرب العددين 5
و 3
وحصلنا على الناتج 15
وخزناه في متغير mul_1
وفي السطر الثاني قمنا بضرب العددين 5.5
و 3.5
وحصلنا على الناتج 19.25
وخزناه في متغير mul_2
في لغات حديثة تستخدم *
و ×
للضرب ولكن في معظم اللغات ستجدها تستخدم *
فقط
هناك لغات مثل الـ Python
تسمح لك بالقيام بعمليات الضرب بين النصوص string
لتكرار النص
name = "Ahmed" * 3 # AhmedAhmedAhmed
هنا قمنا بضرب النص Ahmed
في العدد 3
وحصلنا على الناتج AhmedAhmedAhmed
وهو تكرار النص ثلاث مرات
كل لغة قد تقدم لك بعض الخصائص والمميزات لتسهل عليك بعض الأمور لذا ادرس للغة التي تنوي تعلمها وتعرف مميزاتها
القسمة /
في لغات البرمجة نستخدم /
لكي نقوم بعملية القسمة
int div_1 = 10 / 2; // 5
float div_2 = 10.5 / 2.5; // 4.2
هنا قمنا بقسمة العددين 10
على 2
وحصلنا على الناتج 5
وخزناه في متغير div_1
وفي السطر الثاني قمنا بقسمة العددين 10.5
على 2.5
وحصلنا على الناتج 4.2
وخزناه في متغير div_2
في لغات حديثة تستخدم /
و ÷
للقسمة ولكن في معظم اللغات ستجدها تستخدم /
فقط
هناك أمور في القسمة يجب أن تعرفها جيدًا
float div = 3 / 2;
هنا قمنا بقسمة العددين 3
على 2
الناتج البديهي هو 1.5
ولكن ستتفاجيء بأن الناتج الذي حصلنا عليه هو 1
فقط برغم من أن المتغير div
من نوع float
هذا يحدث لأن القيمتين 3
و 2
هما من نوع int
وعند قيام العملية الحسابية تم تحويل الناتج إلى int
وليس float
لأن لغات البرمجة ستتعامل بالنوع فعندما تجد قيمتين من نوع int
ستقوم بإعطاءك الناتج من نوع int
لكي تحصل على الناتج الصحيح يجب أن تقوم بتحويل أحد الرقمين إلى float
float div = 3.0 / 2; // 1.5
هنا قمنا بتحويل الرقم 3
إلى 3.0
هكذا ستفهم اللغة أن الرقم من نوع float
وبالتالي سيتم تحويل الناتج إلى float
وليس int
يكفي أن تقوم بتحويل أحد الأرقام إلى float
لتكون الحسبة كلها من نوع float
لأن الـ float
يطغى على الـ int
في الحسابات
هناك لغة مثل Python
تستخدم /
للقسمة ولكن تعطيك الناتج بنوع float
مباشرة
وتستخدم //
للقسمة ولكن تعطيك الناتج بنوع int
div = 3 / 2 # 1.5
div = 3 // 2 # 1
يوجد طرق أخرى لتحويل الأرقام من int
إلى float
وتسمي casting
كما ذكرنا سابقًا وهي كالتالي:
- تستطيع كتابة
3
هكذا3.0
بشكل يدوي - أو تكتب
3
وتضع الـf
بعد الرقم هكذا3f
بشكل يدوي - أو تكتب
float
وتضع الرقم بين أقواس هكذاfloat(3)
مفيدة عندما تتعامل مع متغيرات لا تستطيع التحكم وتغيرها يدويًاfloat(x)
- أو تكتب
float
بين أقواس وتضع الرقم بجانبها هكذا(float) 3
وتستطيع فعلها مع المتغيرات أيضًا(float) x
يمكنك فعل الشيء لتحويل الأرقام من float
إلى int
بنفس الطرق
باقي القسمة %
في لغات البرمجة نستخدم %
لكي نقوم بعملية القسمة ونحصل على الباقي
قد تسمى Modulus
أو Remainder
وهي باقي القسمة بين العددين
بعض اللغات قد تجدها تستخدم mod
بدلاً من %
لكي تقوم بعملية باقي القسمة
int mod = 3 % 2; // 1
على سبيل المثال 3 % 2
تعني باقي القسمة بين 3
و 2
هو 1
وهذا معناه أن ناتج القسمة 3 / 2
يعطينا عدد عشري وهو 1.5
بسبب أنه لا يمكن قسمة 3 / 2
بشكل متساوي دون كسور
تخيل أن معك ثلاث تفاحات وتريد تقسيمها على شخصين بالتساوي فكيف ستفعل؟
ستعطي كل شخص تفاحة كاملة وسيتبقى معك تفاحة واحدة وهذه التفاحة هي باقي القسمة التي قمت بها
ويمكنك حساب باقي القسمة بشكل يدوي عن طريق ايجاد قسمة 3 / 2
ستحصل على 1.5
الرقم الصحيح هو 1
والكسر المتبقي هو 0.5
الآن عندما تضرب العدد الكسري 0.5
المتبقي المعامل الثاني وهو 2
الناتج سيكون 1
وهو باقي القسمة
مثال أخر 8 % 4
لحساب باقي القسمة أول شيء أحسب ناتج القسمة 8 / 4
ستحصل على 2
وهو عدد صحيح ليس به أي كسر وهذا يعني أن باقي القسمة 8 % 4
هو 0
ملحوظة
: عندما تقوم بقسمة عددين والناتج يكون عدد صحيح بدون كسر فهذا يعني أن باقي القسمة هو0
وهذا يعني أن العدد الأول يقبل القسمة على العدد الثاني أو أنه من مضاعفات العدد التاني
فإذا كان8 % 4
تساوي0
إذًا الرقم8
يقبل القسمة على4
بدون باقي وهذا يعني أن8
هو من مضاعفات العدد4
وهكذا مع كل شئ مثل9 % 3
ستجد أن الناتج هو0
وهذا يعني أن الرقم9
يقبل القسمة على3
بدون باقي وهو من مضاعفات العدد3
هناك طرق عديدة لحساب باقي القسمة وهي
سنستخدم مثال أخر 19 % 5
ونطبق الطرق المختلفة عليها
- الطريقة الأولى: (الطريقة التي جعلتني أنا شخصيًا استوعب ما هو باقي القسمة)
- معك
19
تفاحة وتريد توزيعها على5
أشخاص بالتساوي كم تفاحة كاملة ستعطي لكل شخص ؟ ستجد أن باقي القسمة هو اجابة سؤال وكم سيتبقى معك ؟ - ستعطي كل شخص
3
تفاحات كاملة (19 / 5 = 3 عدد صحيح
) - سيتبقى معك
4
تفاحات كاملة وهذا هو باقي القسمة (19 % 5 = 4
)
- معك
- الطريقة الثانية:
- نحسب ناتج القسمة
19 / 5
سنحصل على3.8
- نحدد العدد الكسري المتبقي
0.8
- نضرب العدد الكسري
0.8
في المعامل الثاني5
هكذا0.8 * 5
سنحصل على4
وهو باقي القسمة
- نحسب ناتج القسمة
- الطريقة الثالثة:
- نحسب ناتج قسمة
19 / 5
سنحصل على3.8
- نحدد الجزء الصحيح وهو
3
- نضرب الجزء الصحيح
3
في المعامل الثاني5
هكذا3 * 5
سنحصل على15
- نطرح الناتج
15
من المعامل الأول19
وسنحصل على باقي القسمة19 - 15
سنحصل على4
وهو باقي القسمة
- نحسب ناتج قسمة
- الطريقة الرابعة:
- تسأل نفسك سؤال ما هو الرقم الذي يكون اصغر من
19
ويكون من مضاعفات الرقم5
؟ - ستجد أن الرقم الذي يكون أصغر من
19
ويكون من مضاعفات الرقم5
هو15
- أطرح
15
من19
وستحصل على باقي القسمة19 - 15
ستحصل على4
وهو باقي القسمة
- تسأل نفسك سؤال ما هو الرقم الذي يكون اصغر من
نمط نواتج باقي القسمة
الناتج الخاص بباقي القسمة لأي عدد له نمط معين وأريدك أن تكتشفه
لنحسب باقي القسمة الأرقام من 0
إلى 10
للرقم 2
ونرى النمط الذي يحدث
0 % 2 = 0
1 % 2 = 1
2 % 2 = 0
3 % 2 = 1
4 % 2 = 0
5 % 2 = 1
6 % 2 = 0
7 % 2 = 1
8 % 2 = 0
9 % 2 = 1
10 % 2 = 0
هل لاحظت النمط الذي حدث ؟
النواتج محصورة بين 0
و 1
فقط وهذا يعني أن باقي القسمة لأي عدد على 2
سيكون إما 0
أو 1
فقط
دعنا نحسب الأرقام من 0
إلى 10
للرقم 3
ونرى النمط الذي يحدث
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
6 % 3 = 0
7 % 3 = 1
8 % 3 = 2
9 % 3 = 0
10 % 3 = 1
هل لاحظت النمط مجددًا ؟
النواتج محصورة بين 0
و 1
و 2
فقط وهذا يعني أن باقي القسمة لأي عدد على 3
سيكون إما 0
أو 1
أو 2
فقط
دعونا نرى مع الرقم 7
0 % 7 = 0
1 % 7 = 1
2 % 7 = 2
3 % 7 = 3
4 % 7 = 4
5 % 7 = 5
6 % 7 = 6
7 % 7 = 0
8 % 7 = 1
9 % 7 = 2
10 % 7 = 3
ستلاحظ أن الناتج يكون محصور بين 0
و n - 1
حيث n
هو الرقم الذي تقوم بقسمة العدد عليه
بالتالي باقي قسمة أي رقم على 12
الناتج سيكون محصور بين 0
و 11
فقط
وباقي قسمة أي رقم على 50
الناتج سيكون محصور بين 0
و 49
فقط
وباقي قسمة أي رقم على 1458
الناتج سيكون محصور بين 0
و 1457
فقط
... وهكذا
بعض فوائد باقي القسمة في البرمجة
باقي القسمة له استخدامات متعددة ومفيدة جدًا في البرمجة ويحل لنا مسائل كثيرة بطرق بسيطة وسهلة
وقد نحتاج لمقالة كاملة لنتحدث عنها وعن تطبيقاتها ونحل بعض المسائل البرمجية باستخدامها
معرفة الأعداد الزوجية والفردية
على سبيل المثال إذا اعطيتك رقم عشوائيًا مثل 6
وقلت لك هل هذا الرقم زوجي أم فردي؟
ستقول لي بسيطة الرقم 6
هو رقم زوجي، أنت عرفت هذا لأنك ما شاء الله عليك بني آدم ذكي وتعرف ذلك بسرعة
لكن لغة البرمجة كيف لها أن تعرف هذا؟
السؤال هنا كيف عرفت أنت أن الرقم 6
هو زوجي؟
الجواب بسيط جدًا لأنك تعرف أن الأعداد الزوجية هي التي تقبل القسمة على 2
بدون باقي
والأعداد الفردية هي التي إذا قسمتها على على 2
وتحصل على عدد به كسور
إذا ففي البرمجة نستطيع أن نعرف إذا كان الرقم زوجي أم فردي بسهولة عن طريق باقي القسمة
int number = 6;
int is_even = number % 2 // 0
هنا قمنا بحساب باقي قسمة الرقم 6
على 2
وبما أن الناتج 0
إذًا الرقم 6
هو زوجي
int number = 7;
int is_even = number % 2 // 1
هنا قمنا بحساب باقي قسمة الرقم 7
على 2
وبما أن الناتج 1
وليس 0
إذًا الرقم 7
هو فردي
حساب أنماط الأوقات والأيام
وأيضًا يفيدنا في حساب الأنماط العددية التي تكرر بشكل دوري كوقت والأيام وغيرها
فمثلا في الساعة إذا كانت الساعة الآن 18
وقلت لك كم الساعة الآن على مقياس 12
ساعة ؟
ستقول لي بسيطة الساعة الآن 6
لأنك تعرف أن الساعات تكرر كل 12
ساعة بالتالي 18 - 12 = 6
حسنا إذا كانت الساعة الآن 34
وقلت لك كم الساعة الآن على مقياس 12
ساعة ؟
قد تقوم بحسابها بشكل يدوي وتقول لي الساعة الآن 10
لأن 34 - 12 - 12 = 10
ماذا إذا زاد الرقم وأصبح 110
وقلت لك كم الساعة الآن على مقياس 12
ساعة ؟ سيكون الأمر صعبًا أليس كذلك
لكن في البرمجة يمكننا حسابها بسهولة عن طريق باقي القسمة كيف ذلك ؟
عندما قلت لك أن الساعة الآن 34
وقلت لي أن الساعة الآن على مقياس 12
ساعة ستكون 10
حسنًا الساعة تتكرر كل 12
لذا لكي تعرف كم يساوي الرقم 34
على مقياس 12
ساعة
عليك أن تطرح منه 12
حتى تحصل على الرقم 10
هذا هو مفهوم باقي القسمة أنك تحاول تقسيم الرقم 34
على 12
وترى كم سيتبقى معك
int hour = 34;
int hour_12 = hour % 12; // 10
هنا قمنا بقسمة الرقم 34
على 12
وحصلنا على الناتج 10
وهو الساعة الآن على مقياس 12
ساعة
هكذا يمكننا حل أي مسألة مشابهة عن طريق إيجاد باقي القسمة
- الساعة الآن
110
على مقياس12
كم تكون ؟110 % 12
ستحصل على2
وهو الساعة الآن على مقياس12
ساعة
- الساعة الآن
110
على مقياس24
كم تكون ؟110 % 24
ستحصل على14
وهو الساعة الآن على مقياس24
ساعة
- الساعة
110
على مقياس60
كم تكون ؟110 % 60
ستحصل على50
وهو الساعة الآن على مقياس60
دقيقة
- ... وهكذا
الأمر لا يختصر على السعات بل يمكن تطبيق نفس الفكرة على الأيام والأشهر والأعوام وغيرها من الأنماط العددية التي تتكرر بشكل دوري
إليك سؤال مختلف قليلًا إذا سألك أحد وقال لك الساعة الآن 7
وقال لك كم ستكون الساعة بعد 15
ساعة ؟ على مقياس 12
ساعة
كيف ستحل هذه المسألة ؟
سنتبع نفس المبدأ فقط الاختلاف أنك ستجمع 7
و 15
ثم ترى الناتج كيف سيكون على مقياس 12
ساعة
int current_hour = 7;
int after_hour = 15;
int hour_12 = (current_hour + after_hour) % 12; // 10
هنا قمنا بجمع الساعة الحالية 7
مع الساعات الزائدة الذي أرادها 15
وحصلنا على الناتج 22
ثم قمنا بحساب باقي قسمة 22
على 12
لنحصل على 10
وهو الساعة الآن على مقياس 12
ساعة
لو اليوم كان يوم الثلاثاء وقلت لك بعد 45
يوم سيكون أي يوم من أيام الأسبوع ؟
يوم الثلاثاء هو اليوم رقم 3
في الأسبوع وبعد 45
يوم سيكون اليوم رقم 48
بالتالي يمكننا حساب اليوم بعد 45
يوم بسهولة عن طريق باقي القسمة
int current_day = 3;
int after_day = 45;
int day = (current_day + after_day) % 7; // 6
هنا قمنا بجمع اليوم الحالي 3
مع الأيام الزائدة الذي أرادها 45
وحصلنا على الناتج 48
ثم قمنا بحساب باقي قسمة 48
على 7
لنحصل على 6
وهو يمثل يوم الجمعة
وهكذا يمكننا حل أي مسألة مشابهة بسهولة
ملحوظة
: المثال الأخير هو مجرد حيلة نستخدمها لحل معضلة ما في باقي القسمة
وهي أننا نحاول تحويل نطاق النواتج الخاص بباقي القسمة من0
إلىn - 1
إلى1
إلىn
وهذا المثال مجرد توسيع افاق مع باقي القسمة وليس له علاقة بفهم مفهوم باقي القسمة بحد ذاتها
ستلاحظ هنا شيئًا أن في مثال الساعة عندما تكون الساعة 12
وقلت لك كم الساعة على مقياس 12
ساعة ستجيب لي بـ 0
لأن 12 % 12 = 0
لكن كمنظور بشري لا يوجد ساعة 0
فكيف يمكننا حل هذه المشكلة ؟
قلنا أن باقي قسمة أي رقم على n
سيكون محصور بين 0
و n - 1
بالتالي قسمة أي رقم على 12
سيكون الناتج محصور بين 0
و 11
12 % 12 = 0
1 % 12 = 1
2 % 12 = 2
3 % 12 = 3
4 % 12 = 4
5 % 12 = 5
6 % 12 = 6
7 % 12 = 7
8 % 12 = 8
9 % 12 = 9
10 % 12 = 10
11 % 12 = 11
لكن لو أردنا أن نحصل على الناتج بين 1
و 12
ماذا نفعل ؟
قد تقول لي بسيطة نقوم بإضافة 1
إلى الناتج النهائي وهكذا سيكون الناتج بين 1
و 12
حسنًا لنجرب هذا
int hour = 12;
int hour_12 = (hour % 12) + 1; // 1
لقد اضفنا 1
على ناتج 12 % 12
وحصلنا على الناتج 1
وهذا خطأ
لأنك لم تحل المشكلة بشكل صحيح كل ما فعلته هو إضافة 1
على الناتج النهائي وهذا ما يحدث
12 % 12 = 0 --> 0 + 1 = 1
1 % 12 = 1 --> 1 + 1 = 2
2 % 12 = 2 --> 2 + 1 = 3
3 % 12 = 3 --> 3 + 1 = 4
4 % 12 = 4 --> 4 + 1 = 5
5 % 12 = 5 --> 5 + 1 = 6
6 % 12 = 6 --> 6 + 1 = 7
7 % 12 = 7 --> 7 + 1 = 8
8 % 12 = 8 --> 8 + 1 = 9
9 % 12 = 9 --> 9 + 1 = 10
10 % 12 = 10 --> 10 + 1 = 11
11 % 12 = 11 --> 11 + 1 = 12
أنت بالفعل جعلت الناتج بين 1
و 12
لكنك قمت بعمل ازاحة
فالرقم 12
أصبح 1
والرقم 1
أصبح 2
والرقم 2
أصبح 3
وهكذا
ونحن لا نريد هذا نحن نريد أن نحصل على الرقم 12
كما هو بدلًا من أن يصبح 0
بصراحة إضافة 1
إلى الناتج النهائي هو نصف الحل فقط ونحن نحتاج لعمل ازاحة فعًلا
لكن قبل الازاحة تلك لنرى هذه الحيلة
1 % 12 = 1
2 % 12 = 2
2 % 12 = (1 % 12) + 1
هل لاحظت شيئًا ؟
إذا قمت بحساب باقي قسمة 1
على 12
ستجد أن الناتج يكون نفسه باقي قسمة 0
على 12
زائد 1
(الازاحة التي قمنا بها)
لنجرب مثال آخر
6 % 12 = 6
7 % 12 = 7
7 % 12 = (6 % 12) + 1
هنا نستطيع الخروج بمعادلة بسيطة وهي (x - 1) % n + 1
وهذه المعادلة تعطينا الناتج بين 1
و n
بدلًا من أن يكون بين 0
و n - 1
الفكرة فيها أننا طالما 12 % 12
يعطينا 0
و 11 % 12
يعطينا 11
فلما لا نحسب 11 % 12
ونضيف 1
للناتج لنحصل على 12
نأتي بالناتج الذي قبله ونضيف له واحد هكذ نحصل على الناتج النهائي بين 1
و 12
لنجرب هذه المعادلة على الساعات
(x - 1) % n + 1
n = 12
x = 1 ... 12
(1 - 1) % 12 + 1 = 0 + 1 = 1
(2 - 1) % 12 + 1 = 1 + 1 = 2
(3 - 1) % 12 + 1 = 2 + 1 = 3
(4 - 1) % 12 + 1 = 3 + 1 = 4
(5 - 1) % 12 + 1 = 4 + 1 = 5
(6 - 1) % 12 + 1 = 5 + 1 = 6
(7 - 1) % 12 + 1 = 6 + 1 = 7
(8 - 1) % 12 + 1 = 7 + 1 = 8
(9 - 1) % 12 + 1 = 8 + 1 = 9
(10 - 1) % 12 + 1 = 9 + 1 = 10
(11 - 1) % 12 + 1 = 10 + 1 = 11
(12 - 1) % 12 + 1 = 11 + 1 = 12
أنظر الآن كيف أننا حصلنا على الساعات بين 1
و 12
بدلًا من أن تكون بين 0
و 11
لنجرب هذه المعادلة ككود برمجي
int hour = 12;
int hour_12 = ((hour - 1) % 12) + 1; // 12
hour = 6;
hour_12 = ((hour - 1) % 12) + 1; // 6
hour = 1;
hour_12 = ((hour - 1) % 12) + 1; // 1
هنا وصلنا لهدفنا وهو الحصول على الساعة بين 1
و 12
بدلًا من أن تكون بين 0
و 11
عن طريق معادلة بسيطة وهي (x - 1) % n + 1
حيث x
أكبر من
اختصارات العمليات الحسابية
سنشرح الآن بعض الاختصارات التي تقدمها لغات البرمجة لتسهيل عليك كتابة بعض الحسابات
مثل ++
و --
و +=
و -=
و *=
و /=
في معظم لغات البرمجة، عندما نريد جمع متغيرات أو أرقام، نستخدم علامة +
int x = 5;
x = x + 1;
// x = 6
في هذا المثال، نحن فقط نضيف الرقم 1
للمتغير x
لكن لتبسيط الأمور وتوفير الوقت، قدمت معظم لغات البرمجة طرقًا مختصرة للقيام بنفس العملية
استخدام علامة +=
علامة +=
تعني جمع القيمة التي في يمين العلامة =
مع المتغير الذي في اليسار، والناتج يخزن في المتغير
int x = 5;
x += 1;
// x = 6
السطر x += 1
هو اختصار لـ x = x + 1
، وهذا يساعد في تقليل تكرار كتابة المتغير
يمكنك أيضًا إضافة أي رقم تريده باستخدام هذه العلامة:
int x = 5;
x += 10;
x += 20;
// x = 35
استخدام علامة ++
نظرًا لأن إضافة الرقم 1
شيء شائع جدًا في البرمجة، قدمت معظم اللغات طريقة مختصرة لزيادة المتغير بقيمة 1
باستخدام ++
int x = 5;
x++;
// x = 6
السطر x++
هو اختصار لـ x = x + 1
أو x += 1
يمكنك استخدام ++
قبل أو بعد المتغير:
int x = 5;
x++;
++x;
// x = 7
في هذه الحالة، لا يوجد فرق بين x++
و ++x
نحن فقط نجمع الرقم 1
على المتغير x
، ولكن في حالات أخرى، يكون الفرق كبيرًا
الفرق بين x++
و ++x
الفرق الأساسي بينهما هو:
x++
تقوم بإرجاع قيمةx
أولًا ثم تزيد عليه1
++x
تزيد1
على المتغيرx
ثم تقوم بإرجاع القيمة الجديدة
يمكن رؤية الفرق في الأمثلة التالية:
int x = 5;
int y = x++;
// x = 6
// y = 5
في السطر الأول، قمنا بتعريف المتغير x
بقيمة 5
في السطر الثاني، قمنا بتعريف المتغير y
وجعلناه يساوي x++
هنا مع x++
أول شيء سيحصل هو أن المتغير y
سيأخذ قيمة x
الحالية لتصبح قيمة y
تساوي 5
ثم يتم زيادة x
بـ 1
لتصبح قيمة x
الجديدة تساوي 6
هكذا تكون قيمة y
تساوي 5
وقيمة x
تساوي 6
أما مع ++x
فالأمر يكون مختلفًا
int x = 5;
int y = ++x;
// x = 6
// y = 6
هنا مع ++x
أولاً ستزيد قيمة المتغير x
بـ 1
لتصبح قيمة x
الجديدة تساوي 6
ثم يتم اسناد القيمة الجديدة لـ x
إلى المتغير y
لتصبح قيمة y
تساوي 6
هذا هو الفرق الأساسي بين x++
و ++x
فمع x++
يتم إرجاع القيمة القديمة ثم زيادة 1
، أما في ++x
يتم زيادة 1
ثم إرجاع القيمة الجديدة
علامات أخرى مشابهة لـ +=
و ++
معظم اللغات لا تقتصر على +=
و ++
فقط، بل تقدم مجموعة من الرموز الأخرى لتسهيل العمليات الشائعة مثل الطرح والقسمة والضرب:
-=
تعني طرح القيمة التي في يمين العلامة=
من المتغير في اليسار والناتج يخزن في المتغير*=
تعني ضرب القيمة التي في يمين العلامة=
بالمتغير في اليسار والناتج يخزن في المتغير/=
تعني قسمة القيمة التي في يمين العلامة=
على المتغير في اليسار والناتج يخزن في المتغير%=
تعني باقي قسمة القيمة التي في يمين العلامة=
على المتغير في اليسار والناتج يخزن في المتغير--
تعني طرح1
من المتغير- ... إلخ
والكثير من العلامات الأخرى التي تقدمها لغات البرمجة لتسهيل العمليات الحسابية
كل ما عليك فعله هو تعلم اللغة التي تدرسها والتعرف على الرموز والمميزات التي تقدمها تلك اللغة لك
ترتيب أولية العملية
في البرمجة هناك ترتيب أولية للعمليات الحسابية
بمعنى عندما تجد معادلة مثل 5 + 3 * 2
أي العملية التي يجب أن تحسب أولًا ؟ الجمع أم الضرب ؟
الجواب هو الضرب يتم حسابه أولًا ثم الجمع
وهذا يحدث لأن الضرب لديه أولوية أعلى من الجمع
وهناك ترتيب أولية للعمليات الحسابية وهي كالتالي:
- القوسين
()
- علامة الجمع والطرح
++
و--
- الضرب
*
و القسمة/
و باقي القسمة%
- الجمع والطرح
+
و-
إذا قابلت عمليات بنفس الأولية مثل *
و %
في نفس السطر تقوم بالحساب من اليسار إلى اليمين
int result = 5 + 3 * 2; // 11
هنا قمنا بحساب الضرب أولًا 3 * 2
وحصلنا على الناتج 6
ثم قمنا بالجمع 5 + 6
وحصلنا على الناتج 11
int result = 5 * 3 % 2; // 1
لدينا هنا عمليتين الضرب وباقي القسمة بنفس الأولية لذا نحسب من اليسار إلى اليمين
لذا نحسب الضرب أولًا 5 * 3
الناتج 15
ثم نحسب باقي القسمة 15 % 2
والناتج 1
int result = 5 * (3 + 2); // 25
هنا الأولية هي حساب العمليات التي بداخل الأقواس أولًا 3 + 2
الناتج 5
ثم نقوم بالضرب 5 * 5
والناتج 25
int x = 5;
int result = ++x * 3 + 2; // 20
هنا الأولية هي حساب العمليات التي تحتوي على ++
و --
أولًا ++x
ستكون 6
ثم نقوم بالضرب 6 * 3
الناتج 18
ثم نقوم بالجمع 18 + 2
الناتج 20
العمليات الحسابية على القيم المنطقية
تعرفنا في مقالات سابقة على نوع البيانات المهتم بالقيم المنطقية التي تسمى boolean
وهي القيم التي تأخذ قيمتين فقط true
و false
وهناك العديد من العمليات التي يمكننا القيام بها على هذه القيم المنطقية
مثل عمليات المقارنة التي تستخدم <
و >
و ==
و !=
و <=
و >=
وغيرها
وعمليات البوابات المنطقية مثل AND
و OR
و NOT
وغيرها
وسنتعرف عليها بالتفصيل الآن
عمليات المقارنة
هذه العمليات تقوم بمقارنة قيمتين معًا وتعطيك قيمة boolean
أي true
أو false
وهذه العمليات تستخدم بشكل أساسي في البرمجة في عمل بعض الشروط والقيود والمقارنات مثل:
- إذا كان الشخص يملك مبلغ أكبر من
1000
جنيه فيمكنه شراء المنتج - إذا كان الشخص وصل للحد من محاولات تسجيل الدخول الفاشلة يتم حظره
- إذا كان الشخص يملك صلاحيات معينة فيمكنك تنفيذ الأمر المعين
- ... وغيرها
كل تلك الأمور يمكنك القيام بها بسهولة عن طريق عمليات المقارنة مع الـ boolean
وهناك العديد من عمليات المقارنة ومنها <
و >
و ==
و !=
و <=
و >=
وغيرها
وسنتعرف عنها بالتفصيل تاليًا
أكبر من >
وأصغر من <
لغات البرمجة تساعدك في عمل مقارنة بين قيمتين لمعرفة هل أي الرقمين أكبر من الآخر أو أصغر من الآخر فهنا تأتي دور عمليتين الأكبر من >
والأصغر من <
int ahmed_age = 24;
int kamal_age = 18;
bool isAhmedOlderThanKamal = ahmed_age > kamal_age; // true
bool isKamalOlderThanAhmed = kamal_age < ahmed_age; // true
هنا لدينا قيم تمثل أعمار شخصين أحدهم يدعى أحمد
والآخر يدعى كمال
خزناهم في متغيرين ahmed_age
و kamal_age
ونريد أن نعرف هل أحمد أكبر من كمال أم العكس
لذا قمنا بعملية المقارنة بين العمرين ahmed_age > kamal_age
وحصلنا على الناتج true
لأن أحمد أكبر من كمال
وفي السطر الثاني قمنا بعملية المقارنة بين العمرين kamal_age < ahmed_age
وحصلنا على الناتج true
لأن كمال أصغر من أحمد
إذا قمنا بعكس العلامة بالطبع ستحصل على قيم false
bool isAhmedOlderThanKamal = ahmed_age < kamal_age; // false
bool isKamalOlderThanAhmed = kamal_age > ahmed_age; // false
هنا قمنا بعكس العلامة في السطر الأول وحصلنا على الناتج false
لأن أحمد ليس أصغر من كمال
وفي السطر الثاني قمنا بعكس العلامة وحصلنا على الناتج false
لأن كمال ليس أكبر من أحمد
ولاحظ أن ناتج عملية المقارنة هي قيمة boolean
إما true
أو false
لذا وضعنا الناتج في متغيرات من نوع boolean
مثل isAhmedOlderThanKamal
و isKamalOlderThanAhmed
أيضًا معظم اللغات تسمح لك بالقيام بالمقارنة بين نصوص من نوع string
أو char
ذكرنا أن كل حرف أو رمز يقابله رقم في جدول الـ ASCII
فالحرف A
يقابله الرقم 65
والحرف a
يقابله الرقم 97
وهكذا
لذا عندما نقارن بين الحروف تقوم لغات البرمجة بمقارنة الأرقام التي تقابلها في جدول الـ ASCII
char first_char = 'A';
char second_char = 'B';
char third_char = 'C';
bool isALessThanB = first_char < second_char; // true
bool isCLessThanA = third_char < first_char; // false
هنا قمنا بعملية المقارنة بين الحروف A
و B
وقلنا هل A
أصغر من B
وكانت النتيجة true
لأن في جدول الـ ASCII
الحرف A
قيمته 65
والحرف B
قيمته 66
وبالتالي A
أقل من B
وفي السطر الثاني قمنا بعملية المقارنة بين الحروف C
و A
وقلنا هل C
أصغر من A
وكانت النتيجة false
لأن قيمة C
في جدول الـ ASCII
هي 67
وقيمة A
هي 65
وبالتالي C
أكبر من A
فيأتي بعده
int one = 1;
char zero = '0';
bool isOneGreaterThanZero = one > zero; // false
هنا سؤال مخادع قليلًا هل الرقم 1
أكبر من الحرف '0'
؟
الجواب هو false
لأن الحرف '0'
في جدول الـ ASCII
يقابله الرقم 48
بتالي عندما نقول 1 > '0'
فهذا يترجم إلى 1 > 48
بالتالي الناتج false
لأن 1
أصغر من 48
نفس الشيء مع الـ string
string name_1 = "Ahmed";
string name_2 = "Kamal";
bool isAhmedGreaterThanKamal = name_1 > name_2; // false
هنا قمنا بعملية المقارنة بين Ahmed
و Kamal
وقلنا هل Ahmed
أكبر من Kamal
وكانت النتيجة false
كيف يتم ذلك ؟
هنا اللغة تقارن حرف حرف من اليسار إلى اليمين وتقارن الحروف بحسب قيمها في جدول الـ ASCII
عندما بدأت المقارنة بين الحرف الأول من كل اسم A
و K
وجدت أن A
أصغر من K
وبالتالي توقفت المقارنة وأعطتني النتيجة false
string text_1 = "abcab";
string text_2 = "ababababababab";
bool isText1GreaterThanText2 = text_1 > text_2; // true
هنا قمنا بعملية المقارنة بين abcab
و ababababababab
وقلنا هل abcab
أكبر من ababababababab
وكانت النتيجة true
كيف يتم ذلك ؟ برغم أن abcab
أقل من ababababababab
من حيث الطول
هذا بسبب أن اللغة كما قلنا تقارن تقارن حرف حرف
فبدأت المقارنة بين الحرف الأول من كل نص a
و a
وجدت أنهما متساويين
ثم انتقلت إلى الحرف الثاني من كل نص b
و b
وجدت أنهما متساويين
ثم عندما وصلت إلى الحرف الثالث من كل نص c
و a
وجدت أن c
في النص الأول أكبر من a
وبالتالي توقفت المقارنة وأعطتني النتيجة true
دون أن تكمل
أكبر من أو يساوي >=
وأصغر من أو يساوي <=
لا داعي لأن اشرح شيء هنا لا توجد فكرة جديدة هنا
كل شيء قلناه عن <
و >
ينطبق هنا أيضًا مع زيادة أنه يأخذ في الاعتبار القيم المتساوية
فقط تذكر أنها تكتب هكذا >=
و <=
بدون مسافة
ولا تكتبها هكذا =>
و =<
بل هكذا >=
و <=
int x = 5;
bool isXLessThanOrEqual5 = x <= 5; // true
bool isXGreaterThanOrEqual5 = x >= 5; // true
// ❌ في حالة عكست ترتيب العلمتين ستحصل على خطأ
bool wrongOrder_1 = x => 5; // Syntax Error
bool wrongOrder_2 = x =< 5; // Syntax Error
فيجب أن تتذكر فقط الترتيب الصحيح للعلامات
ويمكنك تذكر ترتيب هذه العلامات بنفس ترتيب نطق كلماتها في الجملة
مثلاً >=
نحن نقول أكبر من أو يساوي هكذا ستكتب العلامة >
ثم =
من اليسار لليمين
وهكذا مع <=
نقول أصغر من أو يساوي ولا أظن أن هناك أحدًا يقول يساوي أو أصغر من ... أليس كذلك ؟ .. أرجوا
لماذا قد أكون بالغت في شرح هذه التفصيلة ؟ لأنني كنت دائمًا أخطئ في كتابة هذه العلامات وأنا أتعلم البرمجة لكن بعد ما شركتها لنفسي بهذا الشكل لم أخطئ في كتابتها مرة أخرى
المساواة ==
و ===
هذه العملية تقوم بمقارنة قيمتين معًا وتعطيك true
إذا كانت القيمتين متساويتين وتعطيك false
إذا كانت القيمتين غير متساويتين
bool equal_1 = 5 == 5; // true
bool equal_2 = 5 == 6; // false
هنا قمنا بمقارنة العددين 5
و 5
وحصلنا على الناتج true
لأن العددين متساويين
وفي السطر الثاني قمنا بمقارنة العددين 5
و 6
وحصلنا على الناتج false
لأن العددين غير متساويين
عليك أن تفرق بين =
و ==
فالأولى تستخدم لتعيين قيمة لمتغير والثانية تستخدم للمقارنة بين قيمتين
int x = 5; // تعيين قيمة
bool equal = x == 5; // مقارنة قيمة
لاحظ أن =
نستخدم لاسناد أو تعيين قيمة لمتغير مثل ما فعلنا في السطر الأول x = 5
هكذا المتغير x
قيمته أصبحت تساوي 5
و ==
نستخدم للمقارنة بين قيمتين مثل ما فعلنا في السطر الثاني x == 5
وهذا يعني هل قيمة x
تساوي 5
؟ والناتج يكون true
أو false
bool equal = x == 5;
لاحظ أنه يقوم بعمل المقارنة x == 5
أولًا ثم الناتج يتم اسناده وتعينه في المتغير equal
سؤال هل 0
تساوي '0'
؟
bool equal = 0 == '0';
في معظم لغات البرمجة الناتج هنا false
لأن العدد 0
لا يساوي الحرف '0'
الذي يقابله الرقم 48
في جدول الـ ASCII
لكن في هناك لغات مثل JavaScript
تعتبر الناتج هنا true
لأنها لا تهتم بنوع القيمة وتقوم بتحويل القيمة تلقائيًا لتوحيدهما وتقارنهما
بمعنى أن في لغة JavaScript
ناتج 0 == '0'
يكون true
لغة JavaScript
قدمت لنا ===
للمقارنة بين القيمتين ومراعاة نوع القيمة أي أنها تقوم بالمقارنة بين القيمتين ونوعهما
let equal_1 = 0 == '0'; // true
let equal_2 = 0 === '0'; // false
هنا في السطر الأول قمنا بمقارنة العدد 0
والحرف '0'
باستخدام ==
وحصلنا على true
لأن JavaScript
هنا قارنت بغض النظر عن نوع القيمة لأننا استخدمنا ==
وفي السطر الثاني قمنا بمقارنة العدد 0
والحرف '0'
باستخدام ===
وحصلنا على false
لأن JavaScript
هنا قارنت القيم وراعت نوع القيمة لأننا استخدمنا ===
ستجد أن اللغات قد تعامل الأمور بشكل مختلف في هذا الجانب فبعضها تهتم بنوع القيمة وبعضها لا تهتم بنوع القيمة
لذا ادرس اللغة التي تتعلمها وافهم كيف تتعامل مع القيم والمقارنات بين انواع البيانات المختلفة
عدم المساواة !=
لا أظن أن هناك شيء جديد هنا يجب شرحه
لأنه ببساطة العلامة !=
هي العكس تمامًا من ==
تقوم بمقارنة قيمتين معًا وتعطيك true
إذا كانت القيمتين غير متساويتين وتعطيك false
إذا كانت القيمتين متساويتين
bool notEqual_1 = 5 != 5; // false
bool notEqual_2 = 5 != 6; // true
هنا قمنا بمقارنة العددين 5
و 5
وحصلنا على الناتج false
لأن العددين متساويين
وفي السطر الثاني قمنا بمقارنة العددين 5
و 6
وحصلنا على الناتج true
لأن العددين غير متساويين
هذه هي عمليات المقارنة الأساسية الشائعة التي ستجدها في معظم اللغات
لكن هذا لا يمنع أنك قد تجد لغات تستخدم رموز وانواع وطرق مختلفة وجديدة للمقارنة بين القيم
مثل في Python
تجد أنها تستخدم is
و is not
عمليات البوابات المنطقية
هل تتذكر البوابات المنطقية في الفيزياء الحديثة ؟
البوابات المنطقية هي مجموعة العملية التي كانت في التحكم بمسار الكهرباء في الدوائر الكهربية
أما في البرمجة فنستخدمها مع القيم المنطقية الـ boolean
لعمل بعض الشروط والتحقق من القيود
نحن كنا نعرف المتغير من نوع boolean
ونضع له شرط واحد فقط
int age = 24;
bool isYoung = age < 30; // true
ماذا إذا أردنا أن نضع أكثر من شرط ؟
مثل إذا كان الشخص طالب جامعي ويردي نظارات وذكي هنا نستخدم البوابات المنطقية للتحقق من أكثر من شرط
هناك العديد من البوابات المنطقية الأساسية لكن سنكتفي بالأساسية الأربعة وهي AND
و OR
و NOT
و XOR
AND
: تستخدم للتحقق من صحة شرطين معًا وتعطيكtrue
إذا كان الشرطين صحيحين وتعطيكfalse
إذا كان أحدهما خطأOR
: تستخدم للتحقق من صحة شرطين معًا وتعطيكtrue
إذا كان أحد الشرطين صحيح وتعطيكfalse
إذا كان الشرطين خطأNOT
: تستخدم لعكس الشرط وتعطيكtrue
إذا كان الشرط خطأ وتعطيكfalse
إذا كان الشرط صحيحXOR
: تعطيكtrue
إذا كان صحة الشرطين متعاكسين وتعطيكfalse
إذا كان الشرطين متساويين
يمكننا بناء جدول يوضح لنا القيم المتوقعة لكل بوابة منطقية
الشرط الأول (A) | الشرط الأول (B) | A AND B | A OR B | NOT A | NOT B | A XOR B |
---|---|---|---|---|---|---|
true | true | true | true | false | false | false |
true | false | false | true | false | true | true |
false | true | false | true | true | false | true |
false | false | false | false | true | true | false |
لاحظ بعض النقاط المهمة هنا:
AND
تعطيكtrue
فقط عندما يكون كلا الشرطين معًا يعطيانtrue
وإلا تعطيكfalse
إذا كان أحدهما يعطيكfalse
OR
تعطيكtrue
عندما يكون على الأقل أحد الشرطين يعطيكtrue
وتعطيكfalse
فقط عندما يكون كلا الشرطين يعطيانكfalse
NOT
مجرد أنها تعكس نتيجة الشرط فإذا كان الشرطtrue
تعطيكfalse
وإذا كان الشرطfalse
تعطيكtrue
XOR
تعطيكtrue
فقط عندما يكون الشرطين متعاكسين أي أحدهماtrue
والآخرfalse
وتعطيكfalse
عندما يكون الشرطين متساويين بمعنى أن كلاهماtrue
أو كلاهماfalse
عملية الـ AND
الشرط الأول (A) | الشرط الأول (B) | A AND B |
---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
هذه العملية تستخدم للتحقق من صحة كلا شرطين معًا وتعطيك true
إذا كان كلا الشرطين صحيحين وتعطيك false
إذا كان أحدهما خطأ
تخيل أن معك مصباح له زرين لا يضيء إلا عندما تضغط على زرين معًا وإذا ضغطت على زر واحد فقط لن يعمل المصباح
ورمزها في لغات البرمجة هو &&
بعض اللغات قد تستخدم and
int age = 24;
bool isStudent = true;
bool isYoungAndStudent = age < 30 && isStudent; // true
لاحظ أننا هنا قمنا بعملية AND
بين شرطين age < 30
و isStudent
وحصلنا على الناتج true
لأن age < 30
تعطينا true
و isStudent
قيمتها true
إذا true && true
تعطينا true
ولاحظ أننا فصلنا بين الشرطين بعلامة &&
وهذا يعني
int x = 5;
int y = 10;
int z = 11;
bool middle = z > x && z < y; // false
هنا قمنا بعملية AND
بين شرطين z > x
و z < y
وحصلنا على الناتج false
لأن z > x
تعطينا true
و z < y
تعطينا false
إذا true && false
تعطينا false
هل يمكننا استخدام AND
مع أكثر من شرطين ؟
نعم نحن كنا نستخدم شرطين لتبسيط الأمور ولكن يمكنك استخدام AND
مع أكثر من شرطين
string name = "Ahmed";
int age = 24;
bool isStudent = true;
bool isSmartMan = name == "Ahmed" && age >= 24 && isStudent; // true
هنا قمنا بعملية AND
بين ثلاث شروط name == "Ahmed"
و age >= 24
و isStudent
وحصلنا على الناتج true
لأن كل الشروط صحيحة
إذا كان هناك شرط واحد فقط خطأ فإن الناتج بأكمله سيكون false
string name = "Ahmed";
int age = 24;
bool isStudent = false;
bool isSmartMan = name == "Ahmed" && age >= 24 && isStudent; // false
هنا بسبب أن isStudent
قيمتها false
فإن الناتج بأكمله سيكون false
حتى ولو كان الشرطين الآخرين صحيحين لأننا نستخدم AND
وهذا يعني أن كل الشروط يجب أن تكون صحيحة لتعطينا true
عملية الـ OR
الشرط الأول (A) | الشرط الأول (B) | A OR B |
---|---|---|
true | true | true |
true | false | true |
false | true | true |
false | false | false |
تستخدم هذه العملية للتحقق من صحة أحد الشرطين أو كليهما وتعطيك true
إذا كان على الأقل أحد الشرطين على الأقل صحيحًا وتعطيك false
فقط عندما يكون كلا الشرطين خاطئين
تخيل تملك مصباح له زرين ويضيء عندما تضغط على أي زر
رمزها في لغات البرمجة ||
وبعض اللغات البرمجة تستخدم or
int age = 12;
bool isSuperSmartKid = true;
bool canEnterCollege = age >= 24 || isSuperSmartKid; // true
لاحظ هنا أن الشرط الأول age >= 24
أعطى false
لكن بسبب أن isSuperSmartKid
قيمته true
فإنا الناتج الكلي سيصبح true
لأن الـ OR
تشترط أن يكون شرط واحد فقط يغطي true
لتعطيك true
والحالة الوحيدة التي تعطيك false
هي عندما يكون كلا الشرطين خاطئين
int age = 12;
bool isSuperSmartKid = false;
bool canEnterCollege = age >= 24 || isSuperSmartKid; // false
هنا بسبب أن كلا الشرطين age >= 24
و isSuperSmartKid
قيمتهما false
فإن الناتج الكلي سيكون false
عملية الـ NOT
الشرط (A) | NOT A |
---|---|
true | false |
true | false |
false | true |
false | true |
تستخدم هذه العملية لعكس ناتج الشرط فإن كان الشرط يعطيك true
فقيمته بعد الـ NOT
سيكون false
رمزها في لغات البرمجة هو !
وبعض اللغات البرمجة تستخدم not
int age = 30;
bool isAdult = !(age > 24);
ما هو الناتج هنا برأيك ؟
الشرط age > 24
سيعطينا true
لأن age
أكبر من 24
ولكن بسبب أننا استخدمنا !
فإن الناتج سيكون false
المعادلة كانت !(age > 24)
ثم اصبحت هكذا !(true)
بالتالي الناتج النهائي سيكون false
لأن الـ NOT
تعكس النتيجة فإذا كان الشرط يعطيك true
فإن الـ NOT
سيعطيك false
والعكس صحيح
عملية الـ XOR
الشرط الأول (A) | الشرط الأول (B) | A XOR B |
---|---|---|
true | true | false |
true | false | true |
false | true | true |
false | false | false |
يمكنك أن تقول أنها تحب الاختلاف وتكره المساواة والتشابه
بمعنى أنها تعطيك true
فقط عندما يكون الشرطين مختلفين وتعطيك false
عندما يكون الشرطين متساويي ومتشابهين
ورمزها في لغات البرمجة ^
bool xorExample_1 = true ^ true; // false
bool xorExample_2 = false ^ false; // false
bool xorExample_3 = true ^ false; // true
bool xorExample_4 = false ^ true; // true
لاحظ أنها تعطيك false
عندما يكون الشرطين متساويين وتعطيك true
عندما يكون الشرطين مختلفين
الـ XOR
تفيدنا في التحقق من الاختلاف خصوصًا التحقق من شيئين يناقضا بعضهما
بحيث ان كان هناك تشابه بين النقيضين فإن الناتج يكون false
وإذا كان هناك اختلاف بينهما فإن الناتج يكون true
bool isTall = true;
bool isShort = true;
bool isLogical = isTall ^ isShort; // false
هنا لدينا متغير يمثل هل الشخص طويل isTall
ومتغير يمثل هل الشخص قصير isShort
وكلا المتغيرين ينقضان بعضهما، لا أظن أن هناك شخص سيكون طويل وقصير في نفس الوقت
ولدينا متغير يدعى isLogical
يمثل هل الحالة منطقية أم لا
بحيث أنه يعتبر أن الحالة غير منطقية إذا كان الشخص طويل وقصير في نفس الوقت أو العكس ليس بطول ولا قصير
هنا قمنا بعملية XOR
بين شرطين isTall
و isShort
وحصلنا على الناتج false
لأن الشرطين متساويين
كأنها وسيلة للتحقق بين نقيضين مثل isTall
و isShort
ولا يمكنهما أن يكونا متساويين
بدون استخدام XOR
كيف كنا سنحسب الشرط السابق في isLogical
؟
bool isLogical = (isTall && !isShort) || (!isTall && isShort)
هل ترى تلك العملية الطويلة ؟ هذه العملية من أجل التحقق من:
- هل الشخص طويل وليس بقصير
isTall && !isShort
- هل الشخص قصير وليس بطويل
isTall && !isShort
ثم نجمعهما في ||
لنرى هل هناك تناقض أم لا ليكون شكل المعادلة النهائية هكذا (isTall && !isShort) || (!isTall && isShort)
الـ XOR
تسهل وتختصر علينا هذه العملية وتجعلها أقصر وأسهل isTall ^ isShort
هذه المعادلة هي ترجمة للـ XOR
باستخدام AND
و OR
و NOT
فقط
ولكن في حقيقة هناك شكل آخر لترجمة الـ XOR
باستخدام !=
وهو كالتالي isTall != isShort
bool isLogical = isTall != isShort;
لكن هذا فقط حين نتعامل مع القيم المنطقية true
و false
ولكن في حالة الأرقام فيجب عليك استخدام الـ XOR
مباشرة والرمز ^
الخاص بها
ستفهم ما اقصد عندما تقرأ الفضفضة التالية
عمليات البوابات المنطقية على الأرقام الثنائية
ملحوظة
: هذا الجزء ليس ضروريًا لفهم الأمور الأساسية في البرمجة ويمكنك تخطيه لذا سأفصله في مقالة أو فضفضة قصيرة بعيدًا عن المقالات الأساسية
يمكنك قراءة الفضفضة من هنا عمليات البوابات المنطقية على الأرقام الثنائية