التسلسل المخزن المؤقت والإخراج من Cout و PrintF
سؤال
أعرف أن Cout و PrintF لديهما عازلة اليوم ، ويقال إن المخزن المؤقت يشبه المكدس ويحصل على إخراج Cout و PrintF من اليمين إلى اليسار ، ثم قم بإخراجهم (إلى وحدة التحكم أو الملف) من أعلى إلى Bottem. مثله،
a = 1; b = 2; c = 3;
cout<<a<<b<<c<<endl;
buffer:|3|2|1|<- (take “<-” as a poniter)
output:|3|2|<- (output 1)
|3|<- (output 2)
|<- (output 3)
ثم أكتب رمزًا أدناه ،
#include <iostream>
using namespace std;
int c = 6;
int f()
{
c+=1;
return c;
}
int main()
{
int i = 0;
cout <<"i="<<i<<" i++="<<i++<<" i--="<<i--<<endl;
i = 0;
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
cout<<f()<<" "<<f()<<" "<<f()<<endl;
c = 6;
printf("%d %d %d\n" , f() , f() ,f() );
system("pause");
return 0;
}
تحت VS2005 ، الإخراج هو
i=0 i++=-1 i--=0
i=0 i++=-1 i--=0
9 8 7
9 8 7
تحت G ++ ((GCC) 3.4.2 (MingW-special)) ، يكون الإخراج هو ،
i=0 i++=0 i--=1
i=0 i++=-1 i--=0
9 8 7
9 8 7
يبدو أن المخزن المؤقت يشبه المكدس. ومع ذلك ، قرأت C ++ Primer Plus اليوم ، ويقال إن COUT يعمل من اليسار إلى اليمين ، في كل مرة يعيد فيها كائن (COUT) ، لذلك "هذه هي الميزة التي تتيح لك تسلسل الإخراج باستخدام الإدراج". لكن من اليسار إلى الطريق الأيمن لا يمكن أن يفسر Cout <output 9 8 7 الآن أنا مرتبك حول كيفية عمل العازلة الخاصة بـ Cout ، هل يمكن لأي شخص مساعدتي؟
المحلول
هذا ليس خطأ ، ولا يتعلق الأمر بالتخزين المؤقت للإخراج.
ترتيب تنفيذ i--
و i++
لا يتم تعريف العمليات عندما يتم الاحتجاج بها أكثر من مرة كمعلمات إلى نفس استدعاء الوظيفة.
لتوضيح (وربما صحيح) ذكر Iraimbilanja لـ "نقاط التسلسل" ، cout
الإصدار يعادل:
(((cout << a) << b) << c)
على نحو فعال ، إنها في الواقع ثلاثة مكالمات وظيفية منفصلة ، يتم تقييم كل من معلماتها بالترتيب ، على الرغم من أنها مكتوب مثل بيان واحد.
ال <<
المشغل هو حقا ostream& operator<<(ostream& os, int)
, ، لذلك طريقة أخرى لكتابة هذا:
operator<< ( operator<< ( operator<< ( cout, a ), b ), c )
نظرًا لأنه لا يتم تحديد (AFAIK) للمكالمة الخارجية ، فهو غير محدد للطلب الذي يتم تقييم المعلمتين ، فمن الممكن تمامًا للمعلمة اليمنى "C" (أو في حالتك "i--
") أن يحدث قبل تقييم المعلمة اليد اليسرى.
نصائح أخرى
إخراج:
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
غير محدد. هذا هو مأزق شائع لـ C ++: أمر تقييم الوسيطة غير محدد.
ليس كذلك مع حالة COUT: يستخدم المكالمات المقيدة (نقاط التسلسل) ، وليس الوسائط لوظيفة واحدة ، لذلك يتم تعريف أمر التقييم جيدًا من اليسار إلى اليمين.
يحرر: يشير ديفيد ثورنلي إلى أن سلوك الكود أعلاه هو في الواقع غير معرف.
إذا كان ذلك ممكنًا ، حاول التحديث إلى GCC> = 4. لقد قمت فقط بتشغيل هذا على 4.0.1 وينفذ Dandy فقط.