خوش آموز درخت تو گر بار دانش بگیرد، به زیر آوری چرخ نیلوفری را


آموزش زبان ++C : اولویت عملگرها (Operator precedence) و وابستگی (associativity)

آموزش زبان ++C : اولویت عملگرها (Operator precedence) و وابستگی (associativity)
نویسنده : امیر انصاری
در ریاضیات، یک عملیات (operation) یک محاسبه ریاضی می باشد که شامل صفر یا تعداد بیشتری ورودی - که این ورودیها عملوند (operands) نامیده می شوند - می باشد، که در نهایت یک مقدار خروجی را تولید می کند. عملیات های (operation) عمومی، مانند عملیات جمع، از نمادهای خاصی مانند + استفاده می کنند که معنای آن عملیات را نشان می دهند. این نمادها عملگر (operator) نامیده می شوند. عملگرها در برنامه نویسی به روش مشابهی مانند عملگرهای ریاضی کار می کنند، با این استثناء که عملگرها در برنامه نویسی همیشه یک نماد نمی باشند و ممکن است اسامی باشند. عملگرها (Operators) شبیه توابع (functions) کار می کنند، به این شکل که یک سری پارامتر ورودی را دریافت می کنند و مقداری را بر می گردانند، با این تفاوت که عملگرها (Operators) خیلی مختصرتر از توابع هستند. به عنوان مثال، خواندن عبارت

نرم افزار سامانه مودیان راهکار

4 + 2 * 3

بسیار ساده تر از خواندن عبارت


add(4, mult(2, 3))

می باشد.

برای اینکه به درستی بتوانیم یک عبارت (expression) مانند

4 + 2 * 3

را ارزیابی کنیم، نیاز داریم تا ابتدا درک درستی از کارکرد هر عملگر داشته باشیم و همینطور ترتیب اجرای عملگرها را نیز بدانیم. ترتیب اجرای عملگرها (Operators) که در یک عبارت (expression) پیچیده اعمال می شود، اولویت عملگرها (Operator precedence) نامیده می شود. اگر با قوانین معمولی ترتیب اجرای عملگرها در ریاضیات آشنا باشیم، طبیعتاً می دانیم که عملگر ضرب بر عملگر جمع اولویت دارد، در نتیجه عبارت بالا باید به صورت

4 + (2 * 3)

محاسبه شود و نتیجه 10 را تولید کند.

در زبان برنامه نویسی ++C هنگامی که کامپایلر (compiler) با یک عبارت (expression) مواجه می شود، به طور مشابهی باید آن عبارت را تجزیه و تحلیل کند و تعیین کند که چگونه باید آن عبارت را ارزیابی نماید. برای کمک به این رویه، تمامی عملگرها (Operators) دارای یک سطح از اولویت (precedence) می باشند. آن عملگرهایی که اولویت (precedence) بالاتری دارند، ابتدا ارزیابی می شوند. جدول زیر اولویت عملگرها (Operator precedence) در زبان برنامه نویسی ++C را نشان می دهد. شما می توانید در جدول ببینید که عملیات ضرب (multiplication) و تقسیم (division) در اولویت سطح 5 قرار دارند و نسبت به عملیات جمع (addition) و تفریق (subtraction) که در اولویت سطح 6 هستند، اولویت بالاتری دارند. هنگامی که کامپایلر با یک عبارت برخورد می کند از این اولویت ها (precedence) برای ارزیابی عبارت استفاده می کند.

بنابراین، عبارت

4 + 2 * 3

به

4 + (2 * 3)

ارزیابی می شود، چرا که عملیات ضرب (multiplication) نسبت به عملیات جمع (addition) اولویت (precedence) سطح بالاتری دارد.

اگر دو عملگر (operator) با سطح اولویت (precedence) یکسان در یک عبارت موجود باشند، قانون وایستگی (associativity) عملگر، به کامپایلر می گوید که آن عملگرها را از سمت راست به چپ (right to left) و یا چپ به راست (left to right) به ترتیب اولویت بدهد. برای مثال، در عبارت

3 * 4 / 2

اولویت عملگرهای ضرب و تقسیم، هر دو در سطح 5 قرار دارند. در اولویت سطح 5 قانون وایستگی (associativity) از سمت چپ به راست (left to right) می باشد، برای همین این عبارت از سمت چپ به راست ارزیابی می شود :

(3 * 4) / 2 = 6


