انواع متغير ها در ++C و نحوه بهکارگيری آنها
جلسه دوم آموزش برنامه نویسی سی پلاس پلاس به معرفی انواع متغير ها در ++C و نحوه بهکارگيری آنها در برنامهها اختصاص دارد. انتظار میرود پس از پايان اين جلسه بتوانيد انواع عددی صحيح و انواع عددی مميز شناور در ++C را نام ببريد و متغيرهايی از اين نوعها را در برنامهها به کار ببريد. نوع بولين را تعريف کرده و متغيرهايی از اين نوع را در برنامهها به کار ببريد. نوع شمارشی را شناخته و متغيرهايی از اين نوع را در برنامهها به کار ببريد. مفاهيم «تبديل نوع» و «گسترش نوع» را شناخته و انواع مختلف را به يکديگر تبديل نماييد. علت خطاهای «سرريزی عددی» و «گرد کردن» را دانسته و بتوانيد محل وقوع آنها را کشف کنيد. عملگرهای حسابی و افزايشی و کاهشی و مقدارگذاری مرکب را در برنامهها به کار ببريد.
مقدمه
ما در زندگی روزمره از دادههای مختلفی استفاده میکنيم: اعداد، تصاوير، نوشتهها يا حروف الفبا، صداها، بوها و غیره. با پردازش اين دادهها می توانيم تصميماتی اتخاذ کنيم، عکسالعملهايی نشان دهيم و مسالهای را حل کنيم. کامپیوترها نيز قرار است همين کار را انجام دهند. يعنی دادههايی را بگيرند، آنها را به شکلی که ما تعيين میکنيم پردازش کنند و در نتيجه اطلاعات مورد نيازمان را استخراج کنند. در ادامه انواع متغير ها در ++C مورد تشریح قرار می گیرند.
انواع داده عددی
در ++C دو نوع اصلی داده وجود دارد: «نوع صحيح» و «نوع مميز شناور». همۀ انواع ديگر از روی اين دو نوع ساخته می شوند (به شکل زير دقت کنيد).
نوع صحیح
نوع صحيح برای نگهداری اعداد صحيح (اعداد 0 و 1 و 2 و …) استفاده می شود. اين اعداد بيشتر برای شمارش به کار می روند و دامنه محدودی دارند.
متغير عدد صحيح
انواع متغير ها در ++C شش نوع متغير عدد صحيح دارد تفاوت اين شش نوع مربوط به ميزان حافظۀ مورد استفاده و محدودۀ مقاديری است که هر کدام می توانند داشته باشند. اين ميزان حافظۀ مورد استفاده و محدودۀ مقادير، بستگی زيادی به سختافزار و همچنين سيستم عامل دارد. يعنی ممکن است روی يک کامپیوتر، نوع int دو بايت از حافظه را اشغال کند در حالی که روی کامپیوتر از نوع ديگر نوع int به چهار بايت حافظه نياز داشته باشد. وقتی برنامهای مینويسيد، توجه داشته باشيد که از نوع صحيح مناسب استفاده کنيد تا هم برنامه دچار خطا نشود و هم حافظۀ سيستم را هدر ندهيد.
محاسبات اعداد صحيح
++C مانند اغلب زبانهای برنامهنويسی برای محاسبات از عملگرهای جمع (+) ، تفريق (-) ، ضرب (*) ، تقسيم (/) و باقيمانده (%) استفاده می کند.
عملگرهای افزايشی و کاهشی
زبان برنامه نویسی ++C برای دستکاری مقدار متغيرهای صحيح، دو عملگر جالب ديگر دارد:
عملگر ++ : مقدار يک متغير را يک واحد افزايش ميدهد.
عملگر — : مقدار يک متغير را يک واحد کاهش ميدهد.
اما هر کدام از اين عملگرها دو شکل متفاوت دارند: شکل «پيشوندی» و شکل «پسوندی».
در شکل پیشوندی، عملگر قبل از نام متغير می آيد مثل m++ يا n– . در شکل پسوندی، عملگر بعد از نام متغير می آيد مثل ++m يا –n . در شکل پيشوندی ابتدا متغير، متناسب با عملگر، افزايش يا کاهش میيابد و پس از آن مقدار متغير براي محاسبات ديگر استفاده میشود. در شکل پسوندی ابتدا مقدار متغير در محاسبات به کار میرود و پس از آن مقدار متغير يک واحد افزايش يا کاهش میيابد. به مثال زیر توجه کنید.
int main() { int x=10; int y=10; cout << "x++ is : " <<x++; cout<<endl; cout << "++y is : " <<++y; return 0; }
پس از اجرای برنامه بخوبی متوجه خواهید بود که چه فرقی بین شکل پیشوندی و پسوندی وجود دارد. ما در کد بالا به هر دو متغیر x و y مقدار یکسان 10 را داده ایم. برای چاپ کردن هر کدام ابتدا ++x را چاپ می کنیم. در اینجا عدد 10 برای ما چاپ می شود و سپس 1 واحد x افزایش می یابد. ولی در مورد y ابتدا این متغیر یک واحد افزایش پیدا می کند سپس چاپ می شود یعنی عدد 11.
عملگرهای مقدارگذاری مرکب
در ++C عملگرهای ديگری دارد که مقدارگذاری در متغيرها را تسهيل مینمايند. مثلا با استفاده از عملگر =+ میتوانيم هشت واحد به m اضافه کنيم اما با دستور کوتاهتر:
;m += 8
دستور بالا معادل دستور ;m = m + 8 است با اين تفاوت که کوتاهتر است. به عملگر =+ «عملگر مرکب» میگويند زيرا ترکيبی از عملگرهای + و = ميباشد. قبلاً از عملگر = برای مقدارگذاری در متغيرها استفاده کرديم. ++C عملگرهای ديگری دارد که مقدارگذاری در متغيرها را تسهيل مینمايند. عملگر مرکب در C++ عبارتند از: =+ و =- و =* و =/ و =% که نحوه عملکرد آنها بصورت زیر است. (معادل هر عبارت)
m += 8; → m = m + 8
m -= 8; → m = m – 8
m *= 8; → m = m * 8
m /= 8; →m = m / 8
m %= 8; →m = m % 8
انواع مميز شناور
در ادامه بحث انواع متغير ها در ++C به مبحث اعداد ممیز شناور میرسیم. عدد مميز شناور به بيان ساده همان عدد اعشاری است. عددی مانند 123.45 يک عدد اعشاری است. برای اين که مقدار اين عدد در کامپیوتر ذخيره شود، ابتدا بايد به شکل دودويی تبديل شود:
123.45 = (1111011.0111001)2
اکنون برای مشخص نمودن محل اعشار در عدد، تمام رقمها را به سمت راست مميز منتقل ميکنيم. البته با هر جابجايی مميز، عدد حاصل بايد در توانی از 2 ضرب شود:
123.45 = 0.11110110111001× 27
به مقدار 11110110111001 «مانتيس عدد» و به 7 که توان روی دو است، «نمای عدد» گفته می شود. در سی پلاس پلاس ++C سه نوع ممیز شناور داریم.
- معمولا نوع float از چهار بايت براي نگهداری عدد استفاده مِی کند.
- نوع double از هشت بايت برای نگهداری عدد استفاده می کند.
- نوع long double از هشت يا ده يا دوازده يا شانزده بايت برای نگهداری عدد استفاده می کند.
تعريف متغير مميز شناور
تعريف متغير مميز شناور مانند تعريف متغير صحيح است. با اين تفاوت که از کلمۀ کليدی float يا double برای مشخص نمودن نوع متغير استفاده می کنيم.
float x; double x,y=0;
تفاوت نوع float با نوع double در اين است که نوع double دو برابر float از حافظه استفاده میکند. پس نوع double دقتی بسيار بيشتر از float دارد. به همين دليل محاسبات double وقتگيرتر از محاسبات float است.
نوع بولين bool
نوع bool يک نوع صحيح است که متغيرهای اين نوع فقط ميتوانند مقدار true يا false داشته باشند. true به معني درست و false به معني نادرست است.
اما اين مقادير در اصل به صورت 1 و 0 درون کامپیوتر ذخيره میشوند: 1 براي true و 0 براي false.
نوع کاراکتری char
از انواع متغير ها در ++C نوغ کاراکتری یا Char است. يک کاراکتر يک حرف، رقم يا نشانه است که يک شمارۀ منحصر به فرد دارد. به عبارت عاميانه، هر کليدی که روی صفحهکليد خود میبينيد يک کاراکتر را نشان میدهد. مثلا هر يک از حروف ‘A’ تا ‘Z’ و ‘a’ تا ‘z’ و هر يک از اعداد ‘0’ تا ‘9’ و يا نشانههاي ‘~’ تا ‘+’ روي صفحهکليد را يک کاراکتر مینامند. براي تعريف متغيری از نوع کاراکتر از کلمه کليدی char استفاده میکنيم. يک کاراکتر بايد درون دو علامت آپستروف (‘) محصور شده باشد. پس ‘A’ يک کاراکتر است؛ همچنين ‘8’ يک کاراکتر است اما 8 يک کاراکتر نيست بلکه يک عدد صحيح است.
مثال
char c ='A';
نوع شمارشی enum
يک نوع شمارشی يک نوع صحيح است که توسط کاربر مشخص می شود. نحو تعريف يک نوع شمارشی به شکل زير است:
enum typename{enumerator-list}
که enum کلمهای کليدی است، typename نام نوع جديد است که کاربر مشخص می کند و enumerator-list مجموعه مقاديری است که اين نوع جديد می تواند داشته باشد. به عنوان مثال به تعريف زير دقت کنيد:
enum Day{SAT,SUN,MON,TUE,WED,THU,FRI}
حالا Day يک نوع جديد است و متغيرهايی که از اين نوع تعريف می شوند می توانند يکي از مقادير SAT و SUN و MON و TUE و WED و THU و FRI را داشته باشند:
Day day1,day2;
day1 = MON;
day2 = THU;
وقتي نوع جديد Day و محدودۀ مقاديرش را تعيين کرديم، میتوانيم متغيرهايی از اين نوع جديد بسازيم. در کد بالا متغيرهای day1 و day2 از نوع Day تعريف شدهاند. آنگاه day1 با مقدار MON و day2 با مقدار THU مقداردهی شده است.
مثال
#include <iostream> using namespace std; enum Day {SAT,SUN,MON,TUE,WED,THU,FRI}; int main() { Day day1,day2; day1 = MON; day2 = THU; cout << "day1 : " <<day1<<endl; cout << "day2 : " <<day2<<endl; return 0; }
خروجی برنامه
day1 : 2 day2 : 5
مقادير SAT و SUN و … هر چند که به همين شکل به کار می روند اما در کامپیوتر به شکل اعداد صحيح 0 و 1 و 2 و … ذخيره میشوند. به همين دليل است که به هر يک از مقادير SAT و SUN و … يک شمارشگر میگويند. میتوان مقادير صحيح دلخواهی را به شمارشگرها نسبت داد:
enum Day{SAT=1,SUN=2,MON=4,TUE=8,WED=16,THU=32,FRI=64}
اگر فقط بعضی از شمارشگرها مقداردهی شوند، آنگاه ساير شمارشگرها که مقداردهی نشدهاند مقادير متوالی بعدی را خواهند گرفت:
enum Day{SAT=1,SUN,MON,TUE,WED,THU,FRI}
دستور بالا مقادير 1 تا 7 را به ترتيب به روزهای هفته تخصيص خواهد داد.
همچنين دو يا چند شمارشگر در يک فهرست ميتوانند مقادير يکسانی داشته باشند:
enum Answer{NO=0,FALSE=0,YES=1,TRUE=1,OK=1}
در انواع متغير ها در ++C نحوۀ انتخاب نامشمارشگرها آزاد است اما بيشتر برنامهنويسان از توافق زير در برنامههايشان استفاده می کنند:
- برای نام ثابتها از حروف بزرگ استفاده کنيد.
- اولين حرف از نام نوع شمارشی را با حرف بزرگ بنويسيد.
- در هر جای ديگر از حروف کوچک استفاده کنيد.
نام شمارشگر بايد معتبر باشد:
يعني:
- کلمۀ کليدي نباشد.
- با عدد شروع نشود.
- نشانههاي رياضی نيز نداشته باشد.
تبديل نوع و گسترش نوع
در محاسباتی که چند نوع متغير وجود دارد، جواب هميشه به شکل متغيری است که دقت بالاتری دارد. يعنی اگر يک عدد صحيح را با يک عدد مميز شناور جمع ببنديم، پاسخ به شکل مميز شناور است به اين عمل گسترش نوع می گويند.
برای اين که مقدار يک متغير از نوع مميز شناور را به نوع صحيح تبديل کنيم از عبارت ()int استفاده میکنيم به اين عمل تبديل نوع گفته میشود.
مثال گسترش نوع
برنامۀ زير يک عدد صحيح را با يک عدد مميز شناور جمع مِی کند:
int main() { // adds an int value with a double value: int n = 22; double p = 3.1415; p += n; cout << "p = " << p << ", n = " << n << endl; return 0; }
خروجی برنامه
p = 25.1415, n = 22
برخی از خطاهای برنامهنويسی
خطای زمان کامپايل : اين قبيل خطاها که اغلب خطاهای نحوی syntax هستند، توسط کامپايلر کشف میشوند و به راحتی میتوان آنها را رفع نمود.
خطاي زمان اجرا : کشف اينگونه خطاها به راحتی ممکن نيست و کامپايلر نيز چيزی راجع به آن نمیداند. برخی از خطاهای زمان اجرا سبب میشوند که برنامه به طور کامل متوقف شود و از کار بيفتد در اصطلاح خطاهای semantic نیز میگویند.
سرريز عددی یا Overflow
يک متغير هر قدر هم که گنجايش داشته باشد، بالاخره مقداری هست که از گنجايش آن متغير بيشتر باشد. اگر سعی کنيم در يک متغير مقداری قرار دهيم که از گنجايش آن متغير فراتر باشد، متغير «سرريز» ميشود،در چنين حالتی میگوييم که خطای سرريز یا Overflow رخ داده است.
مثال سریز عددی
اين برنامه به طور مكرر n را در 1000 ضرب می كند تا سرانجام سرريز شود:
int main() { //prints n until it overflows: int n =1000; cout << "n = " << n << endl; n *= 1000; // multiplies n by 1000 cout << "n = " << n << endl; n *= 1000; // multiplies n by 1000 cout << " n = " << n << endl; n *= 1000; // multiplies n by 1000 cout << " n = " << n << endl; return 0; }
خروجی برنامه
n = 1000 n = 1000000 n = 1000000000 n = -727379968
وقتی يک عدد صحيح سرريز شود، عدد سرريز شده به يک مقدار منفی «گردانيده» می شود اما وقتی يک عدد مميز شناور سرريز شود، نماد inf به معنای بی نهايت را به دست می دهد.
خطای گرد کردن
خطای گرد كردن نوع ديگری از خطاست كه اغلب وقتی کامپیوترها روی اعداد حقيقی محاسبه می كنند، رخ می دهد. براي مثال عدد 1/3ممكن است به صورت 0.333333 ذخيره شود كه دقيقا معادل 1/3 نيست. اين خطا از آنجا ناشی میشود که اعدادی مثل 1/3 مقدار دقيق ندارند و کامپیوتر نمی تواند اين مقدار را پيدا کند، پس نزديکترين عدد قابل محاسبه را به جای چنين اعدادی منظور میکند.
«هيچگاه از متغير مميز شناور برای مقايسه برابری استفاده نکنيد» زيرا در متغيرهای مميز شناور خطای گرد کردن سبب می شود که پاسخ با آن چه مورد نظر شماست متفاوت باشد.
حوزه متغيرها
در انتهای بحث انواع متغير ها در ++C به حوزه متغیر ها می رسیم. انتخاب نامهای نامفهوم يا ناقص سبب کاهش خوانايی برنامه و افزايش خطاهای برنامهنويسی میشود. استفاده از متغيرها در حوزۀ نامناسب هم سبب بروز خطاهايی می شود. «حوزه متغير» محدودهای است که يک متغير خاص اجازه دارد در آن محدوده به کار رود يا فراخوانی شود.
اصطلاح «بلوک» در ++C واژه مناسبی است که می توان به وسيلۀ آن حوزۀ متغير را مشخص نمود. يک بلوک برنامه، قسمتی از برنامه است که درون يک جفت علامت کروشه { } محدود شده است.
حوزۀ يک متغير از محل اعلان آن شروع می شود و تا پايان همان بلوک ادامه می يابد. خارج از آن بلوک نمی توان به متغير دسترسی داشت. همچنين قبل از اين که متغير اعلان شود نمی توان آن را استفاده نمود. می توانيم در يک برنامه، چند متغير متفاوت با يک نام داشته باشيم به شرطی که در حوزههای مشترک نباشند.
درباره امین جلیل زاده رزین
پایه گذار و موسس وب سایت آموزشی پی استور، مدرس دانشگاه فنی و حرفه ای، برنامه نویس و تحلیل گر سیستم، پژوهشگر در حوزه الگوریتم های ابتکاری، فرا ابتکاری، یادگیری ماشین، شبکه و پایگاه داده. ایشان در زبان های برنامه نویسی متعدد، نظیر ++C، سی شارپ، PHP ،Java، متلب MATLAB و Python تسلط و سابقه تدریس فعال دارند.