PDA

View Full Version : عبارت محاسباتی



star462
یک شنبه 22 دی 1387, 19:51 عصر
سلام
میشه برای من توضیح بدین چرا جواب عبارت زیر وقتی کامپایل میکنم 5 میشه از نظر من جواب باید 9 باشه . من با tcc کامپایل کردم




int a=6, b=2 ,c=1, d=12;
if (c++)
d=a++*b/c*b++-++c ;
cout<<d;

Saeed_m_Farid
یک شنبه 22 دی 1387, 23:21 عصر
سلام
میشه برای من توضیح بدین چرا جواب عبارت زیر وقتی کامپایل میکنم 5 میشه از نظر من جواب باید 9 باشه . من با tcc کامپایل کردم




int a=6, b=2 ,c=1, d=12;
if (c++)
d=a++*b/c*b++-++c ;
cout<<d;
چون اول c++ كه آخرين جمله تون هست اجرا ميشه بعد از اول محاسبات انجام ميشه!
يعني d=6*2/3*2-3

موفق باشيد.

star462
دوشنبه 23 دی 1387, 08:18 صبح
مرسی
ولی میشه بیشتر توضیح بدین؟!
توی همه ی عبارات از سمت راست شروع میکنیم؟
یا اینکه به خاطر c++ این جوری شده؟
مرسی

Saeed_m_Farid
دوشنبه 23 دی 1387, 12:40 عصر
یا اینکه به خاطر c++ این جوری شده؟
این یا اینکه تون درسته : عملگرهای پیش پردازشی (بهتر از این ترجمه ای نیافتم) قبل همه چی اعمال میشن.

pars.engineer
دوشنبه 23 دی 1387, 13:00 عصر
من پاسخ واضحي در اين زمينه پيدا نكرده ام.
در كتاب برنامه نويسي C آقاي رضواني گفته شده است كه اينطور عباراتي كه درون خود نيز عبارات محاسباتي دارند از چپ به راست محاسبه مي شوند.(ولي من براي اين گفته مثال نقض پيدا كردم).
و همچنين نوشته بود كه در عباراتي كه كاما وجود دارد كامپايلر عبارت را از چپ به راست مي خواند.
ولي در اين مورد نيز مثال نقض وجود دارد. مثلا:



int i,j,k,L;
L=(i=3,j=i+2,i+0,k=i+j,k++);



i=0 , j=5 , k=6, L=5
موفق باشيد.

Nima_NF
دوشنبه 23 دی 1387, 15:09 عصر
کلا استفاده از عملگر های ++ و -- وقتی در هر دو حالت prefix و postfix در یک عبارت (خط / جمله) استفاده می شوند، جواب قطعی دریافت نخواهید کرد.

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

در یک کلام، سعی کنید همیشه از انواع مختلف آن ها در یک عبارت استفاده نکنید تا نتایج عجیب (و گاها خطرناک) دریافت نکنید و آن را به قسمت های مختلف تقسیم کنید.

این مورد زیر منطقی هست:



َx = A++ / B++;


مثلا به مورد ساده زیر توجه کنید، بهتر هست آن را جداگانه بنویسید (البته این مورد ساده هست و منظور فقط تذکر هست تا برای عبارت های بزرگ تر این عمل انجام شود):



x = ++A / B++ ;

این طور بنویسید (البته اگر من جای شما بودم ++B را نیز جهت خوانایی جداگانه می نوشتم):



++A;
x = A / B++;

or
++A;
x = A / B;
B++;

pars.engineer
دوشنبه 23 دی 1387, 22:07 عصر
آقاي Nima_NF ممنونم از پاسختون.
ولي كلا از اين مشكلات در اكثر زبانهاي برنامه نويسي و در كل كامپيوتر موجود است.
مثل استفاده از نوع هاي داده اي Float و Double در ‍C,C++,C# , SQL Server و Real در پاسكال (كه به دليل نحوه انجام محاسبات در CPU ) كه حتما برايتان پيش آمده كه در برخي اوقات جوابهاي واقعا خطرناكي مي دهند.
البته دات نت و SQL Server نوع Decimal را عرضه كرده اند كه از نظر محاسبات خيلي دقيق تر است ولي فضاي بيشتري نياز دارد.

star462
سه شنبه 24 دی 1387, 12:04 عصر
ممنون که جواب دادین
من گرفتم چی شد :لبخندساده: