PDA

View Full Version : خروجی های متفاوت یک قطعه کد در C# و C++ !!



مرتضی تقدمی
شنبه 29 مهر 1391, 21:04 عصر
با سلام
قطعه کد زیر در C# و C++ خروجی های متفاوتی می ده! در C# مقدار 38 و در C++ مقدار 39 در خروجی چاپ میشه!!
کسی دلیل این رو می دونه؟!



int x = 10, y = 3, z = 0;
z = x++ + ++x + y++ + ++x;

موفق باشید

danialafshari
شنبه 29 مهر 1391, 21:22 عصر
ممکنه یک عدد اعشاری مثل38.844655 بوده که گرد ش کرده باشه و داده 39 :متفکر:

morteza271
شنبه 29 مهر 1391, 21:36 عصر
ممکنه یک عدد اعشاری مثل38.844655 بوده که گرد ش کرده باشه و داده 39 :متفکر:
دوست عزیز اقا دانیال من یه سوال از شما دارم!!!
آیا شما واقعا به کدی که دوستمون گذاشتن نگاه کردین و این پاسخ رو گذاشتین؟؟؟؟؟؟؟؟!!!!:متعجب::م عجب::متعجب:
شما اگه یه دقت کوچولو توی کد بکنین متوجه میشین که نتیجه عدد اعشاری نمیشه چرا که هیچ کدوم از اعداد اعشاری نیستند و اعمال انجام شده هم فقط یکی به مقدار متغیرها اضافه میکنه پس چطوری میخواد عدد اعشاری حاصل بشه؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟
منو ببخشید که اینطوری صحبت کردم آخه توی این سایت زیاد می بینم که دوستان اینطوری پاسخ میدن و نمیتونم جلوی خودمو بگیرم و پاسخ ندم....

در مورد سوال هم باید بگم واسه منم خیلی عجیبه و اینکه چرا این اتفاق افتاده خیلی جالبه و باید ببینیم چرا اینطوری هست!!! من که تا الان فکر میکردم C# و C++ از نظر نتیجه اینطور کدها باهم تفاوتی ندارن!!!

موفق باشید.

AceBomBom
شنبه 29 مهر 1391, 21:55 عصر
سلام

منم اینجوری مشکلات برام پیش اومده و در آخر جواب c++ درست بود

در کل فکر کنم کامپایلر c++ از c# حداقل تو این موارد قویتره

براساس تجربه گفتم
فقط همین

مرتضی تقدمی
شنبه 29 مهر 1391, 22:02 عصر
بحثی که پیش میاد بحث تقدم عملگرهاست. چیزی که در MSDN خود میکروسافت آمده, ++ و -- پیشوندی بالاترین و ++ و -- پسوندی کمترین تقدم رو دارن. اینو گفته بود در C# و C++ هر دو شبیه هم هستند. حالا اینجا جالبه که چرا این اتفاق افتاده! :متعجب:

veniz2008
شنبه 29 مهر 1391, 22:09 عصر
در کل فکر کنم کامپایلر c++ از c# حداقل تو این موارد قویتره
حالا شما از کجا فهمیدی که ++C جواب درست رو داده؟.
چیزی که منطق نشون میده ، #C داره درست میگه.
اگر اون x++ آخری رو برداری جفتشون یکسان هستن با اضافه شدن این آخری مقدارهاشون متفاوت میشه.

مرتضی تقدمی
شنبه 29 مهر 1391, 22:11 عصر
بصورت دستی هم که حساب کنیم مقدار 38 یعنی خروجی C# درسته.

lalecarbon
شنبه 29 مهر 1391, 22:14 عصر
سلام

يك دليل مي تونه ++ پيشوندي و پسوندي باشه.
يعني در عبارت
z = x++ + ++x + y++ + ++x;
++xكه بدون تغيير جايگزين ميشه، اما در x++، به دليل اينكه تغيير روي X اعمال ميشه، تغيير ++x هم اعمال ميشه و جواب رو محاسبه مي كنه.
يعني ميشه
z = 10 + 12 + 4 + 13;
در اولين ++x ، تغيير ++x نيز اعمال مي شود و اين نتيجه حاصل مي شود.

دليله ديگه مي تونه اولويت عملگرها در همان خط باشه كه فكر مي كنم منطقي نباشه. يعني اولويت x++ كه بالاتر هست ابتدا محاسبه مي شود و نتيجه به صورت زير مي شود:
z = 12 + 11 + 3 + 12;

حالا در سايت مايكروسافت هم سوال كرديم، بايد ديد چه جوابي براش وجود داره.

موفق باشيد

mohamad.zakery
شنبه 29 مهر 1391, 22:16 عصر
نه دوست من

http://msdn.microsoft.com/en-us/library/126fe14k%28v=vs.80%29.aspx
http://msdn.microsoft.com/en-us/library/6a71f45d%28v=vs.80%29.aspx

++ پرفیکس و + در C#و C++ یک تقدم ندارند
دلیل اینه!!!


یک تجربه شخصی:
کامپایلر هیچ وقت اشتباه نمی کنه!!!

lalecarbon
شنبه 29 مهر 1391, 22:21 عصر
نه دوست من

http://msdn.microsoft.com/en-us/library/126fe14k%28v=vs.80%29.aspx
http://msdn.microsoft.com/en-us/library/6a71f45d%28v=vs.80%29.aspx

