سؤال

أدرك أنك تستطيع فقط #define بعض الأعداد الصحيحة، ولكن لماذا لم يكن لديك نوع بيانات منطقية مخصصة قبل C99؟

إنه حدوث شائع في البرمجة والمنطق، وأنا لا أفهم الغياج بنوع واضحة وتدوين.

هل كانت مفيدة؟

المحلول

إذا كنت تقضي بعض الوقت في المكتبة، فلن تضطر إلى التكهن. فيما يلي بعض البيانات التي اتخذت من ورقة دينيس ريتشي على تطور ج. وبعد السياق هو أن دينيس يبني بلغة كين طومسون ب، والتي تم تنفيذها على PDP-7 الصغير جدا، آلة موجهة إلى الكلمة. بسبب الاهتمام المتزايد، حصلت المجموعة على واحدة من أول برنامج PDP-11s. دينيس يكتب،

تعرض ظهور PDP-11 العديد من أوجه القصور النموذج الدلالي B. أولا، كانت آليات معالجة الشخصية، التي ورثت بها تغييرات قليلة من BCPL، خرقاء: استخدام إجراءات المكتبة لنشر سلاسل معبأة في الخلايا الفردية، ثم أعد تشكيل الأحرف الفردية، أو للوصول إليها، بدأت تشعر بالحرج، حتى سخيفة، على آلة الموجهة نحو البايت.

ضمن نموذج B و BCPL النفقات العامة في التعامل مع المؤشرات: قواعد اللغة، من خلال تحديد مؤشر كفهرس في صفيف من الكلمات، يتم تمثيل المؤشرات القسرية كمؤشرات كلمة. ولدت كل مرجع مؤشر تحويل مقياس وقت التشغيل من المؤشر إلى عنوان البايت المتوقع بواسطة الأجهزة.

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

(التركيز لي.)

تستمر الورقة في وصف نضالات دينيس لإنهاء دلالات مؤشر جديدة، لجعل مجموعة صفائف، والحصول على شروط مع هذا Newfangled struct فكرة. لم تبدو مفاهيم السلامة والتمييز المميز من أعداد صحيحة مهمة حتى وقت لاحق :-)

نصائح أخرى

C هو في الواقع أكثر من مجرد لغة تجميع المستوى الأعلى. نعم، حصلت على هياكل السيطرة و Whatnot، وحتى حصلت على أنواع المجمع لا يحتاج بالتأكيد.

لكن اللغة تم تصميمها منذ عقود. وبما أن كل نتيجة منطقية تنزل إلى بتات فردية في كلمة حالة المعالج، فمن الواضح أنها كانت كافية فقط لاستخدام نوع بيانات متكاملة لذلك. وجعلت المحول البرمجي ربما معقد أقل قليلا حيث يمكنك حذف بعض الفحص من النوع (في هياكل التحكم اللغات اللغات يحتاج قيمة منطقية، في ج أنها بحاجة فقط إلى قيمة جزء لا يتجزأ من أي شيء آخر).

كان من الشائع (وما زال في بعض الحالات) لعلاج الصفر كخطأ وأي غير صفرية حقيقية. هذا لديه مزايا للاختصار: على سبيل المثال، بدلا من while (remaining != 0) يمكنك فقط استخدام while (remaining).

بعض اللغات موحدة على كونك حقيقي -1. السبب في ذلك هو أنه في تدوين تكامل TWOS (الذي تستخدم معظم أجهزة الكمبيوتر لتمثيل أرقام سلبية)، فإن bitwise-not of 0 هو -1 (في الثنائي 8 بت، 11111111 هو عشري -1).

بمرور الوقت، أدركت أن استخدام ثابت محدد بالمترجم سيمنع الكثير من الارتباك المحتمل. لقد مر بعض الوقت منذ أن قمت بإجراء C ++، لكنني متأكد من أن أي قيمة غير صفرية ستظل تقيم "صحيح".

وحدة المعالجة المركزية لا يوجد لدى وحدة المعالجة المركزية "نوع منطقي"، فهي تعمل فقط على البايتات ومضاعفاتها حتى لا معنى للنوع المنطقي في ذلك الوقت لأنه لم يمنح ميزة (لماذا استخدام نوع عندما يمكنك التحقق فقط "هو 0" أو "ليست فارغة")

أظن أنه يعتبر كافيا أن يكون لديك نوع عدد صحيح، مع 0 كاذبة وأي شيء ليس 0 صحيح.

النوع الذي تستخدمه لتخزين شركة منطقية (عادة) يجسد مقايضة بين الفضاء والوقت. عادة ما تحصل على أسرع النتائج (على الأقل لعملية فردية) باستخدام Int (عادة أربعة بايت). من ناحية أخرى، إذا كنت تستخدم الكثير جدا، فيمكن أن يكون هناك شعور بكثير لاستخدام بايت واحد أو حتى قم بتعبئةها حتى تتمكن كل قيمة تقوم بتخزينها فقط - ولكن عند / إذا قمت بذلك، قراءة أو كتابة بت واحد يصبح أكثر تكلفة بشكل كبير (ويستخدم رمز إضافي).

نظرا لعدم وجود إجابة واحدة كانت "حق"، فقد تركوا القرار للمستخدم لإجراء استنادا إلى متطلبات البرنامج الذي كتبوه.

