التسلسل المخزن المؤقت والإخراج من Cout و PrintF

StackOverflow https://stackoverflow.com/questions/659266

  •  20-08-2019
  •  | 
  •  

سؤال

أعرف أن 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 فقط.

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