سؤال

لا ANSI القياسية ولاية عوامل التشغيل المنطقية أن يكون تماس ، سواء C أو C++?

أنا محتار لأني أذكر K&R الكتاب قائلا التعليمات البرمجية الخاصة بك يجب أن لا تعتمد على هذه العمليات التي دارة قصيرة, لأنهم قد لا.يمكن للشخص يرجى حيث أشير في مستوى يقال المنطق العمليات دائما تماس?أنا في الغالب المهتمين على C++, إجابة أيضا ج من شأنها أن تكون كبيرة.

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

هل معيار تشير إلى تقييم النظام من هذا التعبير ؟

if( functionA() && functionB() && functionC() ) cout<<"Hello world";
هل كانت مفيدة؟

المحلول

نعم تفقد أعصابها والتقييم أمر مطلوب مشغلي || و && في كل من C و C++ المعايير.

C++ القياسية يقول (يجب أن يكون هناك ما يعادل شرط في ج القياسي):

1.9.18

في تقييم التعبيرات التالية

a && b
a || b
a ? b : c
a , b

باستخدام المدمج في معنى من المشغلين في هذه التعبيرات ، هناك تسلسل نقطة بعد التقييم الأول التعبير (12).

في C++ هناك إضافية فخ:الدائرة قصيرة لا لا تنطبق على أنواع الزائد المشغلين || و &&.

الحاشية 12:مشغلي المشار إليها في هذه الفقرة هي المدمج في المشغلين ، كما هو موضح في البند 5.عند واحد من هذه العوامل هو فوق طاقتها (بند 13) في صالح السياق ، وبالتالي تعيين المستخدم-تعريف المشغل وظيفة التعبير يعين وظيفة الاحتجاج و المعاملات شكل حجة قائمة ، دون ضمني تسلسل نقطة بينهما.

وعادة لا ينصح الزائد هذه الشركات في C++ إلا إذا كان لديك متطلبات محددة.يمكنك أن تفعل ذلك, ولكن قد كسر المتوقع السلوك في رمز الآخرين ، خاصة إذا هذه الشركات تستخدم بشكل غير مباشر عن طريق إنشاء قوالب مع نوع الحمولة الزائدة هذه الشركات.

نصائح أخرى

ماس كهربائى والتقييم من أجل التقييم هو تكليف المعيار الدلالي في كل من C و C++.

إذا لم يكن الرمز مثل هذا لن تكون لغة مشتركة

   char* pChar = 0;
   // some actions which may or may not set pChar to something
   if ((pChar != 0) && (*pChar != '\0')) {
      // do something useful

   }

القسم 6.5.13 منطقية و مشغل من مواصفات C99 (PDF رابط) يقول

(4).على عكس جميع الثنائية المعامل & ، & & مشغل ضمانات من اليسار إلى اليمين التقييم ؛ هناك تسلسل نقطة بعد تقييم المعامل الأول.إذا كان أول المعامل يقارن يساوي 0 ، الثانية لا يتم تقييم المعامل.

وبالمثل, قسم 6.5.14 منطقية أو المشغل يقول

(4) على عكس المعامل | المشغل ، || مشغل ضمانات من اليسار إلى اليمين التقييم ؛ هناك تسلسل نقطة بعد التقييم الأول المعامل.إذا كان المعامل الأول يقارن غير متكافئة إلى 0 المعامل الثاني هو لم يتم تقييمها.

صيغة مماثلة يمكن العثور عليها في C++ المعايير ، تحقق من قسم 5.14 في مشروع نسخ.كما الداما الملاحظات في جواب آخر ، إذا تجاوز && أو | | كل المعاملات يجب أن يكون تقييم يصبح العادية استدعاء دالة.

نعم إنه ولايات (سواء تقييم النظام كهربائى).في المثال الخاص بك إذا كان كل الوظائف العودة الحقيقية, ترتيب المكالمات بدقة من functionA ثم functionB ثم functionC.يستخدم هذا مثل

if(ptr && ptr->value) { 
    ...
}

نفس المشغل فاصلة:

// calls a, then b and evaluates to the value returned by b
// which is used to initialize c
int c = (a(), b()); 

واحد يقول بين اليسار واليمين المعامل &&, ||, , و بين الأولى و الثانية/الثالثة المعامل ?: (المشروطة المشغل) هو "التسلسل نقطة".أي آثار جانبية يتم تقييم تماما قبل تلك النقطة.هكذا, هذا هو آمنة:

int a = 0;
int b = (a++, a); // b initialized with 1, and a is 1

لاحظ أن الفاصلة مشغل وينبغي عدم الخلط مع النحوية فاصلة لفصل الأمور:

// order of calls to a and b is unspecified!
function(a(), b());

C++ القياسية يقول في 5.14/1:

