ملخص
يفتتح هذا الدرس الوحدة الثالثة من الدورة، المخصّصة للتعابير وعواملها. ويشرح الغاية من الوحدة: أن تعلّم بناء تعابير يمكن التنبّؤ بقيمتها يقينًا، بمعرفة أيّ عملية تُجرى أولًا، ومن أيّ نوع تكون النتيجة، وما آثارها الجانبية، وأيّ التعابير لا معنى لها؛ ويعرض دروسها الأربعة والخيط الذي يجمعها، من حساب الأعداد الصحيحة والحقيقية إلى البتات والمكتبة الرياضية، مرورًا بالشروط وبفهرس السلوك غير المعرَّف؛ ويذكّر بما تفترض الوحدة أنه معلوم من الثانية، وهو نوع كل معطى وحدوده وتحويلاته؛ ويصوغ المسألة التي تحلّها الوحدة، مسألة برنامج يُترجَم دون تحذير واحد وأجوبته عن ستة أسئلة مدرسية كلها خاطئة، إن لم تكن غائبة؛ ويبيّن إلى أين تقود، في الوحدات اللاحقة وفي دورة البرمجة بلغة C++ II.
أهداف التعلم
- وصف تسلسل محتويات الوحدة، وشرح ما يقدّمه كل درس للدرس الذي يليه.
- تذكّر ما يلزم من الوحدة 2 (الأنواع الصحيحة والحقيقية، ومدى قيمها، والفيضان، والتحويلات)، ومراجعته عند الحاجة.
- الاستباق، بمثال، إلى أن قيمة التعبير تتوقّف على قواعد في الحساب (الأسبقية، ونوع المعامَلات، وترتيب الآثار) لا تطابق دائمًا قواعد الرياضيات المدرسية.
- التعرّف على ما يُنتظر إتقانه في نهاية الوحدة، وتمييزه ممّا سيُتعلَّم في الوحدات اللاحقة.
تقييم الدخول
قبل اجتياز الوحدة يحسن قياس نقطة البداية. وهذا التقييم تقييم ذاتي: لا تُمنح عليه درجة، وغايته الوحيدة توجيه الدراسة. وتتناول الأسئلة الأربعة الأولى ما تفترض الوحدة أنه معلوم من الثانية: القسمة بين الأعداد الصحيحة، والكتابة في الأساس 2، والطرح عديم الإشارة، والفيضان ذا الإشارة. وتتناول الأسئلة الستة التي تليها، بترتيب الدروس، الأفكار المحورية في الوحدة، وينطلق عدد منها من الرياضيات المدرسية أو من المنطق الأوّلي. ولا أحد ملزم بالإصابة فيها بعدُ، وفي اثنين منها يكون «لا أعرف بعدُ» جوابًا صادقًا: فكل جواب، صائبًا كان أو خاطئًا، يشرح المسألة ويسمّي الدرس الذي يعالجها. وتُقاس المهارات نفسها مرة أخرى في النهاية، في درس الخلاصة.
قبل أن تبدأ الوحدة، قِس نقطة انطلاقك. إنه تقييم ذاتي قصير: لا يُمنح عليه درجة، وتُحفظ نتيجته في متصفحك فقط.
السؤال 1من وحدات سابقةيصرّح برنامج بـ
const double r{7 / 2};ثم يكتبr. فماذا يظهر؟يظنّ أن نوع المتغير يحدّد طريقة القسمة؛ والذي يحدّدها هو نوع المعامَلات.يظنّ أن القسمة الصحيحة تقرّب؛ وهي في الحقيقة تحذف الجزء العشري.القيمة 3 ثابتة وتُمثَّل تمثيلًا تامًّا فيdouble: فلا تضييق يُرفض.القسمة7 / 2بين عددين صحيحين، فتعطي خارج القسمة الصحيح، 3؛ ولا يتحوّل هذا الـ 3 إلىdoubleإلا بعد ذلك. فنوع المعامَلات هو الذي يحدّد العملية، لا نوع المتغير الذي يتلقّى النتيجة. ويحوّل الدرس 3.1 هذه الملاحظة إلى قاعدة عامة: يتحدّد النوع عند كل عقدة من عقد التعبير.السؤال 2من وحدات سابقةكيف يُكتب العدد 13 في الأساس 2 بثمانية بتات؟
يخطئ في جمع الأوزان: .يكتب بواقي القسمات المتتالية بالترتيب الذي تظهر به؛ وهي تُقرأ من الأخير إلى الأول.هذا النمط هو 26، ضعف 13: فالبتات مزاحة منزلة واحدة.وزن كل منزلة ضعف وزن المنزلة التي على يمينها: والآحاد تشغل المنازل ذات الأوزان 8 و4 و1. ويعمل الدرس 3.4 على هذه البتات مباشرة، ولذا يحسن قراءتها بيُسر.راجِع: الأعداد الصحيحة وتمثيلها
السؤال 3من وحدات سابقةماذا تكتب
std::println("{}", 0u - 1);معunsigned intمن 32 بتًّا؟لا يراعي اللاحقةu: فالنوع عديم الإشارة لا قيم سالبة له.يخلط بين الحساب عديم الإشارة، المعرَّف بترديد ، والفيضان ذي الإشارة.يظنّ أن الطرح يتوقّف عند أصغر قيمة في النوع؛ وهو في الحقيقة يلتفّ دائرًا.الحساب عديم الإشارة حساب بترديد : . والنتيجة معرَّفة، ولذلك لا يشير إليها أيّ كاشف. وتلقاها الوحدة من جديد في تحويلات التعبير المختلط وفي عوامل البتات، التي تُكتب بأنواع عديمة الإشارة.راجِع: الأعداد الصحيحة وتمثيلها
السؤال 4من وحدات سابقةينفّذ برنامج
int count{std::numeric_limits<int>::max()};ثمcount = count + 1;. فماذا يضمن المعيار بشأن قيمةcount؟يخلط بين ما يُلاحَظ أحيانًا وما يضمنه المعيار؛ فالعودة إلى الحدّ الأدنى هي ما تفعله الأنواع عديمة الإشارة، لا ذات الإشارة.يتجاهل حدّ النوع: فهذا العدد لا يتّسع فيintمن 32 بتًّا.لا يعرف المترجم القيم التي ستكون للبرنامج عند تنفيذه؛ وهو يترجم في أغلب الأحيان دون أن يقول شيئًا.للجمع شرط مسبق، هو أن تتّسع النتيجة في النوع، وخارجه لا يعد المعيار بشيء. وكاشف الدورة يوقف البرنامج؛ ومن دونه قد يُكتب أيّ شيء. ويجمع الدرس 3.3 هذه الحالة مع غيرها من نوعها في فهرس.راجِع: الأعداد الصحيحة وتمثيلها
السؤال 5كم تساوي و؟
يُجري العمليات من اليسار إلى اليمين دون مراعاة أسبقية الضرب.يتجاهل أقواس التعبير الثاني.ينسب إلى كل تعبير قيمة الآخر: فيعكس أثر الأقواس.الضرب أشدّ ارتباطًا من الجمع: ففي يُجرى الضرب أولًا، والأقواس تغيّر هذا الترتيب. وتتبع C++ الاصطلاح نفسه، ويوسّعه الدرس 3.1 ليشمل القسمة والباقي والتجميعية، متّخذًا شجرة التعبير أداةً.راجِع: العمليات الحسابية
السؤال 6وفق مبرهنة القسمة في الرياضيات، ومع تقييد الباقي بالشرط ، ما خارج القسمة وما الباقي لقسمة على ؟
هذا ما تحسبه C++، لكنه لا يحقّق : فباقي الرياضيات ليس سالبًا.لا يتحقّق من المتطابقة: ، لا .ولا يحقّق المتطابقة هو أيضًا: .تشترط المبرهنة مع ، وهذان العددان هما الوحيدان اللذان يحقّقان ذلك. أما C++ فتبتر خارج القسمة نحو الصفر:-7 / 2يساوي و-7 % 2يساوي . ويشرح الدرس 3.1 الفرق ويعلّم الحصول على باقي الرياضيات انطلاقًا من باقي C++.راجِع: العمليات الحسابية
السؤال 7ما نفي «السماء تمطر والجو بارد»؟
ينفي كل جزء دون أن يغيّر الرابط: وهذا يقرّر أكثر بكثير من النفي، لأنه يستبعد أيضًا اليوم الجافّ البارد.ينفي جزءًا واحدًا فقط.يقول ما يقوله الخيار الثاني، بالخطأ نفسه.نفي العطف هو الفصل بين النفيين: وهذا أحد قانونَي دي مورغان. ويكفي أن ينتفي أحد الأمرين لتكون العبارة كاذبة. ويطبّق الدرس 3.2 القانون نفسه على شروط البرنامج.راجِع: العلاقات والمنطق
السؤال 8ماذا تكتب
std::println("{}", 3 < 5);؟يظنّ أن القيمة المنطقية تُكتب عددًا؛ ومع العنصر النائب{}تكتبstd::printlnالكلمة.يظنّ أن التعبير يُكتب نصًّا؛ والذي يُكتب هو قيمته.بل هي قيمة: فالمقارنة تعبير من النوعbool.المقارنة تعبير كسائر التعابير: لها قيمة من النوعbool، وتكتبهاstd::printlnعلى صورةtrueأوfalse. وينطلق الدرس 3.2 من هذه الملاحظة: الشرط يُحسب، ولذلك له أسبقية وشجرة وجبر.راجِع: العلاقات والمنطق
السؤال 9بعد
int a{5};وint b{a++ * 2};، كم تساويaوb؟هذا جواب صادق: الدرس 3.3 يعلّم الفرق بين قيمة التعبير وأثره، وتقييم الخروج سيسأل عنه مرة أخرى.ينسى الأثر:a++يزيدa.يستعمل القيمة الجديدة لـa؛ والزيادة اللاحقة تعطي القيمة السابقة.للتعبيرa++قيمة، هي التي كانت لـa(5)، وأثر، يتركaعند 6. والضرب يستعمل القيمة لا الأثر. ويعلّم الدرس 3.3 الفصل بين الأمرين، والتعرّف على الحالات التي يُفقد فيها أثران في تعبير واحد هذا التعبيرَ معناه.السؤال 10ماذا تكتب
std::println("{}", 2 ^ 3);؟هذا جواب صادق: الدرس 3.4 يشرحه، وتقييم الخروج سيسأل عنه مرة أخرى.يقرأ علامة الإقحام قوةً، كما في ترميز كثير من الآلات الحاسبة؛ وهي ليست كذلك في C++.يقرؤها ضربًا.ليست علامة الإقحام في C++ هي القوة، بل هي «أو» الحصرية البتّية: فـ و لا يختلفان إلا في البتّ ذي الوزن 1، فتكون النتيجة 1. وليس في C++ عامل للقوة؛ ويعلّم الدرس 3.4 متى تُستعملstd::powومتى تُستعمل الإزاحة.راجِع: البتات والمكتبة الرياضية
جارٍ تحميل المحتوى…