السؤال الحقيقي، إذن، هو السبب في أنه تمت إضافة نوع منطقية في C99. تخميني هو أن اثنين من العوامل تشارك. أولا، أدركت أن قابلية القراءة والراحة للمبرمج أصبح الآن أكثر أهمية من إعطاء أفضل أداء مطلق ممكن. ثانيا، التحويل البرمجيات الآن تحليل عالمي أكثر قليلا، لذلك من الممكن على الأقل تخمين أن شخصا ما ربما اكتب مترجم يحاول اختيار تمثيل مناسب لبرنامج معين (على الرغم من أنني لا أعرف أي ذلك يفعل حقا).

لم يكن قديم C لم يكن "مفقودا" نوع منطقية - كان مجرد أن جميع الأنواع المتكاملة كانت تعتبر أيضا مناسبة للقيام بواجب مضاعفة، تخزين المنطمنون. أستطيع أن أرى سببين رئيسيين لهذا:

  • لم تكن معالجات معالجة بت غير شائعة (وما زلت ليست كذلك)، وبالتالي فإن المترجم لن يكون قادرا حقا على استخدام نوع "منطقي حقيقي" لإنقاذ أي مساحة - ستظل المنطقية على الأقل أ char على أي حال (إذا كنت تأمل في الوصول إليها بكفاءة).

  • أنواع أضيق من ذلك int يتم توسيعها إلى int في التعبيرات على أي حال - وبالتالي فإن المشغلين المنطقيين سيظلون يعملون int المعاملات.

..So أنها تبدو وكأنها لم تكن هناك حالة مقنعة بما فيه الكفاية لن ينقل نوع منطقية مخصصة في الواقع فوائد عملية.

تذكر أن لغة C لديها مجموعة من المشغلين الذين ينتجون نتائج منطقية (المعرفة ليكون إما 0 أو 1) - !, &&, ||, !=, ==, <, <=, > و >= - لذلك فقط نوع منطقية مخصص ليس هناك.

أسباب تاريخية، ربما:

CPL، الذي تأثر بشدة بالغول، على الأرجح لديه نوع منطقية منطقية، لكن بلدي google-fu لم يكفي لإيجاد مرجع لهذا. لكن CPL كان طموحا للغاية لوقته، مما يؤدي إلى إصدار تجريبي يسمى BCPL، الذي كان له الفائدة التي يمكنك تنفيذها بالفعل على الأجهزة المتاحة.

كان لدى BCPL فقط نوع واحد - "الكلمة" - والتي تم تفسيرها على أنها خاطئة في سياقات منطقية إذا 0 و صحيح إذا ~0 (وهذا يعني استكمال 0, ، والتي من شأنها أن تمثل القيمة -1 إذا تم تفسيرها على أنها عدد صحيح تكملة TWOS). كان تفسير أي قيمة أخرى يعتمد التنفيذ.

بعد أن لا يزال خليفة عديم الفائدة B، C إعادة إدخال نظام نوع، لكنه لا يزال يتأثر بشدة بالطبيعة الواضحة لساحباتها.

إضافة نوع منفصل "منطقي" غير متوافق مع الأعداد الصحيحة كان من شأنه أن يجعل المترجم أكثر تعقيدا من مجرد استخدام أعداد صحيحة لهذا الغرض. وجود نوع منطقي منفصل متوافق مع الأعداد الصحيحة يجعل من الضروري تحديد النتائج المحتملة لتخزين قيمة بخلاف 0 أو 1 في كائن منطقي، أو أداء حسابات رقمية على كائن منطقي يحتوي تمثيله على نمط بت مرتبط " 0 "ولا" 1 ". منح:

someBool = intFunction();
someInt = someBool;

تتطلب أن يتطلب هذا القيمة أن يحصل على القيمة 1 إذا عخلت أي قيمة غير صفرية، فستصنع عموما أعلى تكلفة أكثر من

someChar = intFunction();
someInt = someChar;

في الحالات التي تكون فيها الدلالات السابقة مطلوبة، يمكن تحقيقها دون استخدام نوع منطقية، عن طريق:

someChar = !!intFunction();
someInt = someChar;

نظرا لأن أي شيء يمكن القيام به باستخدام أنواع منطقية يمكن القيام به من دونها، وفي كثير من الحالات، يمكن أن يكون رمز الحالات الذي يستخدم أنواع الأحرف أكثر كفاءة من أنواع المنطقية، أود أن أقترح أنه لم يكن هناك (وما زال ليس) أي حقيقي تحتاج لهم.

لأنهم لم يضعوا أحدهم. آسف إذا كان ذلك يبدو أن Snippish، ولكن في الأساس لم يتم تعريفه على هذا النحو.

تذكر أن معظم الناس # Define صحيح وكاذب.

قد تقول BOOL قياسي - ولكن من الواضح أنه لم يكن معيارا قبل C99 - التي تم إجراؤها قبل 10 سنوات؛) أضافها بعد ذلك عندما أصبح من الواضح عنصر مفقود.

لأنه لا يمكن أن يتوقع أي شيء بما في ذلك نوع البيانات المفقود في لغة البرمجة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top