++ پرفیکس و + در C#و C++ یک تقدم ندارند
دلیل اینه!!!


یک تجربه شخصی:
کامپایلر هیچ وقت اشتباه نمی کنه!!!

بله تقدم عملگرها متفاوت هست.
الان بحث نحوه ي محاسبه هست كه با چه روشي داره محاسبه مي كنه.

veniz2008
شنبه 29 مهر 1391, 22:31 عصر
نه دوست من

http://msdn.microsoft.com/en-us/library/126fe14k%28v=vs.80%29.aspx
http://msdn.microsoft.com/en-us/library/6a71f45d%28v=vs.80%29.aspx

++ پرفیکس و + در C#و C++ یک تقدم ندارند
دلیل اینه!!!


یک تجربه شخصی:
کامپایلر هیچ وقت اشتباه نمی کنه!!!


بله تقدم عملگرها متفاوت هست.
الان بحث نحوه ي محاسبه هست كه با چه روشي داره محاسبه مي كنه.
عزیز چطور تقدم ها متفاوتن؟. اون دو تا لینک هم که میگن تقدم ها یکسانه.

danialafshari
چهارشنبه 03 آبان 1391, 03:12 صبح
واقعا معذرت می خوام از دوستان کد رو دقیق نگاه نکردم

FastCode
چهارشنبه 03 آبان 1391, 07:40 صبح
C++‎ از نظر منطقی درست تره.++ باید اولوین داشته باشه.
z = x++ + ++x + y + ++++x;

arshia_
چهارشنبه 03 آبان 1391, 09:22 صبح
يه بار ديگه كد رو بررسي كنيد تا متوجه بشيد
ما فقط يك عبارت داريم پس اولويتها در هنگام انجام عمليات در نظر گرفته مي شه
اولويت X++ از اولويت ++X بيشتره و با اينكه اول اومده ولي قبل از انجام عمليات تغيير مقدار صورت مي گيره.
با پرانتز گذاري كاملا متوجه امر خواهيد شد.
منطق C# احتمالا مثل منطق دستي حل كردن شده!

veniz2008
چهارشنبه 03 آبان 1391, 10:26 صبح
C++‎‎‎ از نظر منطقی درست تره.++ باید اولوین داشته باشه.
z = x++ + ++x + y + ++++x;
لطفا بیشتر توضیح بدید. متوجه نشدم دقیقا منظورتون چیه. کدوم ++ ؟ پیشوندی منظورتونه؟

ما فقط يك عبارت داريم پس اولويتها در هنگام انجام عمليات در نظر گرفته مي شه
اولويت X++ از اولويت ++X بيشتره و با اينكه اول اومده ولي قبل از انجام عمليات تغيير مقدار صورت مي گيره.
منظور شما اینه که x++ در جمله مورد بحث، اول محاسبه میشه؟
فرض رو میگیریم که حرف شما درست باشه. با این توصیف ابتدا x++ (دوم) محاسبه میشه ( یعنی 11) و بعد x++ آخری (یعنی 12). مقدار ++x (جمله اول) هم باید 12 بمونه و ++y هم که همون 3 خودش باقی میمونه. اگر جمع بزنیم بازم میشه 38.

FastCode
چهارشنبه 03 آبان 1391, 10:57 صبح
حرفم رو پس میگیرم.هر جور حساب کنی نمیشه.
اگر پست اول من درست بود باید نتیجه C++ دو تا بیشتر میشد.

zayens
پنج شنبه 04 آبان 1391, 10:38 صبح
با سلام
قطعه کد زیر در C#‎‎ و C++‎‎ خروجی های متفاوتی می ده! در C#‎‎ مقدار 38 و در C++‎‎ مقدار 39 در خروجی چاپ میشه!!
کسی دلیل این رو می دونه؟!



int x = 10, y = 3, z = 0;
z = x++ + ++x + y++ + ++x;

موفق باشید
برای سی شارپ
بیاین کدها را بررسی کنیم تا ببینیم چه اتفاقی میفته!
فقط قبلش یه نکته بگم واونم اینه که در این عملگرها اطلاعات در سی شارپ از راست به چپ ریخته میشه ولی اولویت محاسبه با چپ ترینه!
خب!
گفته z مساویه با :

x++
مهم اینجا مقدار x را اول میریزه توی z بعدش یه دونه X را زیاد میکنه یعنی حاصل این عبارت میشه 10 و مقدار x=11
(یه عکس گذاشتم که نگاه کنین)
94326


++x
در اینجا به x که 11 بود یه واحد اضافه میکنه و مقدار x را هم تغییر میده یعنی حاصل میشه 12 و x هم میشه 12 !!

y++
اینهم که معلومه و مثل مورد اول در ابتدا حاصل را برای محاسبه اضافه میکنه Result=3 و بعدش یه واحد به y اضافه میکنه y=4 که در نتیجه آخر بی اهمیته

++x
و در اینجا هم به x که 12 هست یه واحد اضافه میکنه و حاصل میشه 13 و x هم 13 خواهد بود
حالا بیاین جمع کنیم
13 + 3 + 12 + 10
که جواب میشه 38
جالبه اگر بدونین که توی جاوا هم جواب برابر 38 خواهد بود

اما برای سی ++
توی سی++ باید به prefix و postfix‌بودن عملگرها و عبارات دقت کنین

گفته z مساویه با :

x++
مهم خب گفته باشه!
توی این عبارت یه عبارت دیگه هست که در محاسبه اولویت داره و اون هم x++ هست!!
پس در ابتدا x++ ها محاسبه میشن و مثل سی شارپ از اول خط شروع به محاسبه نمیکنه!!

++x
پس محاسبه ازینجا شروع میشه (یه جورایی شبیه عملیات ضرب و جمع در سی شارپ که اولویت با ضربه حتی اگر ابتدای عبارت نباشه z=x+m*4)
پس در اینجا به x که 10 هست یه واحد اضافه میکنه و مقدار x را هم تغییر میده یعنی حاصل میشه 11 و x هم میشه 11 !!

y++
این عبارت را هم چون اولویت نداره بیخیال میشه و در آخر محاسبه میکنه ( در کل حاصل 3 )

++x
در اینجا هم به x که 11 هست یه واحد اضافه میکنه و حاصل میشه 12 و x هم 12 خواهد بود
حالا در آخر مقادیر ++y و ++x را اضافه میکنه که گفتیم y همون 3 خواهد بود
و در ++x حاصل برابر با 12 خواهد بود و x=13 میشه اما چون آخر محاسبه شده و x در حافظه است مقدار x را به حاصل اضافه میکنه نه مقدار عبارت را !
حالا بیاین جمع کنیم
13 + 3 + 12 + 11
که جواب میشه 39
نتیجه
کمپانی مربوطه روش محاسبه توی ++C را بخاطر مشکلاتی که بوجود آورده بود بطور کلی در زبانهای بعد از خودش عوض کرد و بقول یکی از دوستامون:
منطق C#‎ مثل منطق دستي حل كردن شده!

veniz2008
پنج شنبه 04 آبان 1391, 12:08 عصر
برای سی شارپ
و در ++x حاصل برابر با 12 خواهد بود و x=13 میشه اما چون آخر محاسبه شده و x در حافظه است مقدار x را به حاصل اضافه میکنه نه مقدار عبارت را !
نه عزیز من. اگر در خط بعد شما بیای و مقدار x رو چاپ کنی ( ;cout<<x ) اونوقت به شما 13 رو میده ولی درون محاسبه که نمیاد بگه x مقدارش 13 هست. یه مثال نقض واسه تحلیلتون میارم( با همون مقادیر قبلی یعنی x = 10 باشه).

z = x++ + x++;
حالا طبق گفته شما مقدار ++x ( اولی ) همون 10 میمونه و x میشه 11 ، برای ++x ( دومی ) چون در آخر محاسبه شده و در حافظه مونده برابر 11 خواهد بود که اگر چمع بزنیم میشه 21 در صورتیکه خروجی که صادر میشه 20 هستش.

zayens
پنج شنبه 04 آبان 1391, 12:29 عصر
حالا طبق گفته شما مقدار ++x ( اولی ) همون 10 میمونه و x میشه 11 ، برای ++x ( دومی ) چون در آخر محاسبه شده و در حافظه مونده برابر 11 خواهد بود که اگر جمع بزنیم میشه 21 در صورتیکه خروجی که صادر میشه 20 هستش.
!!!
خروجی 20 میشه!!
خدا وکیلی یه حساب بکنین (توی همین سی شارپ) ببینین آیا جواب 21 نمیشه!

94330

veniz2008
پنج شنبه 04 آبان 1391, 16:25 عصر
!!!
خروجی 20 میشه!!
خدا وکیلی یه حساب بکنین (توی همین سی شارپ) ببینین آیا جواب 21 نمیشه!

94330
شما ظاهرا همه حساب کتابها رو روی کاغذ انجام میدی!!!.
داداش یه ++ Turbo C نصب کن ببین 20 میشه یا 21.
لطفا حرف های منو کامل بخون. من نگفتم در سی شارپ جواب 20 میشه. بحث بر سر جواب هایی هست که ++c نشون میده.

linux
جمعه 05 آبان 1391, 01:26 صبح
با سلام
قطعه کد زیر در C# و C++ خروجی های متفاوتی می ده! در C# مقدار 38 و در C++ مقدار 39 در خروجی چاپ میشه!!
کسی دلیل این رو می دونه؟!



int x = 10, y = 3, z = 0;
z = x++ + ++x + y++ + ++x;

موفق باشید

دقیقا به کامپایلر شما بستگی دارد با gcc در لینوکس شما جواب ۳۷ خواهید گرفت
اما در سی شارپ:
از سمت چپ محاسبه شروع می شود چون اولویت x++ بیشتر هست پس ابتدا x برابر ۱۱ خواهد شد و بعد x++ + ++x برابر ۲۲ خواهد شد حالا چون محاسبه انجام شده ++x محاسبه شده و x مقدار ۱۲ را خواهد گرفت در ادامه
۲۲ با ۳ جمع شدخ مقدار z برابر ۲۵ شده و حالا با مقدار x++ برابر ۱۳ شده و جمع ۱۳+۲۵ برابر ۳۸ خواهد شد.

در سی ( ویژوال سی) ویندوز:
به نظر می رسد که به توجه به الویت ++ ابتدا مقدار ++x + ++x پردازش می شود که برابر ۲۴ خواهد بود بعد + ++x افزوده می شود که در این حالت مقدار x برابر ۱۲ خواهد بود تا اینجا جمع اعداد برابر ۳۶ است که با افزودن ۳ مقدار ۳۹ خواهد شد به نظر می رسد که چون کل محاسبات در یک خط اتفاق می افتد کامپایلر سی ++x را محاسبه نمی کنند.

اما در gcc و در لینوکس مانند سی شارپ پردازش از سمت چپ شروع شده و مقدار ۲۲ بدست می آید ولی بعد از انجام جمع (x++ (x++ + ++x پردازش نمی گردد و مقدار x همان ۱۱ خواهد بود با افزودن ۳ مقدار به ۲۵ رسیده و با افزودن x++ که برابر ۱۲ خواهد شد در کل عدد ۳۷ بدست خواهد آمد.
امیدوارم توضیحات روشن باشد و کلا همچین کدی خیلی گیج کننده خواهد بود حتی برای کامپایلر حالا اگر محاسبات به این شکل صورت گیرد

z=x++;
z+=++x;
z+=y++;
z+= ++x;

مقدار بدست آمده برابر ۳۸ خواهد بود هر چند خیلی بعید هست که در یک برنامه کاربردی همچین کدی نوشته شود.

FastCode
جمعه 05 آبان 1391, 14:15 عصر
Microsoft یک بار با تغییر ه params کاری با من کرد که چند ساله همه جا پرانتز میزارم.

veniz2008
جمعه 05 آبان 1391, 14:26 عصر
در سی ( ویژوال سی) ویندوز:
به نظر می رسد که به توجه به الویت ++ ابتدا مقدار ++x + ++x پردازش می شود که برابر ۲۴ خواهد بود بعد + ++x افزوده می شود که در این حالت مقدار x برابر ۱۲ خواهد بود تا اینجا جمع اعداد برابر ۳۶ است که با افزودن ۳ مقدار ۳۹ خواهد شد
دوست عزیز، واقعا به چیزهایی که نوشتی اعتقاد داری؟ یا فقط خواستی هرطوری شده به جواب ++C برسی؟
میشه بگید 24 رو چطور بدست آوردید؟

به نظر می رسد که چون کل محاسبات در یک خط اتفاق می افتد کامپایلر سی ++x را محاسبه نمی کنند.
این جواب بدترین جوابیه که من در طول این 21 پست دیدم. کمترین منطقی در این جمله مشاهده نمیشه.

مرتضی تقدمی
جمعه 05 آبان 1391, 16:16 عصر
تا امروز که من اینجور مسائل رو بصورت زیر حل می کردم:

- اگر ++ یا -- پیشوندی وجود دارد از سمت چپ همه را به ترتیب اعمال می کنیم.
- محاسبات رو انجام میدیم و در متغیر نتیجه قرار میدیدم.
- اگر ++ یا -- پسوندی وجود دارد از سمت چپ همه را اعمال می کنیم.

با این اوصاف نتیجه بصورت زیر 38 خواهد بود:
x = 10, y = 3
z = x++ + ++x + y++ + ++x
z = 12 + 11 + 3 + 12
2 4 1 3 :الویت
در پایان:
z = 38
x = 13
y = 4

دوستان اگه فرصت دارند چند نمونه دیگه شبیه این مسئله رو در C#‎ و C++‎ اجرا کنند ببیند که جواب یکی در میاد یا نه.
تشکر
موفق باشید

veniz2008
جمعه 05 آبان 1391, 16:27 عصر
دوستان اگه فرصت دارند چند نمونه دیگه شبیه این مسئله رو در C#‎‎ و C++‎‎ اجرا کنند ببیند که جواب یکی در میاد یا نه.
تا دلتون بخواد مثال واسش هست فقط تا الان ظاهرا کسی توجه نکرده بود که خوشبختانه شما رو کردید. مثلا عبارت زیر در سی شارپ 21 و در سی پلاس مقدار 20 رو برمیگردونه:

z = x++ + x++;

linux
جمعه 05 آبان 1391, 17:59 عصر
دوست عزیز، واقعا به چیزهایی که نوشتی اعتقاد داری؟ یا فقط خواستی هرطوری شده به جواب ++C برسی؟
میشه بگید 24 رو چطور بدست آوردید؟

این جواب بدترین جوابیه که من در طول این 21 پست دیدم. کمترین منطقی در این جمله مشاهده نمیشه.
دوست عزیز دین و ایمان که نیست بحث اعتقاد پیش بیاید، یک روال مشخص هست و اگر شما فکر می کنید اینجور نیست خوب برید بیشتر مساله را بشکافید
اگر زحمت می کشیدید یک خط کد می نوشتی می دیدی که جواب برابر ۲۴ خواهد شد هم gcc هم در ویژوال سی و هم در gcc. شما لطف کنید بگید که چرا ۲۴ می شه البته با منطق!
کامپایلر سی بعد از اینکه این خط کد را پردازش می کند در خط بعدی پردازش ++x را پردازش می کند می توانید خودتان امتحان کنید.

veniz2008
جمعه 05 آبان 1391, 20:13 عصر
دوست عزیز دین و ایمان که نیست بحث اعتقاد پیش بیاید،
با این حرفتون موافق نیستم. اعتقاد لزوما درباره مسائل دینی و مذهبی بکار نمیره. نمیدونم چرا (شاید بی ربط باشه حرفم)ولی این حرف شما منو یاد این واقعیت میندازه که هنوزم خیلی ها فکر میکنن (مرورگر ) اینترنت = "اینترنت اکسپلورر". حتی فکر میکنن که اینترنت اکسپلورر همیشه همون ورژن 6 بوده و هست و خواهد بود. بگذریم بهتره به بیراهه نریم و روی بحث تمرکز کنیم.

یک روال مشخص هست و اگر شما فکر می کنید اینجور نیست خوب برید بیشتر مساله را بشکافید
اگر زحمت می کشیدید یک خط کد می نوشتی می دیدی که جواب برابر ۲۴ خواهد شد هم gcc هم در ویژوال سی و هم در gcc. شما لطف کنید بگید که چرا ۲۴ می شه البته با منطق!نشد دیگه دوست من!. اگه قرار باشه من سوالی از شما بپرسم و شما بیای همون سوال رو از خود من بپرسی که نه چیزی من یاد میگیرم نه دردی از کسی دوا میشه. شما پست منو یه بار دیگه مطالعه بفرمایید. من پرسیدم: شما چطور 24 رو بدست آوردید؟(من نگفتم داخل ++C جواب 24 نمیشه). مشکل ما و در واقع سوال این تاپیک هم به همین موضوع اشاره داره . من روی کاغذ انجام میدم میشه 23.(x++ اول میشه 11 و x++ دوم هم میشه 12 که اگه جمع بزنیم میشه 23 ). درون سی شارپ هم مینویسم بازم خروجی 23 میشه ولی درون ++C خروجی 24 هست که به نظر من جواب سی شارپ منطقی هست.حالا سوال من از شما این بود که شما چطور حساب کردی که شد 24؟

linux
جمعه 05 آبان 1391, 21:04 عصر
با این حرفتون موافق نیستم. اعتقاد لزوما درباره مسائل دینی و مذهبی بکار نمیره. نمیدونم چرا (شاید بی ربط باشه حرفم)ولی این حرف شما منو یاد این واقعیت میندازه که هنوزم خیلی ها فکر میکنن (مرورگر ) اینترنت = "اینترنت اکسپلورر". حتی فکر میکنن که اینترنت اکسپلورر همیشه همون ورژن 6 بوده و هست و خواهد بود. بگذریم بهتره به بیراهه نریم و روی بحث تمرکز کنیم.
نشد دیگه دوست من!. اگه قرار باشه من سوالی از شما بپرسم و شما بیای همون سوال رو از خود من بپرسی که نه چیزی من یاد میگیرم نه دردی از کسی دوا میشه. شما پست منو یه بار دیگه مطالعه بفرمایید. من پرسیدم: شما چطور 24 رو بدست آوردید؟(من نگفتم داخل ++C جواب 24 نمیشه). مشکل ما و در واقع سوال این تاپیک هم به همین موضوع اشاره داره . من روی کاغذ انجام میدم میشه 23.(x++ اول میشه 11 و x++ دوم هم میشه 12 که اگه جمع بزنیم میشه 23 ). درون سی شارپ هم مینویسم بازم خروجی 23 میشه ولی درون ++C خروجی 24 هست که به نظر من جواب سی شارپ منطقی هست.حالا سوال من از شما این بود که شما چطور حساب کردی که شد 24؟
اگر این جمله را این جوری بنویسید


z=++x;
z+=++x;

جواب همان ۲۳ خواهد شد در سی ولی اتفاقی که می افتد در حالت اول و من اینطور حدس می زنم اول سمت راست + محاسبه میشه یعنی x++ که مقدار ۱۱ می گیرد بعد سمت چپ که مقدار ۱۲ می گیره بعد خود + محاسبه میشه یعنی الان x برابر ۱۲ شده ۱۲+۱۲ هم ۲۴ .

veniz2008
جمعه 05 آبان 1391, 21:20 عصر
من اینطور حدس می زنم اول سمت راست + محاسبه میشه یعنی x++ که مقدار ۱۱ می گیرد بعد سمت چپ که مقدار ۱۲ می گیره بعد خود + محاسبه میشه یعنی الان x برابر ۱۲ شده ۱۲+۱۲ هم ۲۴ .
من هر کاری میکنم نمیتونم منطق شما رو هضم کنم. مگه خودتون نمی گید 11 و بعدش 12 میشه؟. عملگر + هم که بنده خدا کارش فقط جمع زدن سمت راست و چپه (نه اضافه کردن به یکی از طرفین).

بعد خود + محاسبه میشه یعنی الان x برابر ۱۲ شده
عملگر + چطور میتونه یه واحد به مقدار 11 اضافه کنه و اونو 12 کنه؟

linux
جمعه 05 آبان 1391, 22:18 عصر
من هر کاری میکنم نمیتونم منطق شما رو هضم کنم. مگه خودتون نمی گید 11 و بعدش 12 میشه؟. عملگر + هم که بنده خدا کارش فقط جمع زدن سمت راست و چپه (نه اضافه کردن به یکی از طرفین).

عملگر + چطور میتونه یه واحد به مقدار 11 اضافه کنه و اونو 12 کنه؟
بحث infix و postfix اینها بود شاید به روشن شدن ذهن شما کمک کند. می دانید که برای محاسبه کردن و به اصطلاح پارز کردن این عبارت ریاضی این عبارت تبدیل به حالت postfix یا prefix می شود که کامپایلرها هر کدام از یکی از این دو روش استفاده می کنند.
یعنی اگر postfix این عبارت را بنویسیم بهتر می شه فهمید.
یعنی اگر اشتباه نکنم چیزی شبیه این خواهد بود


+ ++x++x

یعنی در سی اول عملگر ++ بر روی x اثر می کند، مقدارش به ۱۱ می رسد دوباره عملگر ++ بر روی x عملکرده مقدار ۱۱ به ۱۲ می رسد بعد عملگر + عملکرده و جواب حاصل ۲۴ خواهد بود.
برای تبدیل infix به postfix
http://scriptasylum.com/tutorials/infix_postfix/algorithms/infix-postfix/index.htm
برای محاسبه عبارت postfix
http://scriptasylum.com/tutorials/infix_postfix/algorithms/postfix-evaluation/index.htm

veniz2008
جمعه 05 آبان 1391, 22:46 عصر
+ ++x++x


فرض رو بر این می گیریم که کامپایلر سی طبق چیزی که شما گفتید عبارت رو پیمایش کنه. عملگر یکانی + (یا عملگر -) زمانیکه در ابتدای عبارت ظاهر بشن جنبه علامت دارن ( مثبت یا منفی بودن رو نشون میدن) نه اینکه به مقدار موجود اضافه یا کم کنن. بنابراین این حرف نمیتونه صحیح باشه که 23+ میشه 24!!!. مگر اینکه منظور شما چیز دیگه ای باشه.

linux
شنبه 06 آبان 1391, 00:30 صبح
فرض رو بر این می گیریم که کامپایلر سی طبق چیزی که شما گفتید عبارت رو پیمایش کنه. عملگر یکانی + (یا عملگر -) زمانیکه در ابتدای عبارت ظاهر بشن جنبه علامت دارن ( مثبت یا منفی بودن رو نشون میدن) نه اینکه به مقدار موجود اضافه یا کم کنن. بنابراین این حرف نمیتونه صحیح باشه که 23+ میشه 24!!!. مگر اینکه منظور شما چیز دیگه ای باشه.
این ویرایشگر چپ به راست و اینچیزها را قاطی نشان می دهد. از سمت راست می خواندی درست بود
postfix این عبارت اینجوری خواهد بود ایکس پلاس پلاس ایکس پلاس پلاس +
لینک ها را می خواندی بحث پستفیکس برات روشن می شد. روش محاسبه کمی با مدل infix فرق می کنه.
توضیح دادم که اتفاقی که می افتد این هست که اول عملگر افزایشی بر روی x اعمال می شود مقدار ۱۰ به ۱۱ تبدیل می شود در ادامه دوباره عملگر افزایشی(++) بر روی x اعمال شده مقدار ۱۲ را خواهد گرفت بعدش عملگر جمع اعمال می شود که مجموع x ها که مقداری برابر ۱۲ دارند را با هم جمع می کند که ۱۲ + ۱۲ =۲۴ خواهد شد.
حال سوال اینجاست که چرا سی شارپ اینجوری عمل نمی کند؟ ممکن هست سر تقدم عملگر افزایشی باشد که قبل یا بعد از عبارت قرار می گیرد. که بین سی و سی شارپ متفاوت هست!

Mahmoud.Afrad
شنبه 06 آبان 1391, 02:30 صبح
اول عملگر افزایشی بر روی x اعمال می شود مقدار ۱۰ به ۱۱ تبدیل می شود در ادامه دوباره عملگر افزایشی(++) بر روی x اعمال شده مقدار ۱۲ را خواهد گرفت بعدش عملگر جمع اعمال می شود که مجموع x ها که مقداری برابر ۱۲ دارند را با هم جمع می کند که ۱۲ + ۱۲ =۲۴ خواهد شد.
حال سوال اینجاست که چرا سی شارپ اینجوری عمل نمی کند؟ ممکن هست سر تقدم عملگر افزایشی باشد که قبل یا بعد از عبارت قرار می گیرد. که بین سی و سی شارپ متفاوت هست!

سلام

نمیدونم چطور شما مقدار 24 رو برای این عبارت بدست میارید؟!! یعنی میدونم ولی میخوام بگم منطق اشتباهی است.
میدونید چرا؟
چون با مقدار اولیه 10 در C#‎‎ مقدار 21 و در سی++ مقدار 20 بدست میاد.
دلیلش اینه که اگر از x++ در عبارتی استفاده بشه ابتدا مقدار عددی x در عبارت قرار میگیره و بعد متغیر x افزایش پیدا میکنه.


اگر تبدیل عبارات infix به عبارات postfix را در نظر بگیریم می دانیم محاسبه در زمان اجرا توسط پشته(stack) انجام میشه (در عبارات postfix اولویت ها رعایت میشه):


x=10

Infix
z = x++ + x++ ;

Postfix
x++ x++ +

حالا از سمت چپ به راست مقادیر(متغیرها و اعداد) در پشته ذخیره میشن و علامت ها روی عناصر بالای پشته اعمال میشن.
برای x++ اول ، از چپ به راست ابتدا مقدار x در پشته ذخیره میشه و بعد مقدار x افزایش پیدا میکنه:

پشته
10

متغیرها
x=11


حالا به x++ بعد می رسیم. باز هم از چپ به راست مقدار x به پشته و بعد افزایش x :

پشته
11
10

متغیرها
x=12


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

10+11 = 21

پشته
21

متغیرها
x=12


و به انتهای رشته postfix رسیدیم پس جواب در پشته است یعنی Z = 21 .

linux
شنبه 06 آبان 1391, 09:27 صبح
خوب! اینجوری میشه
اگر آن صفحه ای که نحوه محاسبه عبارت پستفیکس را نشان آموزش می دهد را یکبار دیگر مرور کنید می بینید که:
مقدار x=10 در پشه قرار می گیرد
عملگر ++ خوانده شده و بر روی x اعمال می گردد و مقدار x به ۱۱ افزایش پیدا می کند مقدار ۱۱ در پشته قرار می‌گیرد، در ادامه باز مقدار x که این بار ۱۱ هست فراخوانی شده در پشته قرار می گیرد الان در پشته دو مقدار داریم برابر ۱۱ باز عملگر ++ فراخوانی شده مقدار x دوم که ۱۱ بوده به ۱۲ افزایش پیدا می کند، این افزایش بر مقدار x قبلی هم اثر کرده و مقدار آن را نیز افزایش می دهد. الان در پشته دو عدد ۱۲ داریم ایندفه عملگر جمع فراخوانی می‌شود و دو مقدر ۱۲ را با هم جمع کرده و مقدار عبارت ۲۴ خواهد شد.
اشتباه شما اینجاست که خود عدد را در پشته قرار می دهید متغیر را در پشته قرار دهید.

در ابتدار
1-
پشته: x=10
عبارت = خالی
2-
پشته = خالی
عبارت => x++ = 11
پشته => x=11
عبارت = خالی
3-
پشته => x=11, x=11
عبارت خالی
-4
پشته => x=11
عبارت => x++ نتیجه عبارت مساوی 12
****چون مقدار x اینجا تغییر کرده در پشته هم مقدار x تغییر می کند و به ۱۲ افزایش پیدا می کند
پشته=> x=12,x=12
عبارت => خالی
-5
خواندن عملگر +
پشته= خالی
عبارت => x+x = 12+12=24
پشته => ۲۴
عبارت => خالی
مقادیر نهایی x=12 , z=24
امیدوارم مطلب روشن شده باشد

Mahmoud.Afrad
شنبه 06 آبان 1391, 16:55 عصر
خوب اینی که شما میگی اصلا صحیح نیست،
چون X++ مقدار X یعنی 10 در پشته قرار میگیره و بعد متغیر X افزایش پیدا میکنه ولی دیگه توی پشته نمیره چون x خودش حافظه داره. در اصل پشته برای مقدارهای عددی عبارت هست.
دلیل دیگر اشتباه بودن راه حل شما(که در اصل به خاطر اضافه کردن مقادیر بعد از ++ کردن به پشته هست) اینه که در انتها بیشتر از یک عدد در پشته باقی مونده در صورتی که در انتها باید یک عدد در پشته باشه.
سوم اینکه شما یکبار کدشو توی C# و سی++ امتحان کن ، هیچکدوم 24 نمیدن.

linux
شنبه 06 آبان 1391, 18:06 عصر
خوب اینی که شما میگی اصلا صحیح نیست،
چون X++ مقدار X یعنی 10 در پشته قرار میگیره و بعد متغیر X افزایش پیدا میکنه ولی دیگه توی پشته نمیره چون x خودش حافظه داره. در اصل پشته برای مقدارهای عددی عبارت هست.
دلیل دیگر اشتباه بودن راه حل شما(که در اصل به خاطر اضافه کردن مقادیر بعد از ++ کردن به پشته هست) اینه که در انتها بیشتر از یک عدد در پشته باقی مونده در صورتی که در انتها باید یک عدد در پشته باشه.
سوم اینکه شما یکبار کدشو توی C# و سی++ امتحان کن ، هیچکدوم 24 نمیدن.
دوست عزیز در استگ همان یک مقدار خواهد ماند که ۲۴ هست آن X را اضافه نوشتم تا بدانید مقدرا x در نهایت چی مشه در ++VC و GCC خروجی برابر ۲۴ خواهد بود
#include <stdio.h>

int main(void)
{
int x,y,z;
x=10;
y=3;
z=0;

z=++x + ++x;
printf("z=%d\n",z);
printf("X=%d\n",x);
int i;
scanf("%d",&i);

}
دوست عزیز این کد را در اجرا کنید خروجی را ببنید.

مرتضی تقدمی
شنبه 06 آبان 1391, 22:39 عصر
سلام
دوستان لطفا در مورد پیشوند و پسوند بحث نکنید. یک قانون ثابت و مشخصی داره که توی هر کتاب و منبعی گفته شده. بحث ما سر این موضوعه که چرا این دو زبانی که یکی بیس دیگری هست خروجی های متفاوتی روی این محاسبه میدن؟! چیزی که خود میکروسافت گفته در C# و C++ تفاوتی ندارن!

Mahmoud.Afrad
شنبه 06 آبان 1391, 23:36 عصر
دوست عزیز در استگ همان یک مقدار خواهد ماند که ۲۴ هست آن X را اضافه نوشتم تا بدانید مقدرا x در نهایت چی مشه در ++VC و GCC خروجی برابر ۲۴ خواهد بود
#include <stdio.h>

int main(void)
{
int x,y,z;
x=10;
y=3;
z=0;

z=++x + ++x;
printf("z=%d\n",z);
printf("X=%d\n",x);
int i;
scanf("%d",&i);

}
دوست عزیز این کد را در اجرا کنید خروجی را ببنید.

شما مثال آقای mohammaddou (http://barnamenevis.org/member.php?155296-mohammaddou) در این پست (http://barnamenevis.org/showthread.php?365637-%D8%AE%D8%B1%D9%88%D8%AC%DB%8C-%D9%87%D8%A7%DB%8C-%D9%85%D8%AA%D9%81%D8%A7%D9%88%D8%AA-%DB%8C%DA%A9-%D9%82%D8%B7%D8%B9%D9%87-%DA%A9%D8%AF-%D8%AF%D8%B1-C-%D9%88-C-!!&p=1616882&viewfull=1#post1616882) را اشتباه متوجه شدی . مثال ایشون ++ پسوندی بود ولی شما پیشوندی داری محاسبه میکنی.


سلام
دوستان لطفا در مورد پیشوند و پسوند بحث نکنید. یک قانون ثابت و مشخصی داره که توی هر کتاب و منبعی گفته شده. بحث ما سر این موضوعه که چرا این دو زبانی که یکی بیس دیگری هست خروجی های متفاوتی روی این محاسبه میدن؟! چیزی که خود میکروسافت گفته در C# و C++ تفاوتی ندارن!
بله درسته ربطی به سوال نداشت ولی خواستم ایشون متوجه اشتباهشون بشن.

Mahmoud.Afrad
یک شنبه 07 آبان 1391, 22:05 عصر
دلیلش رو متوجه شدم:

در سی شارپ مقادیر در عبارت همون لحظه جایگزین میشن یعنی اگر از چپ به راست پیمایش کنیم مقادیر با رسیدن به نام متغیر جایگذین و در انتها محاسبه صورت میگیره( یعنی مثل همون محاسبه دستی):
int x = 10, y = 3, z = 0;
z = x++ + ++x + y++ + ++x;
in C#‎: 10 + 12 + 3 + 13 = 38



ولی در سی++ همه عملگرهای تک عملوندی با اولویت بیشتر(مانند ++ پیشوندی) ابتدا روی متغیرهای مرتبط تاثیر میزارن و بعد جایگزین میشن:

بالاترین اولویت در این عبارت مربوط به ++ پیشوندی است پس همه ++های پیشوندی ابتدا روی متغیرها اعمال شده و در انتها جایگزین میشن. یعنی دو تا ++پیشوندی روی x اعمال شده و بعد نتیجه یعنی عدد 12 جایگذین هر دو ++x میشه:

z = x++ + 12 + y++ + 12
x = 12
y = 3

اولویت بعدی علامت جمع هست و بعد از اون ++پسوندی یعنی:
z = 12 + 12 + 3 + 12 = 39
x = 13
y = 4

veniz2008
دوشنبه 08 آبان 1391, 00:37 صبح
جالب بود. باتوجه به توضیحات دوستمون mafaman2003 که جواب هاش منطقی به نظر میرسن میتونیم به یکسری نتایج برسیم. در سی شارپ محاسبه براساس نظم و ترتیب قرار گرفتن متغیرها صورت میگیره و جواب هر بخش مستقل از بخش های دیگه است ( حتی اگر دو عبارت دقیقا مثل هم و یک اولویت داشته باشن) ولی در سی پلاس ابتدا متغیرها براساس اولویت هاشون دسته بندی میشن ( یه جور group by ) و به تعداد تکرارشون عمل مناسب بر روی اونها انجام میشه ولی جالب ترین قسمت اینه که نتیجه نهایی برای همه متغیرها یکسان در نظر گرفته میشه. فرض کنید میخوایم عبارت زیر رو با مقدار اولیه x = 10 محاسبه کنیم :

z = ++x + ++x + ++x;
در سی شارپ :

z = 11 + 12 + 13 که نتیجه میشه 36

در سی پلاس:

z = 13 + 13 + 13 که نتیجه میشه 39 یعنی اول میاد یه دسته بندی براساس اولویت میکنه بعد شروع میکنه به اضافه کردن. اول میشه 11 ، بعد میشه 12 و آخرش میشه 13 ولی مقدار نهایی یعنی 13 رو برای هر 3 در نظر میگیره.
این کار در سی پلاس از یه جهت میتونه منطقی و از یک جهت دیگه اشتباه باشه : منطقی از این نظر که چون هر 3 عبارت x++ در یک جمله اومدن (همزمان با هم به کار رفتن)بنابراین بایستی بصورت یکسان تحث تاثیر قرار بگیرن (شاید این مثال اشتباه باشه ولی مثل این میمونه که بگیم به تمام فیلدهایی که مقدارشون 10 هست سه واحد اضافه کنید!!! یعنی فرقی نداره که کدوم رکورد اول شامل 10 باشه مهم اینه که 10 باشه) ولی غیر منطقیش که بیشتر خودشو نشون میده به این خاطره که ما داریم بر روی "متغیرها" کار میکنیم و قرار نیست که یک متغیر در 3 جای متفاوت در یک جمله (حتی با اولویت یکسان) مقدار یکسان داشته باشه. این دقیقا مثل این میمونه که دو انسان نسبت به یک موضوع از دو نگاه متفاوت نگاه کنن. به نظر من منطق و نگاه سی شارپ قویتر هست. به نظر میرسه خود مایکروسافت هم تلویحا" پذیرفته که بهتره منطق محاسبه رو عوض کنه وگرنه قطعا دست به چنین تغییری نمیزد. به نظر شما کدوم روش منطقی تر هست؟