اگه
a=10
a=++a + ++a
a=24
چطور این امکانپذیر میشه؟؟؟
اگه
a=10
a=++a + ++a
a=24
چطور این امکانپذیر میشه؟؟؟
راستش اولش منم یکم error دادم !!
مشکل ما اینه که فکر میکنیم حاصل رو به این صورت حساب میکنه :
a = 11 + 12
عملگر ++ نسبت به عملگر + اولویت داره. پس اول اون ++ ها انجام میشه بعد جمع. عملگر جمع برای جمع کردن 2 تا عملوندش میاد آدرس اون خونه ها رو ذخیره میکنه و بعدش میره از تو آدرس مقدارشونو میخونه و بعدش عمل + رو انجام میده. اینجا چون اول دوتا ++ ها انجام میشه مقدار a میشه 12. حالا میاد آدرس 2 تا عملگر جمع رو میخونه و میبینه که مقدار جفتشون 12 هستش. پس a = 12 + 12
تقریباً مطمئنم که اینجوریه اما 100% مطمئن نیستم ....
آخرین ویرایش به وسیله qwerty11 : یک شنبه 29 آذر 1388 در 22:45 عصر
مگه a++برابر 11 نيست؟
چرا ميگيد 12؟
چون دستور a++ دوبار اجرا میشه نه یکبارمگه a++برابر 11 نيست؟
چرا ميگيد 12؟
کد HTML:a = (++a) + (++a)
آخرین ویرایش به وسیله Microname : یک شنبه 29 آذر 1388 در 23:22 عصر
پس چرا این دستور مقدارش میشه 23 ؟عملگر ++ نسبت به عملگر + اولویت داره. پس اول اون ++ ها انجام میشه بعد جمع. عملگر جمع برای جمع کردن 2 تا عملوندش میاد آدرس اون خونه ها رو ذخیره میکنه و بعدش میره از تو آدرس مقدارشونو میخونه و بعدش عمل + رو انجام میده. اینجا چون اول دوتا ++ ها انجام میشه مقدار a میشه 12. حالا میاد آدرس 2 تا عملگر جمع رو میخونه و میبینه که مقدار جفتشون 12 هستش. پس a = 12 + 12
تقریباً مطمئنم که اینجوریه اما 100% مطمئن نیستم ....
int a=10;
a= (a=a+1) + (a=a+1) ;
سلام دوستان منم يه اضهار نظر كنم
int a=10;
a= (a=a+1) + (a=a+1) ;
a = (++a) + (++a
خوب دوستان اين دو تا دستور كاملا با هم ديگه فرق ميكنه (دوستان عزيز اگه اشتباه ميگم بگيد)
در اولين كد بايد بريم سراغ ژرانتز ها در اولين ژرانتز مقدار a+1 در a ذخيره ميشه يعني در ژرانتز اول a ميشه 11 و در پرانتز دوم دوباره مقدار a+1 در a ذخيره ميشه البته دقت كنيد a در ژرانتز دوم 11 هست و a جديد ميشه 12 و در كل 12 و 11 ميشه 23
اما در كد دوم شما بايد دوبار ++a رو انجام بديد و بعد با هم جمع كنيد و در a ذخيره كنيد كه در اينصورت a ميشه 12 , a در آخر ميشه 24
در این عبارت:
اول a++ حساب میشه متغییر a میشه 11کد HTML:a=++a + ++a
دوم a++ یک واحد به a که الان 11 هست اضافه میشه a الان میشه 12
خب a هست 12 حالا a+a چند میشه؟ این عبارت در حقیقت اینه:
a = a+ a
ولی دومی
در پرانتز اولی a میشه 11 (داخل پرانتز محاسبه شد:11 اسم فرضی برای حافظه میزاریم b=11)کد HTML:int a=10; a = (a=a+1) + (a = a+1)
در پرانتز دومی a همچنان یازده است و با محاسبه میشه 12 (داخل پرانتز شد 12، اسم فرضی برای حافظه میزاریم مثلا c =12 )
حالا جمعشان میشه 23 و در a قرار میگیره. عبارت رو اینجوری ببین:
a = b + c
اگه کمی در نحوه اختصاص حافظه تامل کنید حل میشه.
من هنوزم میگم که با آدرس کار میکنه !! وقتی که پرانتز میزارید کامپایلر میاد یه متغیر اضافی رو خودش در نظر میگیره، فارغ از اینکه داخلش چی هست !!int a=10;
a= (a=a+1) + (a=a+1) ;
ببخشید ولی اصلاً جوابتونو نفهمیدم !! چیزی که من از حرفای شما فهمیدم این بود که فقط میخواستین جواب آخر رو توجیه کنین ...خوب دوستان اين دو تا دستور كاملا با هم ديگه فرق ميكنه (دوستان عزيز اگه اشتباه ميگم بگيد)
در اولين كد بايد بريم سراغ ژرانتز ها در اولين ژرانتز مقدار a+1 در a ذخيره ميشه يعني در ژرانتز اول a ميشه 11 و در پرانتز دوم دوباره مقدار a+1 در a ذخيره ميشه البته دقت كنيد a در ژرانتز دوم 11 هست و a جديد ميشه 12 و در كل 12 و 11 ميشه 23
اما در كد دوم شما بايد دوبار ++a رو انجام بديد و بعد با هم جمع كنيد و در a ذخيره كنيد كه در اينصورت a ميشه 12 , a در آخر ميشه 24
چرا حالا توجيه؟
يه چيز واضحي مطرح شده كه دوستان دارن ساده تر توضيح ميدن
من توصيه ميكنم كسايي كه هنوز چيزي نفهميدن برن بخش اولويت هاي عملگر ها رو بخونن
بين ++ و + اولويت با ++ هست. حالا اگر ما 1000 تا از اين ++ داشته باشيم اول ++ صورت ميگيره و بعد +
حالا من يك سوال ميكنم
مقدار زير رو در صورتي كه a برابر 10 باشه بدست بياريد
a=++a + a++
چونکه دیدید 12 + 12 میشه 24 و خواستید یه جوری ربطش بدین دیگه
حالا این بحث ها به کنار. من رفتم این برنامه رو تو جاوا چک کردم و نتایج جالبی گرفتم نتیجه ی اخلاقی این بود که فهمیدم زبان C خیلی بیشتر از اون چیزی که من فکرشو میکردم مزخرفه !! این برنامه تو جاوا جواب 23 میده و اتفاقاً منطقی هم همینه. متاسفانه چیزی که تو زبان C زیاده باگه ... مهمترین اشکال زبان C همون اشاره گر هاش هستند که تو این مسئله هم یجورایی خودشون رو نشون میدن !! خلاصه اگه هر وقت تو زبان C جواب غیر عادی دیدین خیلی تعجب نکنین ...
اما خودتونو اصلا درگیر این چیزا نکنین چون اصلا مهم نیستن. دونستن تک تک این چیزا نیازمند اینه که دقیقا بدونین کامپایلرهای زبان های گوناگون برای به دست آوردن یه عبارت چه راهی رو انجام میدن، نحوه ی استفاده از متغیرها به چه صورته و خیلی چیزای دیگه که دونستنش خیلی لزوم نداره ...
اكثر تازه كار ها به چنين عقيده اي مي رسند، براي رهايي از اين بينش نا صحيح با سالها تحربه نياز داري ;)حالا این بحث ها به کنار. من رفتم این برنامه رو تو جاوا چک کردم و نتایج جالبی گرفتم نتیجه ی اخلاقی این بود که فهمیدم زبان C خیلی بیشتر از اون چیزی که من فکرشو میکردم مزخرفه !! این برنامه تو جاوا جواب 23 میده و اتفاقاً منطقی هم همینه. متاسفانه چیزی که تو زبان C زیاده باگه ... مهمترین اشکال زبان C همون اشاره گر هاش هستند که تو این مسئله هم یجورایی خودشون رو نشون میدن !! خلاصه اگه هر وقت تو زبان C جواب غیر عادی دیدین خیلی تعجب نکنین ...
اینکه من تازه کارم یا نه به کنار. ولی واقعا به نظر شما این زبان هیچ باگی نداره ؟؟ تو زبانی که میشه یه متغیر bool رو با یه متغیر int جمع کرد، دیگه حرفی از منطق و این چیزا دیگه نمیمونه !!
تو اینکه خیلی زبان سریعی هستش شکی نیست ولی این دلیل نمیشه بگیم بهترین زبانه و هیچ مشکلی نداره !
1- هم bool و هم int داراي مقدار هستند و مقادير قابل جمع!
2- حتي كلاس ها در C++ در صورت پياده سازي اين عملگر با هم قابل جمع كردند هستند
3- اينها باگ نيستند، رفتار هاي نا ملموس از نظر كساني كه با زبان هاي ديگري كار كرده اند هستند
1- از کی تا حالا سیب رو میشه با گلابی جمع کرد ؟؟ عبارت بولی عبارتیه که یا درسته یا نادرست. حالا تعریف عبارت درست + int چی میتونه باشه ؟؟
2- خوب این هم از شاهکارهای c هستش
3- مطمئن باش اگه بیشتر از تو با c کد ننوشته باشم (که مطمئنم بیشتر نوشتم) کمتر هم ننوشتم !! اتفاقا به نظر من این نوع حرف زدن شما رفتار کسانیه که هیچ زبان دیگه ای غیر از c رو ندیدن !!
شما مدام از c حرف مي زنيد، گمان مي كنم منظور شما C++ باشد، C نوع bool ندارد!
در c به جاي bool از تعريف int استفاده مي شود!
استدلال به غير!!!از کی تا حالا سیب رو میشه با گلابی جمع کرد ؟؟
اما براي پاسخ بايد عرض كنم 2 سيب با اضافه 3 گلابي مي شود 5 ميوه!
خير، عبارت بولي عبارتيه كه اگر مقدار 0 داشته باشه به نادرست و در ساير موارد به درست تعبير ميشه.عبارت بولی عبارتیه که یا درسته یا نادرست.
چه خوب، پس مي تونيم از معلوماتتون استفاده كنيممطمئن باش اگه بیشتر از تو با c کد ننوشته باشم (که مطمئنم بیشتر نوشتم) کمتر هم ننوشتم !! اتفاقا به نظر من این نوع حرف زدن شما رفتار کسانیه که هیچ زبان دیگه ای غیر از c رو ندیدن !!
O0oh خوب شد گفتی c نوع داده ی bool نداره ! نمیدونستم !! c و C++ تو یه خونواده ان !! اینو دیگه فکر کنم شما هم بدونی !! منظور من کلاً c و مشتقاتش بود ...
این تعریفیه که c واسه عبارت بولی ابداع کرده !! به نظر من این کاملاً واضحه که عبارتی مثل : int i = 10 + true کاملا بی معنیه ...خير، عبارت بولي عبارتيه كه اگر مقدار 0 داشته باشه به نادرست و در ساير موارد به درست تعبير ميشه.
این همه آدم اومدن گفتن زبان c باگ داره شما قبول نکردی ! حالا میخوای از معلومات من استفاده کنی ؟؟ ولی به هر حال من مشکلی ندارم. هر کمکی که از دستم بر میاد حاضرم برات انجام بدم ... میتونی رو کمک من حساب کنیچه خوب، پس مي تونيم از معلوماتتون استفاده كنيم
خير!c و C++ تو یه خونواده ان !!
دو ماهيت مستقل از هم هستند و به صورت جداگانه رشد مي كنند.
true يك ثابت تعريف شده است، نه چيزي بيشتر.این تعریفیه که c واسه عبارت بولی ابداع کرده !! به نظر من این کاملاً واضحه که عبارتی مثل : int i = 10 + true کاملا بی معنیه ...
در مقابل اون همه آدم دارند با اين زبان سيستم عامل، درايور، برنامه كاربردي و ... مي نويسند، جالبه اونا صداشون در نيومده اما شما ها به پرباگ بودن اين زبان پي برديد!!!این همه آدم اومدن گفتن زبان c باگ داره شما قبول نکردی !
خوب عزیز شما با اون کامپایلر که کار میکنید مگر برای bool چه مقدار از حافظه رو میگیره یه تحقیق کوچیک انجام بده خواهید فهمید که همان یک بایت اندازه داره پس لزومی نداره که معنی عبارت bool را چیزی جز یک بایت از حافظه در نظر بگیرید.این تعریفیه که c واسه عبارت بولی ابداع کرده !! به نظر من این کاملاً واضحه که عبارتی مثل : int i = 10 + true کاملا بی معنیه ...
ولی در مورد زبان c شما نباید به یک جمله یا دستوری که جوابش با تعاریف شما سازگاری ندارید بگید bug دارد بلکه هر زبانی احتیاج به عادت و رفتار برنامه نویس به کامپایلر دارد یعینی قبول کند که این نوع محاسبه توسط این کامپایلر به این صورت تحلیل میشود در غیر اینصورت محاسبه چیز دیگری خواهد شد.
شما که تو زبان C یا C++ نمی تونی جواب یک عبارت ساده رو بدست بیاری چطوری میگی خیلی با C کد نوشتی اگه یک ساختمان داده و طراحی و پیاده سازی زبانها خونده بودی از این حرفا نمی زدی فکر کنم مدرک شما بیشتر از کاردانی نباشه؟ درسته چون اگه با ساختمان داده و به خصوص با درس طراحی پیاده سازی درست آشنا شده باشی و خونده باشی نه برای نمره اونوقت به حرفای خودت خندت میگره
نکنه فکر کردی من c رو ابداع کردم که باید از همه چیش سر در بیارم !! نه جداً همچین فکری کردی ؟؟ این شماهایین که باید جوابی که c به این سوال میده رو توجیه کنین !! واقعا جالبه که عبارتهای زیر تو c جواب جداگونه دارن !!شما که تو زبان C یا C++ نمی تونی جواب یک عبارت ساده رو بدست بیاری چطوری میگی خیلی با C کد نوشتی اگه یک ساختمان داده و طراحی و پیاده سازی زبانها خونده بودی از این حرفا نمی زدی فکر کنم مدرک شما بیشتر از کاردانی نباشه؟
a = ++a + ++a ;
a = (a=a+1) + (a=a+1)
اگه بخواین اون دومی رو به خاطر وجود پرانتز توجیه کنین، این 2تا پایینی رو چی میگین ؟؟a = a + ++a;
a= (a) + ++aدر ضمن اینکه مدرک من چیه و چه درسایی رو پاسیدم چه درسایی رو نه به شما هیچ ربطی نداره. فقط همین قدر بهت میگم که تو همون درس طراحی و پیاده سازی بسیاری از معایب این زبان شمرده شده !!
جواب قسمت اول حرفت رو اون بالا دادم ! ولی جداً جات خالی !! از امروز صبح کلی به حرفای شماها خندیدیم !! اصلا باورم نمیشه کسایی پیدا بشن که بگن c هیچ مشکلی نداره !! اما خوب مثل اینکه به دانشجوهای کاردانی که شما باشین جور دیگه ای درس میدن.درسته چون اگه با ساختمان داده و به خصوص با درس طراحی پیاده سازی درست آشنا شده باشی و خونده باشی نه برای نمره اونوقت به حرفای خودت خندت میگره
آخرین ویرایش به وسیله qwerty11 : دوشنبه 30 آذر 1388 در 17:35 عصر
هیچ فرقی ندارند هر دوتا جواب میشه 22!کد HTML:a = a + ++a; a= (a) + ++a
معلومه که فرقی نمی کنه چون عملیاتی رویش انجام ندادید که بخواد تغییر کنه!اونوقت چرا اون 2تای بالایی یکیش میشه 24 و یکیش هم میشه 23 ؟؟
فقط خوشگل شده رفته داخل پرانتز!
ولی اون دوتای بالا متغییر اصلیمان عوض میشه!
دوستان عزیز، لطفاً اینجا رو تبدیل به محل مناقشات شخصی خودتون نکنید.
جناب qwerty11، با اینکه بنده خودم پاسکال کار میکنم و بالطبع توی دعوای همیشگی برنامه نویسها که به به و چه چه کردن از زبان مورد استفاده خودشون و تخطئه کردن زبانهای دیگه می پردازند منم اینکارو میکنم ولی الحق و الانصاف تنها چیزی که نمیتونم بهش گیر بدم نوآوری هست که با معرفی زبان C ارائه شد. شما حلقه for زبان C رو در نظر بگیرید. قدرتی که این دستور داره و طراحی فوق العاده ای که پشت اون هست به هیچ وجهی قابل انکار نیست. اینکه شما می فرمائید چرا نوع بولین با int جمع میشه یکی از دلایل اصلیش اینه که طراح زبان تا اونجا که امکان داشته سعی کرده سرعت زبان رو زیاد کنه و قابلیت انعطاف به اون بده. خیلی زبانهای کمی پیدا میشن که قابلیت کار با بیتها رو داشته باشند(منظورم اینه که شما بتونید مثلاً عدد یک رو توی 1 بیت ذخیره کنید) چرا؟ چون زبان C هدفش اینه که تا حد ممکن به سخت افزار هم نزدیک باشه(علاوه بر راحتی استفاده). یا مثلاً توی این زبان بازه آرایه ها چک نمیشه. شما نمیتونید ادعا کنید که عجب چیز بدیه. مثلاً پاسکال خوبه که چک میکنه. خود همین چک کردن بازه (بوسیله دستورات اضافه شده توسط کامپایلر) سرعت رو کند میکنه.
پس هر زبانی برای یک هدف خاصی طراحی میشه. بنظر من زبان C واقعاً گرامر خارق العاده ای داره. و همچنین قابلیت های بسیار جالبی.
این هم یک باگ نمیتونه باشه. باید از کسی پرسید که از مستندات زبان به اندازه زبان به اندازه کافی اطلاعات داشته باشه. شاید در مستندات زبان یک روش اجرای خاص برای عملگر ++ در نظر گرفته شده باشه. هدف ما هم همینه که یه نفر که این اطلاعات رو داره بهمون کمک کنه. نه اینکه بخواهیم اطلاعاتمون رو به رخ هم بکشیم. وگرنه مطمئناً هرکسی میتونه یه سری اطلاعات داشته باشه که یه نفر دیگه اونها رو نداشته باشه.
من سوال رو دوباره مطرح میکنم. امیدوارم تاپیک دوباره به بحث اولیه برگرده، ممنون
چرا جواب اولی 24 و جواب دومی 23 میشه ؟
1) int a=10
a=++a + ++a;
2) int a=10;
a=(a=a+1) + (a=a+1);
آخرین ویرایش به وسیله esmit61 : سه شنبه 01 دی 1388 در 17:02 عصر
برای اینکه کامپایلر اینگونه تحلیل کاری دارد!!!
1) int a=10
a=++a + ++a;
این تحلیل کامپایلر هست
مرحله اول
a = (++) + (++) ->> a += 1+1 -> a += 2 -> a = 12;
مرحله دوم
a = a + a -> 12+12
2)
int a=10;
a=(a=a+1) + (a=a+1);
تحلیل
a = (11=10+1)+(12=11+1) = 23
آخرین ویرایش به وسیله tdkhakpur : دوشنبه 30 آذر 1388 در 20:09 عصر دلیل: املا
ممنون. ولی با عرض معذرت من متوجه نشدم (چگونگی انجام روش اول رو).
اگه ممکنه تفاوت این دو روش رو توضیح بدید.
باز هم ممنون.
a = ++a + ++a; // ++a; (OR) a = 10 + 1 = 11;
a = a + ++a; // ++a; (OR) a = 11 + 1 = 12;
a = a + a; // a = 12 + 12; (OR) a = 24;
a = (a = a+1) + (a = a+1); // a = a + 1 = 11;
a = 11 + (a = a+1); // a = a + 1 = 12;
a = 11 + 12 = 23;
آخه سوال اینه که چرا C اینجوری عمل میکنه؟ یعنی فقط برای ++ (و احتمالاً --) اینجوریه؟
تفاوت توی سطر سومه. مگه برای عملگر جمع عملوندها توی پشته push نمیشن ؟
کسی میتونه بگه چرا C از این روش استفاده میکنه ؟
یه چیزی. من همین الان امتحان کردم حاصل عبارت دوم هم 24 شد! البته تو ++C. یعنی با C فرق داره؟
a = 10 ;
a = a++ + a++ =22;
a=10;
a = ++a + ++a =24 ;
a=10;
a = (a=a+1) + (a=a+1) =23;
a=10;
a = (++a)+ ++a=24;
علتش تو ++ و -- هستش. X++ يعني اول x يه واحد اظافه بشه ، بعد در محاسبه شرکت کنه. ولي ++X يعني اول x تو محاسبات شرکت کنه، بعدش يه واحد اظافه بشه.
تو مورد چهارم هم ، دربخش دومش ، چون a++ اومده ، مقداري که ++a قرار بوده بعد از محاسبات در a قرار بده ، همون موقع در a قرار داده شده.
اين برنامه اجرا شدش:
من با C++ Builder تست کردم همون 23 شد !یه چیزی. من همین الان امتحان کردم حاصل عبارت دوم هم 24 شد! البته تو ++C. یعنی با C فرق داره؟
دوست عزیز، اینو همه میدونن. سوال اینه که طبق حرف شما هم باید جواب دومی بشه 23 نه 24 !علتش تو ++ و -- هستش. X++ يعني اول x يه واحد اظافه بشه ، بعد در محاسبه شرکت کنه. ولي ++X يعني اول x تو محاسبات شرکت کنه، بعدش يه واحد اظافه بشه.
تو مورد چهارم هم ، دربخش دومش ، چون a++ اومده ، مقداري که ++a قرار بوده بعد از محاسبات در a قرار بده ، همون موقع در a قرار داده شده.
عجب موضوع جالبی شده ها !
طبق توضیح من جواب دومی میشه 24 نه 23 یه بار دیگه ببین:اینو همه میدونن
اول ++ روحساب میکنه ، بعد متغیر رو درمحاسبه قرار میدههمچنین سومی میشه 23 :
0) a= ++a + ++a
1) a+=1 =>a=11
2) a+=1 =>a=12
3) a= 12 + 12 = 24
اول متغیر رو درمحاسبه قرار میده بعد + میکنهالآن مشکلت چیه ؟
0) a=(a+1) + (a+1)
1) a= 11 + (a=a+1)
2) a= 11 + 12
=23
بچه ها دعوا نکنید ، مشکل از کامپایلریه که استفاده میکنید
من تو ویژوال استودیو واسه این دوتا کد یه جواب گرفتم :
(a+=1) + (a+=1)
++a + ++a
اگه a=10 باشه تو هردو حالت میده 24 ؛ حالا شاید کامپایلرهای دیگه جواب های متفاوتی بدند
ممکنه در مورد این هم توضیح بدین
c برابر با 18 میشه.چرا؟؟؟
int c=4,i=2,e=4;
++c=C++ + ++i + e++ + ++c;
چون رفتار چنین عبارتهایی در استاندارد زبان ++C تعریف نشده است به نقل از خالق زبان ++C
و این یک باگ نیست. طراح زبان به خاطر performance، بعضی از رفتارها را undefined تعریف کرده است و تصمیمگیری در رابطه با آن، بر عهده Compiler است.
اینطور میشه توجیه کرد :
1_ اول سمت راست محاسبه میشه
2_ بعد در سمت چپ قرار داده میشه
3_ بعد سمت چپ محاسبه میشه
و این دستور هم هست :
1_ اول ++x اجرامیشه بعد در عبارت قرار داده میشه
2_ اول در عبارت قرار داده میشه بعد x++ حساب میشه
پس میشه ::
اول طرف راست حل میشه :
1_ اول ++c حل میشه : c=5 بعد c در عبارت سمت راست جایگزین میشه
2_ بعد ++i اجرا میشه و بعد در عبارت قرار داده میشه i = 3
3_بعدش عبارت سمت راست حل میشه : c = 5 + 3 + 4 + 5 = 17
4_ بعد e++ محاسبه میشه : e = 5
آخرش سمت چپ حساب میشه
1 _ ++c ==> c=18
ولی من فکر میکنم اینجوری بشه
6+4+3+4=17
17+1=18=c
c=4 بعد++c=cکه 5 میشه
بعد i++ میشه3
e=4
بعدشمC++میشه 6
باهم جمع ميشه ميشه 17 بعدم يكي بهش اضافه ميشه و قرار ميديم توي c