فصل دوم
دستورات پایه و دستورات شرطی
متغیرها و عبارات
متغیر بخشی از حافظه کامپیوتر است که میتواند مقداری را در خود ذخیره و نگهداری نماید. متغیرها نقش اساسی در برنامهنویسی کامپیوتری داشته و بسیار پرکاربرد هستند. معمولاً متغیرها روی کاغذ با یک مستطیل نشان داده میشوند (شکل 2-1). هر متغیر از سه رکن اصلی تشکیل میشود:
-
نام: هر متغیر در برنامهنویسی دارای یک نام است که با آن شناخته میشود. بهعنوانمثال در شکل 2-1 سه متغیر با نامهای number1، number2 و sum تعریف شده است. در خصوص شرایط نامگذاری متغیرها در ادامه توضیح خواهیم داد.
-
نوع داده : برای هر متغیر باید نوع آن مشخص شود. مثلاً یک متغیر میتواند مقادیر عددی از نوع اعداد صحیح در خود جای دهد. بنابراین نوع آن عدد صحیح تعیین میشود. یا متغیر دیگر میتواند اعداد حقیقی یا حتی متن نگهداری کند.
-
مقدار: هر متغیر در هرلحظه دارای یک مقدار است. نکته مهم اینکه مقدار متغیرها در طول زمان و با اجرای دستورات جدید تغییر میکند و ثابت نخواهد ماند. اصولاً به همین دلیل است که به آنها متغیر گفته میشود.
شرایط نامگذاری متغیرها
نامی که برای متغیرها انتخاب میشود باید حتماً گویا و بامعنا باشد و هدف از آن متغیر را نشان دهد. در نامگذاری متغیرها میتوان از ترکیبی از حروف و اعداد استفاده کرد ولی نام حتماً باید با یک حرف شروع شود. استفاده از حروف کوچک و بزرگ در نامگذاری مجاز است اما توصیه میشود برنامهنویسان صرفاً از حروف کوچک استفاده کنند. ++C زبانی است که به حروف کوچک و بزرگ حساس است، به عبارتی x و X را دو متغیر مجزا و مستقل محسوب میکند. لذا در صورت استفاده نادرست از حروف بزرگ امکان اشتباه افزایش پیدا خواهد کرد.
استفاده از خط پیشزمینه (_) در نامگذاری مجاز است ولی معمولاً فقط در اسامی چندبخشی مورداستفاده قرار میگیرد، نظیر price_list. جهت افزایش خوانایی استفاده از آن جز در موارد خاص توصیه نمیشود.
درصورتیکه اسامی انتخابی مجاز نباشد، کامپایلر ++C خطای سینتکس صادر خواهد کرد. چند نمونه از اسامی غیرمجاز برای متغیرها در زیر آورده شده است:
اولین متغیر به دلیل اینکه با عدد شروع شده قابلقبول نیست. متغیر بعدی از علامت غیرمجاز $ استفاده کرده است. اما در مورد متغیر سوم ظاهراً همهچیز درست است. حال این سؤال پیش میآید که چرا کامپایلر ++C متغیر class را نپذیرفته است؟ هر زبان برنامهنویسی از مجموعهای از کلمات خاص استفاده میکند که برای کامپایلر یا مفسر آن زبان، مفهوم خاصی داشته و صرفاً باید به همان منظور به کار گرفته شوند. اصطلاحاً به این کلمات، کلمات کلیدی یا رزرو شده گفته میشود. معمولاً زبانهای برنامهنویسی اجازه استفاده از کلمات رزرو شده را برای نامگذاری متغیرها نمیدهند. class یکی از کلمات رزرو شده زبان ++C است. لیست کامل کلمات رزرو شده ++C در ادامه نشان داده شده است. نمونه چهارم به دلیل استفاده از کاراکتر فاصله غیرمجاز است.
انواع داده-نوعها در زبان ++C
مقادیری که میتواند در متغیرها قرار گیرد، به داده-نوع یا تایپ آن متغیر بستگی دارد. بهعنوانمثال مقدار 2، از نوع عدد صحیح محسوب میگردد که در ++C به آن int گفته میشود. یا مقدار “Hello World” از نوع متنی یا رشتهای محسوب میشود که اصطلاحاً در ++C به آن string (دنبالهای از کاراکترها و حروف) گفته میشود. عبارتهای متنی حتماً باید بین دو کوتیشن (") قرار گیرند، مانند “What’s up”.
داده و نوعهای داده (Data Types)
یک برنامه کامپیوتری، دادهها را پردازش میکند. داده در ++C باید عضو یکی از مجموعههای مختلف نوعهای داده باشد. نوع داده، یک مجموعه معین از دادههای خاص به همراه عملیات مجاز روی آنها است. بهعنوانمثال میتوان مجموعه اعداد صحیح را بهعنوان یک نوع داده ذکر کرد که عملیات جمع، تفریق، ضرب و تقسیم و نظایر آن روی آنها قابلاجرا است. توجه شود که یک نوع درواقع یک مجموعه است و هر کجا که کلمه "نوع داده" را به کار میبریم منظورمان یک مجموعه است.
نوع داده (Data Type) مجموعهای از دادهها است که عملیات خاصی روی آنها تعریف شده و قابل انجام است.
در C++، چهار نوع داده اصلی وجود دارد که عبارتند از int، double ،char و bool. همانگونه که در ادامه خواهیم دید، هر یک از این نوع دادهها نیز دارای گونههای متعددی هستند. علاوه بر این، C++ مجموعهای از داده نوعهای پیشرفتهتر را هم ارائه میدهد که در فصلهای بعدی بهتدریج با آنها آشنا خواهیم شد.
-
نوع داده int: از سادهترین و پرکاربردترین نوع دادههای این زبان به شمار میآید و هر جا نیاز به اعداد صحیح است، از این نوع استفاده میشود.
-
نوع داده double: این نوع داده برای کار کردن با اعداد اعشاری ارائه شده است. در محاسبات مهندسی اعداد اعشاری یا حقیقی کاربرد زیادی دارند.
-
نوع داده char: متغیری که از این نوع داده تعریف شود میتواند یک کاراکتر را درون خود جای دهد. کاراکتر میتواند هر یک از حروف الفبای انگلیسی a تا z و یا A تا Z و مجموعه ارقام 0 تا 9 و هر یک از علائم نظیر ‘.’, ’,’, ’$’, ‘&’, ‘*’, ‘-‘, ‘+’, ‘&’, ‘#’, ‘!’, ‘?’ و نظایر آن باشد. کاراکترها بین علامت ‘ محصور میشوند. دقت کنید که منظور از ‘2’ کاراکتر 2 است و نباید با عدد 2 اشتباه شود.
-
نوع داده bool: این نوع داده برای دادههای دودویی بولی مورد استفاده قرار میگیرد. این دادهها صرفاً دو حالت میتوانند داشته باشند: درست یا غلط، true یا false، 0 یا 1. متغیرهای بولی در درست کردن دستورات شرطی بسیار پرکاربرد هستند.
اکنون که با نوع دادههای ساده C++ آشنا شدید، نحوه کار با آنها را در قالب مثال زیر دنبال میکنیم:
در این مثال سه متغیر به نامهای number1، number2 و sum تعریف شده است. نوع هر سه متغیر int تعریف شده است، بنابراین هر سه متغیر میتوانند اعداد صحیح را در خود جای دهند.
قالب تعریف متغیر در زبان C++ به صورت زیر است:
به مثالهای زیر توجه کنید:
در این مثالها، متغیر x از نوع عدد صحیح، y از نوع عدد حقیقی، ch از نوع کاراکتر و flag از نوع متغیر دو مقداری (بولین) تعریف شدهاند.
مقدار متغیر number1 در خط 11 از کاربر دریافت شده است. دستور cin برای دریافت اطلاعات از کاربر مورد استفاده قرار میگیرد و کاربرد آن دقیقاً برعکس cout است. به جهت فلش >> برای دستور cin دقت نمایید. همانگونه که مشاهده میکنید قبل از این دستور، در خط 10 از یک دستور cout استفاده شده است و پیغامی به کاربر نشان داده شده است که عدد اول را وارد کند. اصطلاحاً به این پیغام پرامپت (prompt) گفته میشود و مرسوم است پیش از خواندن اطلاعات از ورودی (دریافت اطلاعات از کاربر) از طریق پرامپت به کاربر گفته شود که دقیقاً چه کاری باید انجام دهد. همواره قبل از دستور cin از پرامپت استفاده میکنیم. همین کار برای متغیر دوم در خطهای 13 و 14 تکرار شده است. خط 12 برای افزایش خوانایی برنامه خالی گذاشته شده است.
خط 16 یک دستور انتساب یا جایگزینی را نشان میدهد. در این دستور، جمع دو متغیر اول محاسبه میشود و در متغیر sum قرار میگیرد. دستور جایگزینی کاربرد بسیار زیادی در تعیین مقدار متغیرها یا به عبارتی در مقداردهی به متغیرها دارد. در ادامه بیشتر با این دستور آشنا خواهیم شد. نهایتاً در خط 18 نتیجه چاپ میشود. دقت کنید که زمانی که sum به صورت رشتهای نوشته میشود (“sum”)، عین این کلمه چاپ خواهد شد، در عوض، وقتی بهعنوان متغیر sum نوشته شود، به جای کلمه sum، مقدار متغیر مربوطه به کاربر نشان داده میشود.
دستور جایگزینی
دستور جایگزینی امکان مقداردهی به متغیرها را فراهم میآورد. به این مثالها توجه کنید:
در مثال فوق که شامل سه دستور جایگزینی است، در اولین دستور مقدار ‘*’ در متغیر star ریخته میشود. بدیهی است نوع این متغیر، char خواهد بود. در دستور دوم مقدار 12 در متغیر عددی n ریخته میشود. نهایتاً در سومین دستور، مقدار 3.14 در متغیر pi که از نوع اعشاری (عدد حقیقی) است ریخته میشود.
دستور عبارتی است که توسط کامپیوتر اجرا شود. پیشازاین با دستوراتی نظیر چاپ و جایگزینی آشنا شدیم.
عبارات ریاضی
به کمک مجموعهای از عملگر های ریاضی نظیر جمع، منها، ضرب و تقسیم میتوان عبارات ریاضی و محاسباتی تولید کرد. نمونههایی از عبارات ریاضی ++C عبارتند از:
عملگرهای جمع و تفریق همان عملگرهای شناختهشده ریاضی میباشند. در ++C برای ضرب از علامت * و برای تقسیم از علامت / استفاده میشود. وقتی یکی از عملوندهای یک عملگر، یک متغیر باشد، نظیر متغیر x در مثال فوق، مقدار آن در محاسبات در نظر گرفته میشود. مثلاً اگر مقدار آن 4 باشد، حاصل عبارت x – 1 برابر 3 خواهد شد. جدول 2-1 مجموعه عملگرهایی را که در ساخت عبارتهای ریاضی مورد استفاده قرار میگیرند، نشان میدهد.
جدول 2-1: عملگرهای ریاضی
علامت در ریاضیات | علامت معادل در C++ | مفهوم | مثال |
+ | + | جمع | x + y |
- | - | تفریق | x - y |
× یا . | * | ضرب | x * y |
÷ | / | تقسیم | x / y |
mod | % | باقیمانده | x % y |
در ++C برای تقسیم از علامت / استفاده میشود. دقت نمایید که استفاده از علامتهای شناختهشده ریاضی نظیر خط کسری یا ÷ برای تقسیم مجاز نیست. در صورتی که عملوندهای / اعداد صحیح باشند، تنها مقدار صحیح خارجقسمت محاسبه میشود. در غیر این صورت خارجقسمت به صورت کامل محاسبه میشود. به مثال زیر توجه کنید:
عملگر باقیمانده یا % باقیمانده تقسیم دو عدد صحیح را محاسبه میکند. به مثال زیر توجه کنید:
این عملگر برای چک کردن بخشپذیری اعداد بر هم بسیار پرکاربرد است. بهعنوانمثال اگر x % 2 مساوی صفر باشد به معنی زوج بودن x است. همچنین اگر x % 10 صفر باشد، یعنی x از مضارب 10 است. درواقع x % 10 رقم یکان عدد را برمیگرداند.
اولویت عملگرها
هر جا صحبت از عملگرها به میان میآید، بلافاصله موضوع اولویت عملگرها مطرح میشود. برای روشنتر شدن موضوع به این مثال دقت کنید:
سؤال این است که ابتدا جمع باید انجام شود سپس ضرب و یا برعکس؟ برای اینکه محاسبات بدون ابهام انجام شود، لازم است اولویت همه عملگرها بهدقت تعیین شود. ترتیب عملگرها در ++C طبق قواعد زیر تعیین میشود:
-
پرانتز بالاترین اولویت را دارد. میتوان از پرانتز برای تغییر اولویتها و الزام اولویتبندی دلخواه استفاده نمود.
-
عملگرهای ضرب، تقسیم و باقیمانده در جایگاه بعدی قرار دارند. اولویت این سه عملگر باهم یکسان است و از جمع و تفریق بالاتر است.
-
عملگرهای جمع و تفرق پایینترین اولویت را دارند. اولویت این دو عملگر باهم یکسان است.
-
در بین عملگرهایی که اولویت یکسان دارند، اولویت با عملگر سمت چپ خواهد بود. بهعنوان مثال در عبارت x * 10 / 3.5 ابتدا ضرب انجام میشود سپس تقسیم.
به مثالهای زیر توجه کنید:
مثال: اولویت عملگرها را در عبارت زیر مشخص کنید:
مثال: تقدم عملگرها را در عبارت زیر مشخص کنید:
با توجه به توضیحات فوق، اولویت عملگرها به شکل زیر است:
عبارتهای ریاضی میتوانند در سمت راست دستورات جایگزینی هم مورد استفاده قرار گیرند:
در مورد دستورات جایگزینی حتماً سمت چپ عبارت باید یک متغیر باشد. ولی سمت راست میتواند مقدار، عبارت ریاضی و یا یک متغیر دیگر باشد. نمونههایی از دستورات جایگزینی صحیح عبارتند از:
نمونههای زیر صحیح نبوده و مجاز نیست (زیرا سمت چپ دستور جایگزینی متغیر نیست):
همانگونه که از مثالهای فوق مشخص میشود، معنی جایگزینی با تساوی در ریاضیات متفاوت است و نباید مفهوم آن را با تساوی ریاضی اشتباه گرفت. در جایگزینی قابلیت جابجایی وجود ندارد، به عبارتی x = 2 و 2 = x کاملاً متفاوت هستند، و دومی اساساً قابلقبول نیست، درحالیکه در ریاضیات، تساوی جابجاپذیر است.
تبدیل صریح و ضمنی نوع دادهها
مقادیر صحیح و اعشاری به طرز متفاوتی در حافظه کامپیوتر نگهداری میشوند. مجموعهای از بیتها که نمایانگر عدد صحیح 2 است با مجموعهای از بیتها که نمایانگر عدد اعشاری 2.0 است کاملاً متفاوت هستند. اگر در انتسابها یا عبارات محاسباتی مقادیر اعشاری و صحیح را توأماً به کار بریم چه اتفاقی میافتد؟
به مثال زیر توجه کنید:
در اینجا someInt تنها میتواند مقادیر صحیح و someDouble تنها مقادیر اعشاری را میتواند نگهداری کند. در انتساب ذیل:
به نظر میرسد که عدد صحیح 12 در someDouble ذخیره میشود، ولی این تصور صحیح نیست. کامپیوتر از ذخیره هر چیز دیگری غیر از مقدار اعشاری در someDouble پرهیز میکند. کامپایلر دستورالعملهای اضافی به زبان ماشین جهت تبدیل 12 به 12.0 را به برنامه افزوده، آنگاه 12.0 را در someDouble ذخیره میکند. این تعویض اجباری (و خودکار از نگاه برنامهنویس) از یک نوع داده به نوع دیگر داده، تبدیل ضمنی نوع نامیده میشود.
دستورالعمل ذیل:
نیز سبب تبدیل ضمنی یک نوع داده به نوع دیگر میشود. وقتی یک عدد اعشاری به یک متغیر صحیح نسبت داده میشود، از قسمت اعشاری صرفنظر میشود. لذا در اینجا مقدار 4 بهعنوان یک داده از نوع داده صحیح در someInt ذخیره میشود.
اغلب بهجای یک مقدار ثابت، یک عبارت محاسباتی در سمت راست دستور انتساب قرار دارد. انتسابهای ذیل نیز سبب تبدیل ضمنی نوع داده میشوند.
ذخیره یک عدد صحیح در یک متغیر اعشاری سبب از بین رفتن اطلاعات نمیشود. یک عدد صحیح نظیر 24 بهراحتی بهصورت اعشاری 24.0 نمایش داده میشود. ولی نتیجه ذخیره یک عبارت اعشاری در یک متغیر صحیح منجر به از میان رفتن اطلاعات میشود زیرا ارقام بعد از ممیز از بین خواهد رفت.
برای پرهیز از وقوع خطا و روشنتر بودن عبارات، ++C امکان تبدیل صریح نوع داده را فراهم کرده است. عمل تبدیل صریح نوع با ذکر نام نوع داده موردنظر و قراردادن عبارت محاسباتی (که قرار است نوع آن عوض شود) در پرانتز بعد از آن امکانپذیر است:
از هر دو دستور ذیل نتیجه یکسانی به دست میآید.
تنها تفاوت در وضوح و شفافیت بیان مطلب است. با عمل تبدیل صریح نوع داده برای برنامهنویس و هر کس دیگری که برنامه را میخواند کاملاً واضح است که ترکیبی از انواع داده موردنظر بوده است و نتیجه محاسبات نیز کاملاً قابل پیشبینی است.
برای گرد کردن (ROUND) یک عدد اعشاری مثبت راهحل جالب ذیل وجود دارد.
توابع کتابخانهای
محاسبات خاصی نظیر جذرگیری و پیدا کردن مقدار مطلق یک عدد، در برنامهها بهطور مکرر موردنیاز واقع میشوند. نوشتن برنامههایی برای انجام اینگونه محاسبات توسط هر برنامهنویس نتیجهای جز اتلاف وقت دربر ندارد. برای کمک به برنامهنویسان، یک کتابخانه استاندارد با مجموعهای بزرگ از توابع از پیش نوشته شده در C++ موجود است که نمونههای کوچکی از این توابع در جدول 2-2 ذکر شده است.
جدول2-2: چند تابع پرکاربرد محاسباتی
استفاده از توابع کتابخانهای ساده است. ابتدا با استفاده از راهنمای #include در ابتدای برنامه فایل سرفصل مناسب را مشخص میکنیم. بهطوریکه کامپایلر بتواند همه اطلاعات موردنیاز خود را از تابع در دسترس داشته باشد، آنگاه هر کجا که بخواهیم، میتوانیم از تابع استفاده کنیم. به این مثال توجه کنید:
پیوست سه لیست بسیاری از توابع کتابخانهای را دربر دارد. توصیه میشود که اکنون نگاهی به این پیوست داشته باشید تا از امکانات کتابخانهای سیستم ++C تا حدودی مطلع شوید.
جزئیات نوعهای داده در ++C
اکنونکه با نوعهای داده ساده در C++ آشنا شدیم، نگاهی عمیقتر به نوع دادههای این زبان خواهیم انداخت. بعضی از نوعهای داده که بهطور مکرر استفاده میشوند در ++C بهصورت پیشفرض در اختیار برنامهنویسان است. همچنین برنامهنویس، خود میتواند یک نوع داده جدید تعریف کند. انواع داده تعبیه شده در ++C به سه دسته تقسیم میشوند: داده ساده ـ داده ساختیافته و داده آدرس. شکل 2-2 را نگاه کنید.
انواع داده ساختیافته و داده آدرس در فصلهای بعدی موردبحث قرار میگیرند.
نوعهای داده صحیح (Integral Type)
نوع دادههای long, int, short, char بهعنوان نوعهای صحیح شناخته شدهاند، زیرا عناصر آنها مقادیر صحیح هستند. سادهترین صورت مقادیر صحیح دنبالهای از یک یا چند رقم است مثل 4000, 498, 10, 22, 26 . در اکثر موارد علامت منفی قبل از این دادهها آنها را منفی میکند مثل -912,-378 . مگر آنکه با بهکارگیری کلمه رزرو شده unsigned قبل از int، تنها مجموعه اعداد صحیح مثبت یا صفر را مورد نظر قرار دهیم. اعضاء مجموعه نوع دادههای long, int, short, char دارای اندازههای مختلف هستند و در حافظه کامپیوتر جاهایی با اندازههای مختلف را اشغال میکنند. شکل ذیل این مطلب را به تصویرکشیده است:
اندازههای فوقالذکر به کامپیوتری که با آن کار میکنیم بستگی دارد. همانگونه که ذکر شد، int بهمراتب رایجترین نوع داده برای انجام عملیات روی داده صحیح است. در بسیاری از کامپیوترهای شخصی محدوده مقادیر نوع داده int از -32768 تا 32767 است. در ماشینهای بزرگتر این محدوده بین -2147483648 الی 2147483647 است. اگر برنامهای بخواهد مقادیر بزرگتر از محدوده مجاز کامپیوتر را در حافظه ذخیره کنید، سرریز (overflow) اتفاق میافتد بعضی از ماشینها پیغام خطا مبنی بر وقوع سرریز صادر میکنند و بعضی پیغامی صادر نمیکنند. البته در یک کامپیوتر شخصی با انتخاب long int میتوانیم به اعداد بزرگتر دسترسی پیدا کنیم.
نوع داده کاراکتر (char Type)
دیدیم که نمایش char کوچکترین نوع داده است. یک مقدار از مجموعه char کمتر از یک مقدار از مجموعه int در حافظه جا اشغال میکند. بنابراین برنامهنویس برای اعداد بین صفر تا 127 گاهی از char برای صرفهجوئی در حافظه یا موارد خاص استفاده میکند. اما دلیل دیگری برای استفاده از نوع داده char وجود دارد: برای توصیف دادههایی نظیر یک حرف، یک رقم، علامت ویژه از این نوع داده استفاده میشود.
'A' 'a' '*' 'P' '$' '&' '-'
هر ماشین مجموعه خاص خود را داراست. (ضمیمه 5 الگوی از این مجموعه کاراکترها را دربر دارد) توجه کنید که کاراکترها در یک علامت مانند ' (کوتیشن تنها) محصور شدهاند. کامپایلر ++C به این علامت ' ' برای تمیز بین کاراکتر ' 8 ' عدد صحیح 8نیاز دارد زیرا این عدد و آن کاراکتر به صورتهای مختلف در حافظه ذخیره میشوند.
همچنان که در تعریف "نوع داده" گفته شد هر نوع داده مجموعهای از عملیات را شامل میشود. مثلاً در مورد مرتبسازی کاراکترها 'A' قبل از 'B' ظاهر میشود و به عبارتی کمتر از آن است همینطور 'B' از 'C' کمتر است و '2' از '3' کمتر است.
نوع داده اعشاری (float Type)
نوع داده اعشاری (float) دومین مجموعه اساسی از نوع داده ساده در ++C است که برای نمایش مجموعه اعداد حقیقی به کار گرفته میشود.
همانطور که نوع داده صحیح در اندازههای مختلف (long, int, short, char) ظاهر میشوند، نوع داده اعشاری نیز در اندازههای مختلف وجود دارد. به ترتیب افزایش اندازه، انواع دادههای اعشاری عبارتند از double, float: (یعنی دقت مضاعف) و long double اندازه بزرگتر، که محدوده وسیعتری از مقادیر و دقت (یعنی تعداد ارقام بامعنی) را در اختیار میگذارند و فضای بیشتری از حافظه نیز مورد استفاده قرار میدهند.
اعداد اعشاری میتوانند بهصورت علمی با یک نما نمایش داده شوند بهطوریکه در ++C به جای نوشتن 3.054x10^12 مینویسیم: 3.054E12 حرف E توان با پایه 10 را نشان میدهد.
اغلب برنامهها به نوع دادههای double یا long double نیاز ندارند. معمولاً نوع داده float دقت و محدوده کافی را فراهم میکند. در کامپیوترهای شخصی مقادیر متعلق به نوع داده float دارای شش تا هفت رقم با معنی و مقداری در حدود فاصله 3.4E+38 تا +3.4E-38 را پوشش میدهد. کامپیوترها همواره نمیتوانند کلیه ارقام اعداد اعشاری را دقیقاً نمایش دهند یا نگهداری کنند. کامپیوتر همه دادهها را به صورت نمائی در مبنای دودویی (Binary) نگهداری میکند. اکثر مقادیر اعشاری تنها بهصورت تقریبی دودویی قابل نمایش هستند. لذا تعجب نکنید اگر کامپیوتر عدد 4.8 را بهصورت 4.7999998 چاپ کند. در اکثر موارد بیدقتی جزئی در آخرین رقم سمت راست طبیعی است (مثلاً حداکثر 107 × 0.5) و خطای برنامهنویس نیست.
ثابتها
در بسیاری از مواقع از مقادیر ثابت نظیر 16 یا 3.23 برای مقداردهی به متغیرها استفاده میشود. مقدار ثابتی مثل 3.14159 که همان عدد π است، میتواند در عبارتها بهطور مستقیم به کار گرفته شود ولی بهتر است شناسهای به آن نسبت دهیم و در عبارات محاسباتی از آن شناسه استفاده کنیم. اصطلاحاً به این شناسهها که مقدار ثابت و مشخصی را در خود نگه میدارند و مقدار آنها هرگز تغییر نمیکند، ثابت بانام گفته میشود. تعریف ثابتهای بانام در ++C به صورت زیر است.
به کلمه ذخیره شده const که اعلان با آن شروع شده است توجه کنید و همینطور به علامت مساوی = که سبب میشود مقدار ثابتی به شناسه نسبت داده شود.
به مثالهای زیر توجه کنید:
معمولاً شناسههای مربوط به دادههای ثابت با حروف بزرگ نامگذاری میشود و درصورتیکه شناسه شامل چند کلمه انگلیسی باشد آنها را با علامت _ از هم جدا میکنند. بهاینترتیب خواننده برنامه قادر خواهد بود که ثوابت را از متغیرها تشخیص دهد.
استفاده از «ثابتهای بانام» این حسن را دارد که اگر در برنامه به جای PI ، PO ، تایپ شود برنامه پیغام خطا میدهد که PO را نمیشناسد ولی اگر به جای استفاده از شناسه ثابت PI مستقیماً از عدد 3.14159 استفاده شود، و در استفاده مجدد از این عدد اشتباهاً 3.14519 تایپ شود برنامه پیغام خطایی نخواهد داد و پیدا کردن چنین اشتباهی در یک برنامه بزرگ کار سادهای نیست.
اضافه کردن توضیح در سمت راست تعریف ثابتهای فوق برای بالا بردن سهولت خواندن برنامه توسط دیگران مفید است مثلاً:
حل مسئله ـ مطالعه یک مورد
محاسبه میزان مسافت برحسب مایل یک خودرو به ازای یک گالن سوخت
مسئله: برنامهای بنویسید که مایل به ازای یک گالن سوخت یک خودرو را در یک سفر محاسبه کند، با فرض اینکه مقدار موجودی در باک در ابتدا و انتهای سفر مشخص باشد. همینطور مایل اولیه 67308.0 و مایل نهائی 68750.5 باشد. بهعلاوه در حین سفر چهار بار خودرو سوختگیری کامل تا حد پر شدن انجام شده است و هر بار به ترتیب 8.5, 12.2, 14.3, 11.7 گالن سوخت دریافت کرده است. فرض کنید که باک در ابتدا و انتها پر باشد.
خروجی: کمیتهایی که محاسبه بر اساس آنها انجام میپذیرد و مایل به ازای هر گالن نشان داده شوند.
بحث: اگر بخواهیم محاسبه را با دست انجام دهیم باید مجموع همه سوختهای دریافتی را با هم جمع کنیم و مقدار مایل طی شده را بر آن تقسیم کنیم، برای محاسبه مایل طی شده مایل ابتدایی را از مایل انتهایی کم میکنیم. درواقع محاسبات ساده فوق، الگوریتم حل مسئلهاند.
برای سهولت در کار که بتوانیم تغییرات بعدی را بهراحتی در برنامه لحاظ کنیم، مقادیر سوختگیری را با ثابتهای نامدار، نامگذاری میکنیم. حل الگوریتمی مسئله به ترتیب ذیل است:
از الگوریتم فوق ثابتها و متغیرهای بهکاررفته در برنامه را پیدا کرده و در ذیل لیست میکنیم.
ثابتها
متغیرها
اکنون برای نوشتن برنامه آماده هستیم. ذیلاً برنامه با توضیح خطوط برنامه آورده شده است.
خروجی برنامه چنین است
خروجی START-MILES نشان میدهد که ++C ممیز و صفر بعد از آن را به علت کامل بودن START-MILES نشان نداده است. نسخههای مختلف ++C ممکن است تعداد ارقام اعشاری بعد از ممیز را متفاوت از آنچه اینجا ذکر شده است نشان دهند.
عملگرهای مقایسهای
عملگرهای مقایسهای کاربرد زیادی در ساختن عبارتهای شرطی دارند و برای حصول اطمینان از درستی یا نادرستی شرطها به کار گرفته میشوند. عملگر == در ++C برای کنترل برابری دو عبارت به کار میرود و مقادیر آنها را باهم مقایسه میکند. چنانچه هر دو یکسان بودند نتیجه درست خواهد بود و در غیر این صورت نادرست . اصطلاحاً به متغیر یا عبارتی که مقدار آن درست یا نادرست باشد، متغیر یا عبارت دودویی یا بولین گفته میشود. بنابراین عملگرهای مقایسهای برای ساختن عبارتهای دودویی کاربرد دارند. به عبارتی نتیجه آنها از جنس دودویی یا درست / نادرست است. عملگرهای مقایسهای در جدول 2-3 نشان داده شدهاند:
جدول 2-3: عملگرهای مقایسهای
همانگونه که ملاحظه میشود، اکثر عملگرهای مقایسهای ++C شبیه عملگرهای مقایسهای در ریاضیات هستند و فقط تغییرات کوچکی در نحوه نگارش انجامشده است. بهعنوانمثال در ++C عملگر کوچکتر مساوی بهجای ≥ با <= نشان داده میشود. همچنین دقت داشته باشید که عملگری به شکل => وجود ندارد.
عملگرهای منطقی
سه عملگر منطقی عطف، فصل و نقیض همانگونه که در منطق و ریاضیات و حتی گفتگوی روزمره مورداستفاده قرار میگیرند، در برنامهنویسی و زبان ++C نیز وجود دارند. این عملگرها در جدول 2-4 نشان داده شدهاند.
جدول 2-4: عملگرهای منطقی
بهعنوانمثال چنانچه بخواهیم چک کنیم که مقدار x بین 0 تا 10 باشد میتوانیم از عبارت x > 0 && x < 10 استفاده کنیم. یا مثلاً اگر بخواهیم چک کنیم که x بر 10 بخشپذیر نباشد، میتوانیم از عبارت ! (x % 10 ==0) استفاده کنیم. عبارت x < 10 || x > 20 نیز وقتی درست است که یا x از 10 کوچکتر باشد و یا از 20 بزرگتر باشد.
حاصل عبارت && وقتی درست است که هر دو عملوند آن درست باشند درحالیکه حاصل || دو عبارت وقتی درست خواهد بود که حداقل یکی از آنها درست باشد. در مورد عملگر نقیض یا not هم مقدار عبارت موردنظر را برعکس میکند، یعنی اگر درست باشد، حاصل نادرست خواهد شد و برعکس.
قاعدتاً عملوندهای عملگرهای منطقی باید عباراتی با مقدار دودویی باشند، اما ++C در این مورد حساسیتی ندارد و میتواند از عبارتهای عددی هم استفاده کرد. در این خصوص، چنانچه نتیجه یک عبارت عددی صفر باشد، بهعنوان False در نظر گرفته میشود و هر نتیجهای غیر از صفر، True تلقی میشود.
اجرای شرطی
در برنامهنویسی در موارد بسیاری نیاز داریم تا اجرای برخی دستورات را به برقرار بودن شرط خاصی منوط کنیم. به عبارتی برخی از دستورات صرفاً در صورت برقرار بودن شرط خاصی اجرا خواهند شد و در غیر این صورت اجرا نمیشوند. اصطلاحاً به این دستور، دستور شرطی گفته میشود که در شکل ساده در ++C با دستور if انجام میشود. به مثال زیر توجه کنید:
بعد از دستور if یک عبارت دودویی ذکر میشود که همان شرط است. درصورتیکه این شرط برقرار باشد، در این مثال اگر x بزرگتر از صفر باشد، عبارت بعدی یا همان دستور شرط اجرا خواهد شد و جمله موردنظر چاپ میشود. درصورتیکه x مثبت نباشد، طبیعتاً این دستور اجرا نخواهد شد و چیزی چاپ نخواهد شد.
شکل کلی دستور if بهصورت زیر است:
پس از دستور if و مشخص کردن شرط، بدنه شرط نوشته میشود. در حالت ساده بدنه شرط شامل یک دستور خواهد بود، ولی چنانچه بخواهیم مجموعهای از دستورات را بهعنوان بدنه شرط تعیین کنیم، میتوانیم آنها را بین آکولاد محصور نماییم و بهاینترتیب اصطلاحاً یک بلوک تشکیل دهیم. تمام دستورات یک بلوک زیر هم نوشته میشوند و نسبت به آکولاد، سه کاراکتر تورفتگی دارند. بنابراین بدنه شرط میتواند یک یا چندین دستور را شامل شود که اجرای همه آنها منوط به شرطی خواهد بود که در دستور if نوشتهشده است.
دستور if در حالت تکمیلی میتواند شامل بخش دیگری به نام else باشد که مشخص میکند در صورت برقرار نبودن شرط چه دستوراتی باید اجرا شود. در این حالت دو سری دستور مشخص میشود که سری اول در صورت برقرار بودن شرط اجرا خواهد شد و سری دوم در صورت عدم برقراری شرط. مثال زیر نحوه استفاده از این دستور را نشان میدهد:
در این مثال درصورتیکه x زوج باشد (شرط برقرار باشد) عبارت زوج بودن x و در غیر این صورت عبارت مربوط به فرد بودن آن نوشته میشود.
مثال: برنامهای بنویسید که مختصات سه نقطه را دریافت کند و مشخص کند که آیا این سه نقطه روی یک خط قرار دارند یا خیر؟
حل: برای تشخیص اینکه سه نقطه روی یک خط قرار دارند یا خیر کافی است شیب خطی که از نقطه اول و دوم میگذرد و شیب خطی که از نقطه اول و سوم میگذرد را محاسبه کنیم. چنانچه شیب این خطوط یکسان نباشد، سه نقطه روی یک خط قرار نمیگیرند. قسمتی از این برنامه به شرح ذیل است. دقت کنید که بخشهای عمومی برنامه و نیز دستورات مربوط به پرامپت، به جهت اختصار حذف شدهاند.
مثال: برنامهای بنویسید که سه عدد دریافت کند و مشخص کند که آیا این سه عدد میتواند اندازه سه ضلع یک مثلث باشد یا خیر.
حل: برای حل این مثال ابتدا باید شرط تشکیل مثلث را پیدا کنیم. اندازه اضلاع مثلث باید بهگونهای باشد که همواره اندازه هر ضلع از مجموع دو ضلع دیگر کوچکتر باشد. بنابراین این برنامه به شکل زیر خواهد بود:
شرطهای تودرتو
عبارتها و دستورات شرطی را میتوان بهصورت تودرتو و ترکیبی استفاده نمود. در این حالت دستور یک شرط، خود میتواند یک دستور شرطی دیگر باشد. به مثال زیر توجه کنید:
در مثال فوق بخش else شرط بیرونی، خود شامل یک دستور مرکب شرطی است و از دستور if/else تشکیل شده است. تفسیر این دستور به این صورت است که اگر شرط x == y برقرار باشد، جمله اول (برابری x و y) چاپ میشود. در غیر این صورت بخش else بیرونی اجرا میشود که خود شامل یک دستور شرطی است. حال اگر x < y باشد، دستور بخش if و در غیر این صورت دستور بخش else داخلی اجرا خواهد شد.
دستورات شرطی تودرتو در برخی موارد میتوانند با شرطهای مرکب که با عملگرهای منطقی ترکیبشدهاند جایگزین شوند. در مثال زیر هر دو حالت معادل هم هستند و اولی بهصورت شرط تودرتو و دومی با شرط ترکیبی && نوشته شده است.
حالت اول:
حالت دوم:
مثال: برنامهای بنویسید که سه عدد از کاربر دریافت کند و بزرگترین عدد را چاپ کند.
شیوه دیگر نگارش این برنامه این است که ابتدا بزرگترین عدد بین دو عدد اول را پیدا کنیم و سپس آن را با عدد سوم مقایسه کنیم:
مثال: برنامهای بنویسید که مالیات حقوق یک کارمند را بر اساس جدول فرضی زیر محاسبه نماید. نحوه محاسبه مالیات بر اساس این جدول بهصورت زیر است:
چنانچه حقوق کارمند کمتر از بیست میلیون ریال در ماه باشد، معاف از مالیات خواهد بود. برای حقوق بالاتر از بیست میلیون ریال تا صدوبیست میلیون ریال، به ازای مبلغ مازاد بر بیست میلیون ریال 10% مالیات تعلق میگیرد. بهعنوانمثال چنانچه حقوق فردی پنجاه میلیون ریال باشد، تا بیست میلیون از حقوق معاف از مالیات است و مازاد آن (سی میلیون ریال) مشمول 10% مالیات خواهد بود. بهاینترتیب مالیات 3 میلیون ریال محاسبه خواهد شد. به همین ترتیب چنانچه حقوق فرد بیش از 120 میلیون ریال باشد، به ازای مازاد بر 120 میلیون ریال، 20% مالیات محاسبه خواهد شد.
برنامه محاسبه مالیات را به کمک چند دستور if میتوان تنظیم نمود. قطعه کد زیر این برنامه را نشان میدهد:
شکلدهی به خروجی
شکلدهی به خروجی برنامه به معنای کنترل چگونگی نمایش خروجی روی صفحهنمایش یا چاپگر است. اگر متغیرهای h, j, i به ترتیب شامل مقادیر 2, 15 و 6 باشند دستورالعمل:
جریانی از کاراکترها را به ترتیب ذیل به خروجی میفرستد:
تفسیر خروجی بدون چاپ فاصله مناسب بین اعداد بهسادگی امکانپذیر نیست. در ادامه چگونگی کنترل فاصلهدهی افقی و عمودی در خروجی را بیان میکنیم. ابتدا نگاهی به فاصلهدهی عمودی خواهیم داشت.
ایجاد خطوط خالی ـ فاصلهدهی عمودی
قبلاً دیدیم که چگونه با استفاده از endl در یک دستورالعمل خروجی میتوان فاصلهدهی عمودی را انجام داد. دنبالهای از دستورالعملهای خروجی آنقدر به نوشتن کاراکترها در خط جاری ادامه میدهند تا endl خط را قطع کند. مثالهای ذیل را ملاحظه کنید:
به دستورهای ذیل توجه کنید.
دستور اول سبب میشود که کلمه Salam چاپ شود. endl سبب میشود که نشانگر صفحه به خط بعد برود. دستور بعدی چیزی را چاپ نمیکند ولی نشانگر صفحه به خط بعد میرود. دستور سوم کلمه Ali را چاپ میکند و خط را قطع میکند. نتیجه خروجی چنین است:
هرگاه endl را بلافاصله بعد از endl دیگری بکار ببریم یک خط خالی ایجاد میشود. همچنانکه ممکن است حدس زده باشید سه endl متوالی تولید دوخط خالی میکنند والی آخر.
توجه کنید که انعطاف زیادی در نحوه نوشتن دستورات خروجی در ++C وجود دارد. میتوانیم سه دستور بالا را در دو دستور ذیل خلاصه کنیم.
همچنین میتوان همه دستورات را در یک دستور خلاصه کرد:
و نحوه دیگر چنین است:
صورت فوق نشان میدهد که میتوان یک دستور ++C را در بیش از یک خط پخش کرد. کامپایلر نماد « ; » را به عنوان معیار پایان دستور میشناسد نه انتهای فیزیکی خط را.
ایجاد فضای خالی در یک خط ـ فاصلهدهی افقی
یک روش به منظور کنترل فضا دهی افقی در خروجی، فرستادن کاراکتر خالی blank)) در جریان داده خروجی است (به خاطر داشته باشید که کاراکتر خالی blank ، که با فشار دادن spacebar روی صفحهکلید ایجاد میشود، یک کاراکتر مجاز در ++C است).
مثلاً برای اینکه در خروجی 6, 2, 15 به هم چسبیده نباشد و بهصورت زیر نمایش داده نشود:
میتوان از یک کاراکتر خالی (blank) بهعنوان کاراکتر ثابت بین اعداد به ترتیب ذیل استفاده کرد:
خروجی دستور فوق چنین است:
اگر فضای بیشتری بین اعداد موردنظر باشد از یک رشته (String) که دنبالهای از کاراکتر خالی است و در نماد " " محصور میشود استفاده میکنند.
خروجی دستور فوق چنین است:
بهعنوانمثال دیگر، برای ایجاد خروجی زیر:
* * * * * * * *
* * * * * * * * *
* * * * * * * *
از دستورات زیر میتوان استفاده کرد:
کلیه کاراکترهای خالی و ستارهها در گیومه مضاعف " " محصور شدهاند، بهطوریکه به همان صورت که در برنامه نوشته شدهاند چاپ میشوند. endl های اضافی، بین سطرها سطر خالی اضافه میکنند.
اگر بخواهیم کاراکترهای خالی چاپ شوند، باید آنها را در گیومه قرار دهیم. خروجی دستورالعمل
چنین است:
**
علیرغم کاراکترهای خالی که در دستورالعمل آورده شده است، ستارهها کنار هم چاپ شدهاند، زیرا کاراکترهای خالی داخل گیومه قرار ندارند.
شکلدهندهها (Manipulators)
تاکنون از شکل دهندة endl برای خاتمه دادن به خط استفاده کردهایم. در ++C شکلدهندهها نظیر توابع عمل میکنند و درعینحال در نقش یک شیء یا data object ظاهر میشوند. نظیر یک تابع سبب وقوع عملی میشوند و نظیر یک شیء دادهای میتوانند بهصورت عملوندهای عملگر اضافهگر << ظاهر شوند.
ذیلاً چهارچوب دستوری تجدیدنظر شدة دستورالعمل خروجی داده میشود که علاوه بر عبارات و رشتهها شامل شکلدهندههای داده نیز است.
دستورالعمل خروجی OutputStatement
کتابخانه استاندارد ++C تعداد زیادی شکلدهنده را فراهم کرده است، لیکن فعلاً فقط به بررسی سه تای آن setw, endl و setprecision میپردازیم. وقتی فایل سرفصل iostream.h توسط # include به برنامه اضافه میشود، endl بهخودیخود معرفی میگردد. برای شکلدهندههای دیگر، setprecision, setw لازم است که فایل سرفصل iomanip.h توسط # include به برنامه اضافه شود.
شکلدهنده setw (به معنی تثبیت عرض (set width)) کنترل اینکه چند ستون خروجی توسط داده بعدی اشغال شود را به عهده دارد. (setw فقط برای شکلدهی دادههای عددی و رشتهها به کار میرود و نه برای داده از نوع char) پارامتر setw یک عبارت صحیح به نام مشخصهساز عرض میدان است. تعداد ستونهای موردنظر میدان خوانده میشود. داده بعدی که قرار است با کنترل setw چاپ شود از سمت راست میزان میشود یعنی با کاراکتر خالی (blank) از سمت چپ پر میشود. به مثالهای ذیل توجه کنید:
در عبارت اول هرکدام از مقادیر مشخصهساز عرض میدان بهاندازهای هستند که حداقل یک فاصله بین دادهها وجود دارد. در عبارت دوم مقادیر مشخصهساز میدان دقیقاً به اندازه ستونهای مورد نیاز داده میباشند. مثلاً برای ans که دو رقمی است دقیقاً دو ستون در نظر گرفته شده است و الی آخر. واضح است که خروجی مفهوم و خوانا نیست. بهتر است که عرض میدان بزرگتر از حداقل اندازه موردنیاز داده باشد بهطوریکه مقداری فضا بین مقادیر داده خالی باقی بماند. در عبارت سوم جاهای خالی بیشتری به منظور خواناتر شدن خروجی در نظر گرفته شده است. در عبارت پنجم جای کافی برای ans در نظر گرفته نشده است و مقدار مشخصهساز عرض میدان کمتر از مقدار موردنیاز برای نمایش ans یا 33 است. در این حالت بهطور خودکار فضا برای داده منظور میشود.
تعیین عرض فیلد عمل یکباره است و فقط برای داده بعد از خود عمل میکند. بعد از چاپ داده بعدی مقدار عرض فیلد به صفر تغییر میکند که به معنی "افزایش اندازه عرض فیلد به مقدار موردنیاز داده بعدی" است.
در دستورالعمل:
مقدار عرض میدان بعد از چاپ ans به صفر تثبیت میشود و در نتیجه خروجی ذیل چاپ میشود.
که در آن نشانگر جای خالی است.
تعیین عرض میدان برای دادههای اعشاری نیز امکانپذیر است. فقط باید توجه داشت که ممیز نیز در شمارش ستونهای موردنیاز در نظر گرفته شود. مقدار 4.85 چهار ستون اشغال میکند. اگر x متغیر اعشاری باشد که در آن 4.85 ذخیره شده است را در نظر بگیریم دستورالعمل:
خروجی ذیل را ایجاد میکند:
در خط سوم اندازه عرض میدان یعنی 3 کافی نیست لذا اندازه میدان بهطور خودکار افزایش یافته است تا بتواند عدد را در خود جا دهد.
نکات متعددی درباره چاپ اعداد اعشاری وجود دارد:
اول آنکه اعداد بزرگ اعشاری بهصورت مهندسی با علامت E نمایش داده میشوند.
مثلاً مقدار 1235456789.5 در بعضی از کامپیوترها بهصورت 1.234567E+08 چاپ
میشود.
دوم آنکه اگر عدد کامل و بعد از ممیز صفر باشد. باشد ++C ممیز را چاپ نخواهد کرد مثلاً حاصل تقسیم 2.0/ 1900عدد 95.0 است که بهصورت 95 چاپ خواهد شد.
سوم آنکه اغلب میخواهیم مقدار ارقام بعد از ممیز را از قبل مشخص کنیم. مثلاً در چاپ معمول نمرات دانشجویان به بیش از دو رقم بعد از ممیز نیاز نداریم. بنابراین ترجیح میدهیم که معدلهای 12.8 و 16.38753 بهصورت 12.8 و 16.39 چاپ شوند. برای نکات اول و دوم دو دستورالعمل ذیل را قبل از آنکه بخواهیم اعداد اعشاری را چاپ کنیم در برنامه ذکر میکنیم:
در دو دستورالعمل فوق بعضی از مفاهیم برنامهنویسی پیشرفته با ++C وجود دارد. اکنون خیلی زود است که راجع به جزئیات این دو دستورالعمل بحث کنیم. اما بهصورت یک دید کلی در نظر داشته باشید که setf تابعی است مربوط به cout (به نقطه بعد از cout دقت کنید). فراخوانی تابع setf در دستورالعمل اول سبب میشود که اعداد اعشاری بهصورت مهندسی چاپ نشوند. فراخوانی تابع setf در دستورالعمل دوم سبب میشود که ممیز همواره چاپ شود اگرچه عدد اعشاری کامل باشد.
برای نکته سوم که تعداد ارقام بعد از ممیز را میخواهیم از قبل مشخص کنیم، شکلدهنده setprecision این کار را انجام میدهد.
پارامتر setprecision تعداد ارقام بعد از ممیز را مشخص میکند. برخلاف setw که تنها روی داده بعدی خود اثر میکند، setprecision روی کلیه دادههای بعدی خود اثر میگذارد مگر با setprecision دیگری پارامتر آن را تغییر دهیم. در ادامه مثالهایی از setw و setprecision داده شدهاند.
در اینجا نیز درصورتیکه عرض میدانها کافی نباشد تعداد ستونهای اختصاص داده شده به داده بهخودیخود افزایش مییابد. لیکن تعداد ستونهای مخصوص قسمت اعشاری مشخصاً توسط پارامتر setprecision کنترل میشود. در جدول ذیل سه شکلدهنده موردبحث در این فصل بهطور خلاصه آورده شدهاند.
گرفتن داده در برنامه
یکی از بزرگترین مزایای کامپیوتر این است که برنامه میتواند بهدفعات با مجموعههای مختلف داده به کار گرفته شود. برای این منظور باید داده را از برنامه تا زمان اجرای برنامه جدا کنیم. آنگاه دستورالعملهای داخل برنامه مقادیر را از مجموعه داده در متغیرهای برنامه کپی میکنند. بعد از ذخیره کردن داده در متغیرها، برنامه میتواند پردازش موردنیاز را روی آنها انجام دهد.
عملگر دریافتکننده بهدفعات میتواند در یک عبارت ورودی به کار رود. در هر بار مواجهه با عملگر، داده بعدی از جریان ورودی برداشته میشود. برای مثال عبارت ذیل
و دو عبارت زیر
یکسان هستند.
هنگام واردکردن داده از طریق صفحهکلید باید از مناسب بودن نوع داده وارده با نوع متغیری که داده قرار است در آن جا بگیرد مطمئن باشیم.
توجه کنید که عملگر دریافتکننده (>>) از کلیه کاراکترهای غیرقابلچاپ و جای خالی (blank) که به کاراکترهای فضای سفید (whitespace) معروفاند، در جریان ورودی صرفنظر میکند به مثالهای زیر توجه کنید. متغیرهای i و j و k صحیحاند و متغیر ch از نوع کاراکتر و x از نوع اعشاری است.
مثال (3) نشان میدهد که هنگام ورود کاراکترها از طریق صفحهکلید گیومه لازم نیست. مثال (4) نمایانگر صرفنظر کردن از فضاهای سفید است. مثال (5) نشان میدهد که بهمحض برخورد با کاراکتر A که از نوع int نیست جریان مربوط به ورود عدد صحیح برای i خاتمه یافته تلقی میشود و کاراکتر A به متغیر دیگر یعنی ch که از نوع کاراکتر است اختصاص داده میشود. بعد از یک کاراکتر آنچه بعد از آن میآید به متغیر دیگر یعنی x نسبت داده میشود. در مثال (6) کامپیوتر منتظر میماند تا کاربر عدد سوم را نیز از طریق صفحهکلید تایپ کند. در مثال (7) بیش از متغیرهای موجود در عملگرهای دریافتکننده داده وجود دارد. کامپیوتر آنها را برای دستورات ورودی احتمالی بعدی نگه میدارد. اگر دستور ورودی دیگری در برنامه نباشد کامپیوتر از دادههای اضافی (در اینجا 15) صرفنظر میکند.
خواندن کاراکترهای داده با تابع get
فرض کنید که ch1 و ch2 دو متغیر از نوع کاراکتر باشند و دستور ذیل در برنامه در حال اجرا باشد.
و جریان ورودی نیز چنین باشد
عملگر دریافتکننده، 'R' را در ch1 ذخیره میکند و از جای خالی blank صرفنظر میکند و ‘1’ را در ch2 ذخیره میکند. (توجه کنید که '1' بهعنوان کاراکتر با 1 بهعنوان عدد صحیح کاملاً متفاوت است و نحوه ذخیره و نگهداری آن در حافظه نیز متفاوت است).
اگر بخواهیم سه کاراکتر را از جریان ورودی بخوانیم: R ، جای خالی و 1 ، چه کنیم؟ با عملگر دریافتکننده این کار غیرممکن است، زیرا کاراکترهای فضای سفید مثل جای خالی توسط عملگر فوق در نظر گرفته نمیشوند. برای این کار به جای استفاده از عملگر دریافتکننده، از تابع get استفاده میکنیم. تابع get بهصورت زیر
هر نوع کاراکتری را در جریان ورودی خواهد خواند. لذا برای واردکردن سه کاراکتر زیر
میتوانیم سه بار تابع فوق را به ترتیب ذیل فراخوانی کنیم:
یا میتوانیم بهصورت زیر از تابع get استفاده کنیم:
چند مثال دیگر در زیر آورده شدهاند. متغیرهای ch1 و ch2 و ch3 از نوع char هستند.
ممکن است در مورد علامت نقطه. (dot) در دستورات بالا دچار سؤال شده باشید. در ++C بعضی از انواع داده نظیر istream و ostream توابعی دارند که منحصراً به نوع داده موردبحث وابسته هستند. لذا در فراخوانی آنها ذکر نام متغیر (در اینجا cin) ضروری است.
نکته دیگری که درخور توجه است این است که تابع get از نوع تهی است یعنی مقداری به تابعی که آن را فراخوانی میکند بازنمیگرداند ولی از طرف دیگر مقدار وارد شده از طریق صفحهکلید را در متغیر ذکر شده در لیست پارامترها وارد میکند. به تعبیری دیگر از طریق لیست پارامترها به تابعی که آن را فراخوانی کرده است مقداری باز میگرداند.
نکتهای که باید به خاطر سپرد این است که از پارامترها برای ارسال یا دریافت داده به تابع میتوان استفاده کرد.
حل مسئله ـ مطالعه یک مورد
محاسبه قیمت رنگآمیزی سطح جانبی یک مخروط
مسئله: میخواهیم برنامهای بنویسیم که سطح جانبی مخروطی را حساب کند و هزینه رنگآمیزی آن را برای سه رنگ مختلف چاپ کند. شکل خروجی و بحث راجع به مثال ذیلاً داده شدهاند.
خروجی: سطح جانبی مخروط را برحسب فوت مربع و هزینه رنگآمیزی آن را برای سه رنگ مختلف چاپ کند. همه اعداد بهصورت اعشاری باشند و جوابها در خطوط مختلف چاپ شوند.
بحث: فرض کنید که اندازههای ارتفاع و قطر قاعده برحسب اینچ داده شده است و مقادیر آنها به ترتیب 30 و 8 در نظر گرفته شدهاند. قیمت رنگآمیزی با رنگ قرمز 0.1 دلار به ازای هر فوت مربع است و این قیمت برای رنگهای آبی و سبز به ترتیب0.15 و 0.18 دلار است. جهت محاسبه سطح جانبی از رابطه pr Ö r2 +h2 که در آن h ارتفاع و r شعاع قاعده است استفاده میکنیم.
اولین چیزی که برنامه باید انجام دهد تبدیل اینچ به فوت و به دست آوردن شعاع است. سپس با استفاده از فرمول بالا مساحت را حساب کند و قیمت رنگآمیزی را با ضرب سطح جانبی در قیمت رنگآمیزی به ازای واحد سطح (فوت مربع) به دست آورد. الگوریتم آن کار چنین است:
نام ثوابت و متغیرهای برنامه ذیلاً داده شدهاند.
متغیرها
اکنون برای نوشتن برنامه که آن را ConePaint مینامیم آمادهایم. لیست برنامه چنین است:
خروجی برنامه چنین است:
حل مسئله ـ مطالعه یک مورد
کارگاه چوببُری
مسئله: یک کارگاه چوببُری دو نوع تخته چوب میفروشد: تختههای نئوپانLumber و تخته چندلا Plywood . صاحب کارگاه برنامهای میخواهد که مجموع سفارشها از جانب مشتریان برای هر نوع تخته را به او بدهد. ابتدا، برنامه باید یکی از حروف L برای تخته نئوپان Lumber و P را برای تخته چندلا Plywood را بخواند تا بتواند نوع تخته را معین کند.سپس چهار عدد صحیح را باید بخواند. برای تخته نوع L، دو عدد اول عرض و ارتفاع برحسب اینچ و سومین عدد طول برحسب فوت و آخرین عدد تعداد تخته سفارش داده شده است. مثلاً داده زیر
به معنی 14 تخته به عرض 2 اینچ و ارتفاع 4 اینچ و طول 8 فوت است. برای محاسبه مقدار سفارش داده شده باید حجم چوب را حساب کنیم. واحد اندازهگیری حجم برای تخته نوع L، عبارت است از حجم تختهای مربع شکل به مساحت 1 فوت مربع به ضخامت 1 اینچ، یا 144 اینچ مکعب. برای نمونه ورودی فوق «حجم» سفارش داده شده چنین است:
برای تخته نوع P دو عدد اول صورت و مخرج کسری است که این کسر برحسب اینچ برابر ضخامت تخته است، عدد سوم طول تخته برحسب فوت و عدد آخر تعداد تختههای سفارش داده شده است. کارگاه چوببری فقط تختههای این نوع را در عرض 4 فوت عرضه میکند. لذا لزومی به واردکردن عرض تخته نیست. بنابراین:
به معنی 6 تخته به ضخامت ¾ اینچ و طول 8 فوت است. برای محاسبه مقدار سفارش داده شده باید حجم چوب را حساب کنیم. واحد اندازهگیری برای این نوع تخته عبارت است از حجم تختهای به طول 8 فوت و عرض 4 فوت و ارتفاع 1 اینچ، یا 4608 اینچ مکعب. برای نمونه ورودی فوق «حجم» سفارش داده شده چنین است:
ورودی: یک کد و چهار عدد صحیح (size1, size2, size3, numOrdered)
خروجی: یک پرامت برای ورودی
چاپ مقادیر ورودی (چاپ اکو برای اطمینان از درستی ورودی)
چاپ نتایج محاسبه مقدار سفارش داده شده برحسب واحد نظیر
ثوابت
متغیرها
نمونه اجرا شده برنامه چنین است. آنچه کاربر وارد میکند سیاه چاپ شده است.