جدول عملگرها (Operators)


نکات :

  • اولویت (precedence) سطح 1 بالاترین اولویت و سطح 17 پایینترین اولویت می باشند. عملگرهایی که اولویت بالاتری داشته باشند، ابتدا ارزیابی می شوند.

  • برای نمایش اینکه قانون وابستگی (associativity) از چپ به راست می باشد از نماد زیر استفاده شده است :

    L->R

  • برای نمایش اینکه قانون وابستگی (associativity) از راست به چپ می باشد از نماد زیر استفاده شده است :

    R->L


آموزش زبان ++C : اولویت عملگرها (Operator precedence) و وابستگی (associativity)
آموزش زبان ++C : اولویت عملگرها (Operator precedence) و وابستگی (associativity)
نکته : عبارتی که در میان عملگر شرطی :? قرار بگیرد، به مشابه پرانتز دار بودن آن ارزیابی می شود.

برخی عملگرهایی که قبلاً در ریاضیات با آنها آشنا شده اید، در زبان برنامه نویسی ++C نیز همان معنا را می دهند :

+, -, *, /, (), =, <, >, <=, and >=

این عملگرهای حسابی (arithmetic) و رابطه ای (relational) در ++C همان معنایی را می دهند که در استفاده روزمره معنا می دهند.

با این حال، احتمالاً اکثر عملگرهای موجود در این جدول، در حال حاضر برای شما قابل فهم نمی باشند. این مساله در این مرحله انتظار می رود و عادی می باشد. خیلی از آنها را در ادامه همین آموزش خواهید شناخت و بقیه هم در صورت نیاز معرفی خواهند شد.

جدول بالا در درجه اول قصد دارد تا به عنوان یک مرجع آموزشی برای شما باشد تا در آینده در صورت نیاز به مشاهده اولویت عملگرها (Operator precedence) و یا قوانین وابستگی (associativity) بتوانید به آن مراجعه کنید.

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

قانون : اگر عبارت شما دارای عملگرهای مختلفی می باشد، حتماً با استفاده از پرانتزها عبارت را روشن و واضح کنید، حتی اگر احساس نیاز به پرانتز نیز نمی کنید، باز هم سعی کنید تا از پرانتزها برای رفع ابهامات استفاده نمایید.

چگونه از توان (exponents) استفاده کنیم؟


ممکن است متوجه شده باشید که نماد توان ^ که به صورت عمومی در ریاضیات به معنای به توان رساندن می باشد، در زبان برنامه نویسی ++C معنای متفاوتی می دهد و دقیقاً معنای عملگر Bitwise XOR را دارد. در واقع زبان برنامه نویسی ++C عملگری برای توان (exponent) ندارد. برای اینکه در زبان برنامه نویسی ++C بتوانید از عملیات به توان رساندن استفاده کنید، ابتدا فایل هدر cmath را include کرده و سپس از تابع pow برای به توان رساندن استفاده نمایید.

#include "cmath"

double x = pow(3.0, 4.0); // 3 to the 4th power

توجه داشته باشید که پارامترهای ورودی و همینطور مقدار بازگشتی تابع pow از نوع داده double می باشد. همینطور توجه داشته باشید که اگر با خطاهای گرد کردن (rounding errors) اعداد ممیز شناور (floating point) در تابع pow برخورد کنید، نتیجه تولید شده توسط تابع pow دقیق نخواهد بود، و کمی کوچکتر یا بزرگتر از عددی که انتظار خواهید داشت، نتیجه ارائه می شود.

اگر می خواهید تا اعداد صحیح (integer) را به توان برسانید، بهتر است تا خودتان یک تابع اختصاصی برای این کار بنویسید، مانند کاری که در مثال زیر ما انجام داده ایم :

// note: exp must be non-negative
int pow(int base, int exp)
{
int result = 1;
while (exp)
{
if (exp & 1)
result *= base;
exp >>= 1;
base *= base;
}

return result;
}

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


آموزش قبلی : آموزش زبان ++C : ثابت های نمادین، Const و constexpr

آموزش بعدی : آموزش زبان ++C : عملگرهای ریاضی (Arithmetic operators)



نمایش دیدگاه ها (0 دیدگاه)

دیدگاه خود را ثبت کنید:

انتخاب تصویر ویرایش حذف
توجه! حداکثر حجم مجاز برای تصویر 500 کیلوبایت می باشد.