PDA

View Full Version : سوال: نتیجه عملگرهای افزایشی



farshidge
دوشنبه 27 تیر 1390, 22:32 عصر
فکر می کنید نتیجه کد زیر چی می شه ؟! :متفکر:

#include <iostream>
using namespace std;
int main()
{
int i = 1;
i = ++i + ++i;
cout << i;

cin.get();
return 0;
}
جواب : 6

و یا کد زیر نتیجش چی می شه ؟

#include <iostream>
using namespace std;
int main()
{
int i = 1;
cout << ++i << i++ << i;

cin.get();
return 0;
}
جواب : 313

منظورم دقت کردن به increment ها هستش، من با mingw کامپایل کردم جواب عجیبی بهم داد، ولی تو جاوا همچنین نتیجه ایی بهمون نمیده.
نمی دونم مشکل کجاست ؟! :متفکر:

Salar Ashgi
سه شنبه 28 تیر 1390, 11:41 صبح
این موضوع قبلا هم چند بار بررسی شده است . نتیجه خروجی به نظر عجیب میاد ولی در واقع طبیعیه ، چرا که این خروجی برمی گرده به نحوه تعریف عملگر افزایشی و آبجکت cout !!!

irpersian20
چهارشنبه 29 تیر 1390, 10:59 صبح
امكان داره لينك تاپيكي كه قبلا بحث شده را اينجا بگذاريد تا ما هم متوجه موضوع بشويم.؟

bigtime
جمعه 31 تیر 1390, 23:45 عصر
با سلام من اولی رو قبول دارم ولی دومی چرا اینطوری شد؟
من فکر می کنم خروجی دومی باید 223 بشه
لطفا کمی توضیح بدید

irpersian20
پنج شنبه 06 مرداد 1390, 21:34 عصر
كسي نبود؟؟؟

tdkhakpur
پنج شنبه 06 مرداد 1390, 23:24 عصر
خروجی باید 1 1 3 بشه و میتونه بسته به نوع کامپایلر و مفسر همراه ان نتیجه متفاوتی بده


cout << ++i << i++ << i;
1+1 + 1 + no = 3
no + 1 + no = 1
no + no + 1 = 1

Mokhless
جمعه 07 مرداد 1390, 23:01 عصر
من قبلا این مورد رو بررسی کردم :خجالت:
برنامه :

#include <iostream>
using namespace std;
int main()
{
int i=1;
i=(++i)+(++i);
cout<<i<<endl;
return 0;
}
کد اسمبلی تولید شده توسط VC++ 2010 :
قسمت مربوط به پرانتز اول :

00E12D55 mov eax,dword ptr [i] ;// i --> eax ( i ro mirize tuye eax )
00E12D58 add eax,1 ;// eax+1 --> eax ( 1 ro be eax ezafe mikone)
00E12D5B mov dword ptr [i],eax ;// i=eax ( eax ro mirize tu i)
تا اینجا i=2
قسمت مربوط به پرانتز دوم :

00E12D5E mov ecx,dword ptr [i] ;// i -->ecx (i ro mirize tuye ecx)
00E12D61 add ecx,1 ;// ye denue be ecx ezafe mikone
00E12D64 mov dword ptr [i],ecx ;// ecx ri mirize tuye i
حالا i=3
جمع دو پرانتز :

00E12D67 mov edx,dword ptr [i] ;// i ro mirize tu edx
00E12D6A add edx,dword ptr [i] ;// edx ri ba i jam mikone
00E12D6D mov dword ptr [i],edx ;// edx ro mirize tu i va i= 6
میبینید که واسه هر دو پرانتز مقدار فعلی i رو قرار میده و دقیقا مشکل همینجاس !
قاعدتا باید هر دو مقدار تولید شده رو به صورت موقت یه جا نگه داره که این کارو نمیکنه (شاید واسه بهینه سازی !) .

Mokhless
جمعه 07 مرداد 1390, 23:24 عصر
با سلام من اولی رو قبول دارم ولی دومی چرا اینطوری شد؟
من فکر می کنم خروجی دومی باید 223 بشه
لطفا کمی توضیح بدید

اینم کد اسمبلی دومی :

int i = 1;
00C613AE mov dword ptr [i],1
cout << ++i << i++ << i;
00C613B5 mov eax,dword ptr [i]
00C613B8 mov dword ptr [ebp-0D0h],eax
00C613BE mov ecx,dword ptr [i]
00C613C1 add ecx,1
00C613C4 mov dword ptr [i],ecx
00C613C7 mov edx,dword ptr [i]
00C613CA add edx,1
00C613CD mov dword ptr [i],edx
00C613D0 mov esi,esp
00C613D2 mov eax,dword ptr [i]
00C613D5 push eax
00C613D6 mov edi,esp
00C613D8 mov ecx,dword ptr [ebp-0D0h]
00C613DE push ecx
00C613DF mov ebx,esp
00C613E1 mov edx,dword ptr [i]
00C613E4 push edx
00C613E5 mov ecx,dword ptr [__imp_std::cout (0C682A0h)]
00C613EB call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0C68298h)]
خلاصه می کنم :
اول i رو یه جا ذخیره میکنه بعد یدونه بهش اضافه میکنه ! دوباره یدونه دیگه بهش اضافه میکنه میشه 3 ! 3 رو میریزه تو پشته بعد مقدار قبلی i یعنی 1 رو میریزه تو پشته . حالا دوباره 3 یعنی مقدار فعلی i رو میریزه تو پشته ودر آخر هم اون 3 مقدار رو چاپ میکنه که میشه 313
میشه گفت یه جور باگه !!! :گیج:

bigtime
دوشنبه 10 مرداد 1390, 10:27 صبح
با سلام
اقا کسی می تونه دلیل این رفتار کامپایلر رو توضیح بده؟
من با visual stadio کامپایلش کردم دومی رو بهم جواب 213 داد بعد با turbo c++ کامپایلش کردم بهم 311 داد خوب دلیل جواب turbo c++ بخاطر اینه که printf ,cout رو از آخر به اول بررسی و چاپ می کنه ولی دلیل کار visual stadio رو نمی فهمم اگه میشه یکی که خوب بلد توضیح بده.
ممنون

_hamid
یک شنبه 16 مرداد 1390, 01:20 صبح
اصولا کامپایلر های سی و سی پلاس پلاس معروفن به بهینه کردن کد اسمبلی.
دقیقا همینطور mokhless نوشتن اینکار رو انجام می ده که کد بهینه بشه.
این کد نتیجه اش یه جور رفتار نامعلوم (undefined behavior) است چون نسبت به کامپایلرهای گوناگون متفاوته.
حالا استادهای احمقی که میان سوال کنکور اینجوری طرح می کند دیگه پا خودشون.