PDA

View Full Version : چرا جواب کد زیر 19 میشود؟؟؟



ravaei
دوشنبه 07 اردیبهشت 1394, 15:15 عصر
int i =5;
i += i++ + ++i;
cout<<i;




++i اول مقدار i رو بر میگردونه بعدش 1+ میکنه ... و i++ اول 1+ میکنه بعد حاصل رو برمیگردونه با این تفکر باید حاصل جمع 17 بشه نه 19 ولی 19 میشششششششششه!!!!!

ehsan_faal
دوشنبه 07 اردیبهشت 1394, 16:03 عصر
اول مقدار i برابره 5 (سمت چپ مساوی) .حالا به دومین قسمت از سمت چپ تساوی که میرسیم مقدار فعلی i برابره 6 ه. که درجا یه دونه هم زیاد میشه و میشه 7.
تا این جا مقدار i =7 و سمت چپ عدد 12 رو داریم که با 7 جمع میشه و 19 میشه دیگه.

rahnema1
دوشنبه 07 اردیبهشت 1394, 19:11 عصر
int i =5;
i += i++ + ++i;
cout<<i;




++i اول مقدار i رو بر میگردونه بعدش 1+ میکنه ... و i++ اول 1+ میکنه بعد حاصل رو برمیگردونه با این تفکر باید حاصل جمع 17 بشه نه 19 ولی 19 میشششششششششه!!!!!

سلام
این جور نوشتن عبارت از نظر ++c اشتباهه و موجب رفتار تعریف نشده یا undefined behavior میشه
ببینید در ++c ترتیب براورد شدن عملوندهای بیشتر عملگرها مشخص نیست (برخلاف زبانی مثل جاوا که همیشه از چپ به راست هست)
مثلا در عبارت a+b مشخص نیست ابتدا a براورد میشه یا b
از طرف دیگه عملگرها میتونند اثرجانبی داشته باشند مثل دو عملگر =+ یا ++ که بعد از i میاد
در عملگر =+ یک بار قسمت سمت راست برآورد می شه و یک بار قسمت سمچ چپ براورد می شه و یک بار هم اثر جانبی داریم که تغییر مقدار عملوند سمت چپ هست
اما در =+ معلوم نیست ابتدا سمت چپ براورد میشه و یا سمت راست همچنین در + هم معلوم نیست
اجازه بدید ای عبارت را به چهار تا زیر عبارت نام گذاری کنیم

بنابراین در عبارتی که شما نوشتید این سناریو ها می تونند اتفاق بیفتند
مقدار برآورد شده عبارت با val و اثرجانبی عبارت را با sid نشون میدیم
مثلا در سناریو اول ابتدا 1 و سپس 2 براورد بشه و داخل 2 هم ابتدا 3و سپس 4

i += i++ + ++i
_ _________
1 2

i++ + ++i
___ ___
3 4
scenario 1:
1 -> 2 and 3 -> 4
val1 = 5
val3 = 5
sid3 -> i=6
val4 = 7
sid4 -> i=7
val2 = 12
sid1 -> i=17

scenario 2:
1 -> 2 and 4 -> 3
val1 = 5
val4 = 6
sid4 -> i=6
val3 = 6
val2 = 12
sid3 -> i=7
sid1 -> i=17

scenario 3:
2 -> 1 and 3 -> 4
val3=5
sid3 -> i=6
val4 = 7
sid4 -> i=7
val2 = 12
val1 = 7
sid1 -> i = 19

scenario 4:
2 -> 1 and 4 -> 3
val4=6
sid4 -> i=6
val3 = 6
val2 = 12
sid3 -> i=7
val1 = 7
sid1 -> i = 19

می بینیم که هم 19 امکان پذیره و هم 17
در این مور در این تاپیک هم بحث شده:
http://barnamenevis.org/showthread.php?455319

ehsan_faal
دوشنبه 07 اردیبهشت 1394, 19:25 عصر
ولی توی کتاب برنامه نویسی به زبان ++C(دکتر مرتضی صاحب الزمانی) توضیحاتی در مورد تقدم عملگرها داده که با اون توضیحات فقط به عدد 19 میرسیم.

rahnema1
دوشنبه 07 اردیبهشت 1394, 19:32 عصر
ولی توی کتاب برنامه نویسی به زبان ++C(دکتر مرتضی صاحب الزمانی) توضیحاتی در مورد تقدم عملگرها داده که با اون توضیحات فقط به عدد 19 میرسیم.

اینجا بحث تقدم عملگرها نیست بلکه بحث ترتیب اجرای عملوند های یک عملگر هست که در بیشتر عملگرهای زبان ++c (به جز چندتا) این ترتیب نامشخصه

ravaei
دوشنبه 07 اردیبهشت 1394, 20:34 عصر
سلام
این جور نوشتن عبارت از نظر ++c اشتباهه و موجب رفتار تعریف نشده یا undefined behavior میشه
ببینید در ++c ترتیب براورد شدن عملوندهای بیشتر عملگرها مشخص نیست (برخلاف زبانی مثل جاوا که همیشه از چپ به راست هست)
مثلا در عبارت a+b مشخص نیست ابتدا a براورد میشه یا b
از طرف دیگه عملگرها میتونند اثرجانبی داشته باشند مثل دو عملگر =+ یا ++ که بعد از i میاد
در عملگر =+ یک بار قسمت سمت راست برآورد می شه و یک بار قسمت سمچ چپ براورد می شه و یک بار هم اثر جانبی داریم که تغییر مقدار عملوند سمت چپ هست
اما در =+ معلوم نیست ابتدا سمت چپ براورد میشه و یا سمت راست همچنین در + هم معلوم نیست
اجازه بدید ای عبارت را به چهار تا زیر عبارت نام گذاری کنیم

بنابراین در عبارتی که شما نوشتید این سناریو ها می تونند اتفاق بیفتند
مقدار برآورد شده عبارت با val و اثرجانبی عبارت را با sid نشون میدیم
مثلا در سناریو اول ابتدا 1 و سپس 2 براورد بشه و داخل 2 هم ابتدا 3و سپس 4

i += i++ + ++i
_ _________
1 2

i++ + ++i
___ ___
3 4
scenario 1:
1 -> 2 and 3 -> 4
val1 = 5
val3 = 5
sid3 -> i=6
val4 = 7
sid4 -> i=7
val2 = 12
sid1 -> i=17

scenario 2:
1 -> 2 and 4 -> 3
val1 = 5
val4 = 6
sid4 -> i=6
val3 = 6
val2 = 12
sid3 -> i=7
sid1 -> i=17

scenario 3:
2 -> 1 and 3 -> 4
val3=5
sid3 -> i=6
val4 = 7
sid4 -> i=7
val2 = 12
val1 = 7
sid1 -> i = 19

scenario 4:
2 -> 1 and 4 -> 3
val4=6
sid4 -> i=6
val3 = 6
val2 = 12
sid3 -> i=7
val1 = 7
sid1 -> i = 19

می بینیم که هم 19 امکان پذیره و هم 17
در این مور در این تاپیک هم بحث شده:
http://barnamenevis.org/showthread.php?455319



ممنون از توضیحات در واقع قبل از اینکه تکلیف i مشخص نشده اون رو ثابت نمیکنه و با تغییر کردن i در سمت راست تساوی مقدار i در سمت چپ تساوی تغییر میکنه ... :لبخندساده: