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


آموزش زبان ++C : لیترال ها (Literals)

آموزش زبان ++C : لیترال ها (Literals)
نویسنده : امیر انصاری
زبان برنامه نویسی ++C دو نوع ثابت (constants) دارد : لیترال (literal) و نمادین (symbolic). در این درس ما با لیترال ها (Literals) آشنا می شویم.

سیستم یکپارچۀ سازمانی راهکار



ثابت های لیترال (Literal constants)

ثابت های لیترال (Literal constants) که معمولاً فقط لیترال (literal) نامیده می شوند، مقادیری هستند که به صورت مستقیم در کد وارد می شوند. به این دلیل به این مقادیر ثابت (constant) گفته می شود که شما نمی توانید مقادیر آنها را تغییر بدهید. برای مثال :

bool myNameIsAlex = true; // boolean variable 'myNameIsAlex' is assigned is a boolean literal constant 'true'
int x = 5; // integer variable 'x' is assigned integer literal constant 5
std::cout << 2 * 3; // 2 and 3 are integer literals

در حالی که لیترال های (Literals) از نوع boolean و integer خیلی سرراست و ساده هستند، برای معرفی لیترال های (Literals) از نوع floating-point دو روش وجود دارد :

double pi = 3.14159; // 3.14159 is a double literal
double avogadro = 6.02e23; // avogadro's number is 6.02 x 10^23

در شکل دوم، عدد بعد از توان می تواند منفی نیز باشد :

double electron = 1.6e-19; // charge on an electron is 1.6 x 10^-19

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

آموزش زبان ++C : لیترال ها (Literals)
شما احتمالاً نیازی ندارید تا در مورد نوع داده integer از پسوندها استفاده کنید، اما در ادامه مثالی از آن آورده ایم :

unsigned int nValue = 5u; // unsigned int
long nValue2 = 5L; // long

به صورت پیش فرض، لیترال های (Literals) از نوع floating point نوع double دارند. برای اینکه آنها را به نوع داده float تبدیل کنیم، پسوند f یا F را می توانیم استفاده کنیم :

float fValue = 5.0f; // float
double d = 6.02e23; // double (by default)

همچنین زبان برنامه نویسی ++C از لیترال های (Literals) نوع داده char و نوع داده string نیز پشتیبانی می کند :

char c = 'A'; // 'A' is a char literal
std::cout << "Hello, world!" // "Hello, world!" is a C-style string literal
std::cout << "Hello," " world!" // C++ will concatenate sequential string literals

لیترال های (Literals) از نوع داده char همانطور که شما انتظار دارید، کار خواهند کرد. با این حال، لیترال های (Literals) از نوع داده string در زبان برنامه نویسی ++C به صورت عجیب و غریبی رفتار می کنند. در حال حاضر، بهتر است تا از لیترال های (Literals) از نوع string صرفاً برای چاپ متن توسط تابع std::cout استفاده کنید، اما سعی نکنید تا آنها را به متغیرها نسبت بدهید یا به توابع ارسال کنید، ممکن است کار نکنند و یا اینکه آنطور که شما انتظار دارید کار نکنند. ما در درسهای آینده در مورد C-style strings و چگونگی کار کردن با آنها توضیح خواهیم داد.

استفاده از لیترال ها (Literals) در داخل کدهای زبان برنامه نویسی ++C تا زمانی که معنی آنها واضح و روشن باشد خوب است. این مساله معمولاً شامل مواردی می شود که از لیترال ها (Literals) برای نسبت دادن یک مقدار به یک متغیر، انجام عملیات ریاضی و یا چاپ متن در صفحه نمایش استفاده می کنید.

لیترال های اکتال (Octal) و هگزادسیمال (hexadecimal)


در زندگی روزمره ما از اعداد دسیمال (decimal) که همان اعداد دهدهی (بر مبنای 10) می باشند برای شمارش استفاده می کنیم، در مبنای دهدهی هر کدام از ارقام می تواند 0 یا 1 یا 2 یا 3 یا 4 یا 5 یا 6 یا 7 یا 8 و یا 9 باشند. دسیمال (decimal) را مبنای 10 (base 10) نیز می نامند، چرا که در دسیمال (decimal) شما ده رقم ممکن (از 0 تا 9) را می توانید مورد استفاده قرار دهید. در سیستم دسیمال (decimal) ما به صورت زیر شمارش را انجام می دهیم.

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, …


به صورت پیش فرض اعداد موجود در زبان برنامه نویسی ++C به صورت دسیمال (decimal) مفروض می شوند.

int x = 12; // 12 is assumed to be a decimal number

در سیستم باینری (binary)، تنها دو رقم وجود دارند : 0 و 1، برای همین آن را مبنای 2 (base 2) می نامند. در سیستم باینری ما شمارش را به شکل زیر انجام می دهیم :

0, 1, 10, 11, 100, 101, 110, 111, …


دو نوع مبنای دیگر نیز وجود دارد که برخی وقتها در محاسبات مورد استفاده قرار می گیرند : اکتال (Octal) و هگزادسیمال (hexadecimal).

سیستم اکتال (Octal) مبنای 8 (base 8) می باشد، به این معنا که تنها 8 رقم در اختیار شما می باشد : 0 ، 1 ، 2 ، 3 ، 4 ، 5 ، 6 و 7 . در سیستم اکتال (Octal) ما شمارش را به صورت زیر انجام می دهیم :

0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, …


توجه داشته باشید که در شمارش ما ارقام 8 و 9 وجود نداشتند و ما مستقیماً از 7 به 10 رسیدیم.

آموزش زبان ++C : لیترال ها (Literals)
برای اینکه بتوانید از یک لیترال (literal) اکتال (Octal) استفاده کنید، آن را با پیشوند 0 آغاز کنید :

#include "iostream"

int main()
{
int x = 012; // 0 before the number means this is octal
std::cout << x;
return 0;
}

خروجی این برنامه :

10

چرا به جای 12 عدد 10 چاپ شد؟ دلیل این مساله اینست که اعداد در مبنای دسیمال (decimal) چاپ می شوند و عدد 12 در سیستم اکتال (Octal) برابر با عدد 10 در سیستم دسیمال (decimal) می باشد.

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

سیستم هگزادسیمال (hexadecimal) مبنای 16 (base 16) می باشد. در سیستم هگزادسیمال (hexadecimal) ما به شکل زیر شمارش را انجام می دهیم :

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, 12, …


آموزش زبان ++C : لیترال ها (Literals)
برای اینکه بتوانید از یک لیترال (literal) هگزادسیمال (hexadecimal) استفاده کنید، آن را با پیشوند 0x آغاز کنید :

#include "iostream>"

int main()
{
int x = 0xF; // 0x before the number means this is hexadecimal
std::cout << x;
return 0;
}

خروجی این برنامه :

15

از آنجایی که در یک عدد هگزادسیمال (hexadecimal) می تواند 16 مقدار متفاوت باشد، می توانیم بگوییم که یک رقم هگزادسیمال (hexadecimal) واحد، شامل 4 بیت می باشد. در نتیجه، یک جفت رقم هگزادسیمال (hexadecimal) می تواند یک بایت کامل را اشغال کند.

یک مقدار integer با اندازه 32 بیتی را در نظر بگیرید که مقدار زیر را داشته باشد :

0011 1010 0111 1111 1001 1000 0010 0110

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

3A7F 9826

این خلاصه نویسی منجر شده است تا مقادیر هگزادسیمال (hexadecimal) به عنوان یک روش مختصر نویسی برای ارائه مقادیر موجود در حافظه کامپیوتر مورد استفاده قرار بگیرند. به همین دلیل، از مقادیر هگزادسیمال (hexadecimal) معمولاً برای نمایش دادن آدرس های حافظه (memory addresses) و یا نمایش مقادیر خام (raw values) در حافظه استفاده می شود.

قبل از C++14 روشی برای نسبت دادن یک لیترال باینری (binary) وجود نداشت. با این حال، جفت های هگزادسیمال (hexadecimal) یک راهکار مفید را به ما ارائه می دادند.

#include "iostream"

int main()
{
int bin(0);
bin = 0x01; // assign binary 0000 0001 to the variable
bin = 0x02; // assign binary 0000 0010 to the variable
bin = 0x04; // assign binary 0000 0100 to the variable
bin = 0x08; // assign binary 0000 1000 to the variable
bin = 0x10; // assign binary 0001 0000 to the variable
bin = 0x20; // assign binary 0010 0000 to the variable
bin = 0x40; // assign binary 0100 0000 to the variable
bin = 0x80; // assign binary 1000 0000 to the variable
bin = 0xFF; // assign binary 1111 1111 to the variable
bin = 0xB3; // assign binary 1011 0011 to the variable
bin = 0xF770; // assign binary 1111 0111 0111 0000 to the variable

return 0;
}

لیترال های باینری در C++14 و جداکننده ارقام (digit separators)


در C++14 ما می توانیم با استفاده از پیشوند 0b لیترال های باینری را به متغیرها انتساب بدهیم :

#include "iostream"

int main()
{
int bin(0);
bin = 0b1; // assign binary 0000 0001 to the variable
bin = 0b11; // assign binary 0000 0011 to the variable
bin = 0b1010; // assign binary 0000 1010 to the variable
bin = 0b11110000; // assign binary 1111 0000 to the variable

return 0;
}

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

#include "iostream"

int main()
{
int bin = 0b1011'0010; // assign binary 1011 0010 to the variable
long value = 2'532'673'462; // much easier to read than 2532673462

return 0;
}

اگر کامپایلر شما از C++14 پشتیبانی نمی کند، این روش برای جدا کردن ارقام را قبول نخواهد کرد و شما با خطای کامپایلر مواجه خواهید شد.

اعداد جادویی (Magic numbers) و دلیل اینکه چرا آنها بد هستند


قطعه کد زیر را در نظر بگیرید :

int maxStudents = numClassrooms * 30;

عددی مانند عدد 30 در قطعه کد بالا را یک عدد جادویی (Magic number) می نامند. یک عدد جادویی (Magic number) عددی است که به صورت هارد کد (hard-coded) در بین کد آمده است و هیچ زمینه ای ندارد. معنای 30 چه می باشد؟ اگر چه شما احتمالاً ممکن است حدس زده باشید که عدد 30 در اینجا حداکثر تعداد دانش آموزان موجود در یک کلاس درسی می باشد، اما این مساله واضح و روشن نمی باشد. در برنامه های بزرگتر و پیچیده تر، حدس زدن اینکه معنای یک عددی که به صورت هارد کد (hard-coded) ارائه شده است چیست، بسیار مشکل می باشد، مگر اینکه در یک کامنت آن را توضیح داده باشید.

استفاده از اعداد جادویی (Magic numbers) به طور کلی به عنوان یک شیوه بد کد نویسی یاد می شود، علاوه بر اینکه زمینه آن تشریح نشده است، در مواقعی هم که نیاز به تغییر دادن آنها باشد ممکن است مشکلاتی پیش بیایند. فرض کنیم که مدرسه مربوطه بخواهد تعدادی میز تحریر جدید بخرد و تعداد دانش آموزان هر کلاس را از 30 به 35 برساند و برنامه ما نیز باید این مساله را پوشش بدهد. برنامه زیر را در نظر بگیرید :

int maxStudents = numClassrooms * 30;
setMax(30);

برای اینکه برنامه خود را بروز رسانی کنیم تا اندازه کلاس های جدید را پوشش بدهد، مجبوریم تا مقدار ثابت (constant) عدد 30 را به 35 تغییر بدهیم. اما در مورد فراخوانی تابع setMax چطور؟ آیا این عدد 30 هم همان معنا را می دهد؟ اگر اینطور باشد که خوب، باید آن را هم به 35 تغییر بدهیم. اگر هم آن عدد 30 معنای دیگری داشته باشد، طبیعتاً نباید آن را تغییر بدهیم و اگر تغییرش بدهیم برنامه ما دچار مشکل دیگری خواهد شد. اگر هم بخواهید با استفاده از قابلیت های یافتن و جایگزینی موجود در IDE خود به صورت اتوماتیک تر این کار را انجام بدهد، باز هم کار خطرناکی خواهد بود، چرا که ممکن است مقادیر دیگری را نیز به اشتباه تغییر بدهید. در این حالت، روش دقیق آنست که تک به تک کدهایی را که در آن عدد 30 بکار رفته است بررسی کرده و تعیین کنید که آیا آن عدد 30 باید به 35 تغییر یابد یا خیر. این روش علاوه بر زمان بر بودن، بسیار مستعد بروز خطا نیز می باشد.

خوشبختانه، گزینه بهتری با نام ثابت های نمادین (symbolic constants) وجود دارد. در درس بعدی در این باره بحث خواهیم کرد.

قانون : از اعداد جادویی (Magic numbers) در داخل کدهایتان استفاده نکنید.


آموزش قبلی : آموزش زبان ++C : نوع داده Char

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



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

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

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