فإن && مشغل مجموعات من اليسار إلى اليمين.المعاملات على حد سواء ضمنا تحويلها إلى نوع bool (البند 4).النتيجة صحيحة إذا كان كل المعاملات صحيحة وكاذبة خلاف ذلك.على عكس &, && ضمانات من اليسار إلى اليمين التقييم:المعامل الثاني لا يتم تقييم إذا كان المعامل الأول هو زائف.

و في 5.15/1:

المشغل || مجموعات من اليسار إلى اليمين.المعاملات على حد سواء ضمنا تحويلها إلى bool (البند 4).إرجاع true إذا كان أي من المعاملات الحقيقية و الكاذبة خلاف ذلك.على عكس |, || ضمانات من اليسار إلى اليمين التقييم ؛ وعلاوة على ذلك ، فإن الثانية لا يتم تقييم المعامل إذا كان المعامل الأول إلى true.

يقول لكل بجانب تلك:

والنتيجة هي منطقي.جميع الآثار الجانبية من التعبير الأول باستثناء تدمير المؤقتات (12.2) يمكن التعبير تقييمها.

بالإضافة إلى ذلك ، 1.9/18 يقول

في تقييم كل من تعبيرات

  • a && b
  • a || b
  • a ? b : C
  • a , b

باستخدام المدمج في معنى من المشغلين في هذه التعبيرات (5.14, 5.15, 5.16, 5.18), هناك تسلسل نقطة بعد تقييم التعبير الأول.

ومباشرة من حسن البالغ من العمر K & R:

<اقتباس فقرة>   

وضمانات C التي && و|| يتم تقييمها من اليسار إلى اليمين - سنرى قريبا الحالات التي يكون فيها هذا المسائل

كن حذرا جدا جدا.

لأنواع أساسية هذه هي مشغلي الاختصار.

ولكن إذا قمت بتعريف هؤلاء المشغلين لديك فئة أو تعداد أنواع الخاصة أنها ليست الاختصار. وبسبب هذا الاختلاف الدلالي في استخدامها في ظل هذه الظروف مختلفة فمن المستحسن أن كنت لا تعرف هذه الشركات.

لوoperator && وoperator || لأنواع أساسية ترك أجل تقييم إلى اليمين (قطع قصيرة وإلا لن يكون :-) الصعب ولكن لمشغلي مثقلة الذي تعرفه، وهذه هي نحوي السكر أساسا لتحديد طريقة وبالتالي ترتيب تقييم المعلمات غير معرف.

وإذا كنت تثق يكيبيديا:

<اقتباس فقرة>   

[&& و||] تختلف غويا من المشغلين ووبت الحكمة | لأنها لن تقييم المعامل الصحيح إذا كانت النتيجة يمكن تحديد من الجهة اليسرى وحدها

http://en.wikipedia.org/wiki/C_(programming_language) #Characteristics

وسؤالك يأتي الى C ++ مشغل الأسبقية و ترابطيات. في الأساس، في التعبيرات مع شركات متعددة وليس قوسين، المترجم يبني شجرة التعبير عن طريق اتباع هذه القواعد.

لالأسبقية، عندما يكون لديك شيء من هذا القبيل A op1 B op2 C، هل يمكن أن الأمور جماعة إما (A op1 B) op2 C أو A op1 (B op2 C). إذا op1 له الأسبقية أعلى من op2، ستحصل على التعبير الأول. خلاف ذلك، سوف تحصل على ثانية واحدة.

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

في هذه الحالة بالذات، && له الأسبقية أعلى من ||، لذلك سيتم تقييم التعبير (a != "" && it == seqMap.end()) || isEven.

والأمر نفسه "من اليسار إلى اليمين" على شكل التعبير عن شجرة. لذلك سنقوم أولا تقييم a != "" && it == seqMap.end(). إذا كان هذا صحيحا التعبير كله صحيح، وإلا نذهب إلى isEven. الإجراء يعيد نفسه بشكل متكرر داخل اليسار التعبير الجزئي بطبيعة الحال.


والحكايات مثيرة للاهتمام، ولكن هذا المفهوم الأسبقية له جذوره في تدوين الرياضيات. ويحدث الشيء نفسه في a*b + c، حيث * له الأسبقية أعلى من +.

وحتى أكثر إثارة للاهتمام / غامضا، لA1 op1 A2 op2 ... opn-1 An التعبير unparenthasiszed، حيث يكون جميع المشغلين نفس الأسبقية، وعدد من أشجار التعبير الثنائية فإننا يمكن أن تشكل تعطى من قبل ما يسمى ب <لأ href = "HTTPS: //en.wikipedia كافيه / ويكي / Catalan_number "يختلط =" نوفولو noreferrer "> أرقام التشيكية . لn كبيرة، وهذه تنمو سريع للغاية. د

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