Download presentation
Presentation is loading. Please wait.
1
(برنامهنویسی به زبان (C/C++
یَرفعُ اللهَ الذینَ آمَنوُا مِنکُم وَ الذینَ اوُتوالعِلم دَرَجَات مبانی کامپیوتر و برنامهنویسی (برنامهنویسی به زبان (C/C++ مدرس: دکتر سهیل افراز عضو هیات علمی دانشگاه آزاد اسلامی اردبیل
2
مراجع «مبانی کامپیوتر و الگوریتم»، عین الله جعفرنژاد قمی، انتشارات جهاد دانشگاهی C/C++ How to program, Deitel and Deitel, 6th ed, Prentice Hall ابزار Visual Studio – C++ (6, 2003, 2005, 2008, 2010, 2012)
3
ارزیابی درس امتحان پایان ترم: 10 نمره امتحان میان ترم: 5 نمره
امتحان پایان ترم: نمره امتحان میان ترم: نمره تکالیف و پروژه نهایی: 5 نمره نظم و فعالیت کلاسی
4
مبانی کامپیوتر و برنامه سازی
فصل اول : مبانی کامپیوترها مدرس : دکتر سهیل افراز
5
1-1 تعاریف اولیه کامپیوتر الگوریتم برنامه کامپیوتری
1-1 تعاریف اولیه کامپیوتر وسیلهای است که دادهها و دستورالعملها را از انسان دریافت کرده و پس از اجرای دستورالعملها برروی داده ها، دادههای حاصل را به انسانها باز میگرداند. به اجرای دستورالعملها برروی دادهها پردازش گفته میشود. الگوریتم دستورالعملهایی که برای کامپیوتر نوشته میشود را الگوریتم گوییم . برنامه کامپیوتری به تشریح الگوریتمها برای کامپیوتر با استفاده از یک زبان برنامه سازی گفته میشود.
6
1-1 تعاریف اولیه زبان برنامه سازی
1-1 تعاریف اولیه زبان برنامه سازی زبانی است که برای کامپیوتر قابل فهم بوده و الگوریتمها با استفاده از آن به کامپیوتر داده میشوند. این زبانها به سه دسته تقسیم میگردند : زبانهای سطح پایین : که به آن زبان ماشین نیز گفته میشود، مستقیما به زبان خود کامپیوتر (یعنی زبان صفر و یک) نوشته میشود و توسط کامپیوتر قابل اجرا میباشد. زبانهای سطح بالا : این زبانها بسیار نزدیک به زبان انسان هستند. مثلا : If (a > b) then c = c + 1; برای تبدیل این زبان به زبان ماشین نیاز به مترجم داریم : کامپایلر (Compiler) : ابتدا کل برنامه زبان سطح بالا را بررسی کرده و درصورت نبود خطا کل آن را به زبان ماشین تبدیل میکند. اکنون برنامه آماده اجرا است. مفسر (Interpreter) : برنامه زبان سطح بالا را دستور به دستور به زبان ماشین تبدیل و همزمان آن را اجرا میکند. زبانهای بسیار سطح بالا : زبانهای خاص منظورهای که برای عملیات خاص طراحی شدهاند همانند زبان PROLOG برای هوش مصنوعی و یا SQL برای پایگاه داده ها.
7
2-1 تاریخچه کامپیوتر کامپیوترهای نسل اول کامپیوترهای نسل دوم
2-1 تاریخچه کامپیوتر کامپیوترهای نسل اول ابداع در اوایل دهه 1950 و از لامپ خلاء بعنوان جزو اصلی خود استفاده میکردند. کامپیوترهای نسل دوم ابداع در اوایل دهه 1960و ویژگی مهم آنها استفاده از ترانزیستور بود. کامپیوترهای نسل سوم در سال 1964 با ابداع مدارات مجتمع IC که صدها ترانزیستور را در یک فضای کوچک جای میداد، ایجاد شدند. نسل چهارم کامپیوترها در اواسط دهه 1970 با ابداع مدارات مجتمع با فشردگی بالا ایجاد شدند. نسل پنجم کامپیوترها یا نسل کامپیوترهای هوشمند که قادر به انجام اعمالی همانند استنتاج و استدلال مانند انسانها باشند.
8
3-1 انواع کامپیوتر کامپیوترهای بزرگ (mainframe)
3-1 انواع کامپیوتر کامپیوترهای بزرگ (mainframe) این کامپیوترها از سرعت و قدرت بالایی برخوردارند و معمولا در سازمانهای بزرگ و برای محاسبات سنگین استفاده میشوند. دستهای از این کامپیوترها که دارای توان بسیار بالای محاسباتی هستند به ابرکامپیوتر (supercomputer) موسومند. کامپیوترهای کوچک (minicomputer) در اواخر دهه 1950 کامپیوترهای کوچک وارد بازاز شدند که توان محاسباتی کمتری داشتند و توسط سازمانهای کوچکتر مورد استفاده قرار میگرفتند. ریزکامپیوتر (microcomputer) در آغاز دهه 1980 ریزکامپیوترها یا کامپیوترهای شخصی با قیمت پایین و حجم بسیار کوچک وارد بازار شدند و مورد استقبال مردم و افراد عادی قرار گرفتند.
9
4-1 اجزای کامپیوتر کامپیوتر از دو قسمت اصلی تشکیل شده است
4-1 اجزای کامپیوتر کامپیوتر از دو قسمت اصلی تشکیل شده است سخت افزار (Hardware) : کلیه دستگاههای الکتریکی، الکترونیکی و مکانیکی تشکیل دهنده یک کامپیوتر را سخت افزار آن میگوییم. نرم افزار (Software) : مجموعه برنامههایی هستند که برای یک کاربرد خاص نوشته شدهاند و بدون آنها سخت افزار قادر به کاری نیست.
10
1-4-1 سخت افزار کامپیوتر کنترل واحد ورودی محاسبه و منطق حافظه اصلی
سخت افزار کامپیوتر کنترل واحد ورودی محاسبه و منطق حافظه اصلی واحد خروجی حافظه جانبی
11
1-4-1 سخت افزار کامپیوتر واحد ورودی واحد خروجی واحد محاسبه و منطق
سخت افزار کامپیوتر واحد ورودی وظیفه این بخش دریافت دادهها از محیط خارج و انتقال آنها به کامپیوتر میباشد. دستگاههای ورودی مهم عبارتند از : صفحه کلید، ماوس، صفحه لمسی (touch screen)، قلم نوری، اسکنر، دیجیتایزر و ... واحد خروجی این بخش وظیفه انتقال اطلاعات از کامپیوتر به محیط خارج را بعهده دارد و مهمترین دستگاههای خروجی عبارتند از : صفحه نمایش(Monitor)، چاپگر، رسام، بلندگو و ... واحد محاسبه و منطق مغز اصلی کامپیوتر است که اعمال اصلی همچون جمع، ضرب، تفریق، تقسیم، مقایسه دو مقدار و ... در آن انجام میپذیرد. واحد کنترل این بخش و ظیفه کنترل سایر بخشها را بعهده دارد و تصمیم میگیرد کدام عمل در چه زمانی صورت پذیرد این بخش بهمراه واحد محاسبه و منطق تشکیل واحد پردازش مرکزی CPU (Central Processing Unit) را میدهند.
12
1-4-1 سخت افزار کامپیوتر واحد حافظه اصلی 1 KiloByte or 1K = 1024 Byte
سخت افزار کامپیوتر واحد حافظه اصلی این واحد وظیفه نگهداری اطلاعات (شامل دادهها و برنامه ها) را بعهده دارد. در واقع هر برنامهای برای اجرا، ابتدا باید بهمراه دادههای مورد نیاز وارد حافظه اصلی گردد.حافظه اصلی به دو دسته اصلی تقسیم میگردد : - حافظه با دستیابی تصادفی (RAM Random Access Memory) این حافظه قابل خواندن و نوشتن میباشد و برای ذخیره اطلاعات کاربران بکار میرود. - حافظه فقط خواندنی (ROM Read Only Memory) این حافظه فقط قابل خواندن است و محتویات آن قابل تغییر نیست. این حافظه معمولا در کارخانه سازنده پر شده و حاوی دستورالعملهای لازم برای راه اندازی اولیه کامپیوتر میباشد. حافظه از واحدهای کوچکی بنام بیت(Bit) تشکیل شده است که هر بیت قابلیت نگاهداری یک 0 یا 1 را در خود دارد. به هر 8 بیت یک بایت(Byte) گفته میشود که واحد اندازه گیری حافظه است. به هر 2 یا 4 بایت، یک کلمه(Word) میگوییم. علاوه براین داریم : 1 KiloByte or 1K = 1024 Byte 1 MegaByte or 1M = 1024 KiloByte = Byte 1 GigaByte or 1G = 1024 MegaByte = Byte 1 TeraByte or 1T = 1024 GigaByte
13
1-4-1 سخت افزار کامپیوتر حافظه جانبی
سخت افزار کامپیوتر حافظه جانبی از آنجا که با خاموش شدن کامپیوتر اطلاعات حافظه اصلی پاک میگردد، نیاز به حافظهای داریم که بتواند دادهها را مدت طولانیتری در خود نگاه دارد. حافظه جانبی برای نگاهداری طولانی مدت اطلاعات و همچنین جابجایی آنها بکار میرود. علاوه براین بدلیل سرعت پایینتر نسبت به حافظه اصلی، ارزانتر بوده و درنتیجه معمولا حجم آن بالا تر میباشد. اما نکته مهم آن است که اطلاعات برای پردازش ابتدا باید وارد حافظه اصلی گردند.در حال حاضر حافظههای جانبی مهم عبارتند از : دیسکهای مغناطیسی (Hard Disk and Floppy Disk) دیسکهای نوری (CD and DVD) Flash Disk
14
نرم افزار کامپیوتر نرم افزار کامپیوتر به دو دسته اصلی تقسیم میگردد : نرم افزارهای کاربردی : نرم افزارهایی هستند که برای یک کاربرد خاص و رفع یک نیاز مشخص کاربران نوشته شده اند. مانند سیستمهای حسابداری، دبیرخانه، سیستم انتخاب واحد دانشگاهی، انواع بازیها نرم افزارهای سیستمی : نرم افزارهایی هستند که برای ایجاد و یا اجرای برنامههای کاربردی نوشته میشوند. مهمترین برنامه سیستمی، سیستم عامل است. سیستم عامل نرم افزاری است که ارتباط بین سخت افزار و کاربران (یا برنامههای کاربردی کاربران) را فراهم میسازد. در حقیقت سیستم عامل مدیریت منابع سخت افزاری یک کامپیوتر را بعهده دارد. Windows : بیشتر در منازل و محیطهای اداری مورد استفاده قرار میگیرد Linux : بیشتر در محیطهای دانشگاهی و بعنوان سرور استفاده میشود. Unix : نیز بیشتر در کامپیوترهای بزرگ نصب میشود.
15
مبانی کامپیوتر و برنامه سازی
فصل دوم : نحوه نمایش اطلاعات در کامپیوتر مدرس : دکتر سهیل افراز
16
2 نحوه نمایش اطلاعات در کامپیوتر
2 نحوه نمایش اطلاعات در کامپیوتر اطلاعات در کامپیوتر به دو دسته اصلی تقسیم میگردند: اطلاعات کاراکتری (حرفی) : مانند :A B …Z $ ! اطلاعات عددی که خود به دو دسته اعداد صحیح و اعداد اعشاری تقسیم میگردند. برای نمایش اطلاعات در کامپیوتر از مبنای 2 استفاده میگردد
17
1-2 سیستم اعداد مبنای 10 ، مبنای مورد استفاده انسانها در ریاضیات
1-2 سیستم اعداد مبنای 10 ، مبنای مورد استفاده انسانها در ریاضیات در ریاضیات متداول هر عدد N بصورت زیر تفسیر میگردد : N = (an-1 an-2 … a2 a1 a0 )10 = a0 × a1 × a2 × … an-1 × 10n-1 بعنوان مثال عدد 3482 بصورت زیر تفسیر میگردد : (3482 )10 = 2 × × × × 103 در سیستم دهدهی نیاز به 10 رقم (از 0 تا 9) داریم. می توان اعداد را در هر مبنای دلخواه دیگری مانند b نیز نشان داد در اینصورت هر عدد مانند N در مبنای b بصورت زیر تفسیر میگردد : N = (an-1 an-2 … a2 a1 a0 )b = a0 × b0 + a1 × b1 + a2 × b2 + … an-1 × bn-1 کاملا واضح است که در مبنای b نیاز به b رقم (از 0 تاb-1 ) خواهیم داشت. بعنوان مثال یک عدد در مبنای 6 از ارقام 0..5 تشکیل میگردد، بنابراین (341)6 یک عدد درست است اما (592)6 غیر قابل قبول میباشد.
18
2-2 تبدیل مبناها برای تبدیل یک عدد از مبنای 10 به هر مبنای دلخواه b، از روش تقسیمات متوالی استفاده میگردد (941)10 = (?)6 941 6 936 156 6 156 26 6 5 24 4 6 2 4 (941)10 = (4205)6
19
2-2 تبدیل مبناها برای تبدیل از مبنای b به مبنای 10 کافی است ارقام عدد مورد نظر را در ارزش مکانی آنها ضرب و سپس با یکدیگر جمع کنیم . (4205)6 = (?)10 (4205)6 = 5 × × × × 63 = = (941)10
20
3-2 مبنای 2 و اهمیت آن مبنای 2 اهمیت بسیار زیادی در کامپیوترهای دیجیتال دارد. چراکه : در مبنای 2 تنها به 2 رقم نیاز داریم،یعنی 0 و 1 آین دو رقم را میتوان توسط هر ابزاری که دارای دو حالت باشد نشان داد. مثلا یک لامپ که خاموش بودن لامپ به معنای 0 و روشن بودن آن به معنای 1 میباشد. این همان ایدهای است که کامپیوترهای دیجیتال از آن استفاده میکنند. همانطور که قبلا نیز گفته شد واحد نگهداری اطلاعات در کامپیوتر بیت میباشد که هر بیت قادر به نگهداری 0 و یا 1 است. با کنار هم قرار دادن بیتها، بایتها تشکیل میگردند و بدینوسیله اطلاعات مورد نظر در قالب بایتها تشکیل میگردند.
21
3-2 مبنای 2 و اهمیت آن تبدیل اعداد از مبنای 10 به 2 و بالعکس بسیار ساده و همانند سایر مبناها است. تبدیل از مبنای 2 به 10 ( )2 = (?)10 ( )2 = 1 × × × × × × × × 27 = = (201)10 تبدیل از مبنای 10 به مبنای 2 (486)10 = (?)2
22
3-2 مبنای 2 و اهمیت آن 486 2 486 243 2 242 121 2 120 60 2 1 60 30 2 1 30 15 2 14 7 2 6 3 2 1 2 1 2 1 1 1 (486)10 = ( )2
23
4-2 مبناهای 8 و 16 و کاربرد آنها
4-2 مبناهای 8 و 16 و کاربرد آنها مشکل اصلی در مبنای 2 اندازه بزرگ اعداد است. بعنوان مثال عدد486 که در مبنای 10 تنها 3 رقم دارد، تبدیل به یک عدد 9 رقمی در مبنای 2 شده است. این مسئله باعث میشود که محاسبه در مبنای 2 برای انسانها بسیار مشکل شود و معمولا برنامهنویسان علاقه چندانی به مبنای 2 ندارند. مبنای 8 نیز همانند سایر مبناها میتواند مورد استفاده قرار گیرد و در ظاهر تفاوتی با سایر مبناها ندارد. اما ویژگی جالب این مبنا در تبدیل ساده آن به مبنای 2 و بالعکس است. همانطور که میدانیم در مبنای 8 تنها ارقام 0 تا 7 استفاده میشوند. از طرف دیگر اگر یک عدد در مبنای 2 با حداکثر 3 رقم را درنظر بگیریم، در مییابیم که میتوان 000 = 0, 001=1, 010=2, … , 111=7 را با آن نشان داد. بنابراین میتوان نتیجه گرفت که هر 3 رقم در مبنای 2، برابر است با 1 رقم در مبنای 8 و بالعکس. این نتیجه گیری تبدیل این دو مبنا را به یکدیگر ساده میکند.
24
4-2 مبناهای 8 و 16 و کاربرد آنها
4-2 مبناهای 8 و 16 و کاربرد آنها تبدیل از مبنای 2 به 8 = (256)8 2 5 6 تبدیل از مبنای 8 به 2 ( )8 = ( )2 010 001 111
25
4-2 مبناهای 8 و 16 و کاربرد آنها
4-2 مبناهای 8 و 16 و کاربرد آنها اکثر برنامهنویسان کامپیوتر ترجیح میدهند از مبنای دیگری بنام مبنای 16 استفاده نمایند. این مبنا نیز همانند مبنای 8 بسادگی قابل تبدیل به مبنای 2 است، اما اعداد آن به ارقام کمتری نیاز دارند. در این مبنا نیاز به 16 رقم داریم درحالیکه ارقام موجود فقط 10 تا است. بهمین دلیل از حروف A تا F برای ارقام 10 تا 15 استفاده میگردد.یعنی ارقام عبارتند از : A B C D E F تبدیل اعداد از مبنای 2 به 16 و بالعکس ازهمان روش گفته شده برای مبنای 8 استفاده مینماییم با این تفاوت که هر رقم در مبنای 16 معادل 4 رقم در مبنای 2 است.
26
4-2 مبناهای 8 و 16 و کاربرد آنها
4-2 مبناهای 8 و 16 و کاربرد آنها تبدیل از مبنای 2 به 16 = (6B9)16 6 B 9 تبدیل از مبنای 16 به 2 ( A 3 E )16 = ( )2 1010 1110 0011
27
5-2 نمایش اعداد صحیح اعداد صحیح در کامپیوتر با استفاده از مبنای 2 نمایش داده میشوند. برای نمایش اعداد صحیح از 1 یا 2 بایت و یا بیشتر (بسته به اندازه عدد) استفاده میگردد. چنانچه قصد ذخیره اعداد صحیح مثبت را داشته باشیم، با استفاده از 1 بایت میتوان اعداد 0 تا 255 را ذخیره کرد. بنابراین برای 1 بایت، بزرگترین عدد قابل ذخیره برابر است با 28 – 1 = 255. با استدلال مشابهی چنانچه از 2 بایت یا 16 بیت استفاده گردد، بزرگترین عدد قابل ذخیره برابر 216 – 1 = خواهد بود. اما مشکل آنستکه اعداد منفی را چگونه ذخیره نماییم؟ برای این کار چندین روش وجود دارد که هریک را جداگانه بررسی مینماییم.
28
1-5-2 استفاده از بیت علامت دو مقدار متفاوت +0 و -0 وجود دارد.
استفاده از بیت علامت در این روش سمت چپ ترین بیت برای علامت عدد درنظر گرفته میشود و سایر بیتها مقدار عدد رانشان میدهند. 0 بودن بیت علامت بمعنای مثبت بودن و 1 بودن آن به معنای منفی بودن عدد میباشد. با داشتن 8 بیت میتوان اعداد بین -127 … +127 را نمایش داد. +83 -83 این روش دو مشکل اصلی دارد: دو مقدار متفاوت +0 و -0 وجود دارد. برای عمل جمع و تفریق نیاز به دو مدار جداگانه داریم.
29
استفاده از متمم 1 در این روش اعداد مثبت بصورت معمولی نمایش داده میشوند. اما برای نمایش اعداد منفی، ابتدا قدر مطلق آن را (بصورت عدد مثبت) نمایش داده و سپس کلیه 0ها را به 1 و بالعکس تبدیل مینماییم. 1 1 1 1 1 1 1 1 + 83 - 83 با توجه به محدودیت تعداد بیتها و جلوگیری از تداخل اعداد مثبت و منفی، برای اعداد مثبت باید بیت سمت چپ 0 باشد و بهمین دلیل بازه اعداد مجاز از -127 تا +127 است. خوشبختانه اکنون تنها نیاز به یک مدار برای عمل جمع و تفریق است اما هنوز هم دو نمایش مختلف برای +0 و-0 وجود دارد. +0 -0
30
استفاده از متمم 2 در این روش برای نمایش اعداد منفی ابتدا متمم 1 آنها را محاسبه و سپس آن را با 1 جمع میکنیم. +90 -90 بازه اعداد مجاز در این روش از -128 تا +127 است.
31
3-5-2 استفاده از متمم 2 تنها یک نمایش برای +0 و -0 وجود دارد.
استفاده از متمم 2 این روش هردو مشکل روشهای قبل را حل میکند. چرا که : تنها یک نمایش برای +0 و -0 وجود دارد. +0 -0 1 برای عمل تفریق میتوان از همان مدار جمع استفاده کرد. بدین ترتیب که ابتدا عدد دوم را به روش متمم 2 منفی کرده و با عدد اول جمع میکنیم. 53 – 22 = 53 + (-22) = 31 ( ) – ( ) = ( ) + ( ) = 1( ) 38 – 60 = 38 + (-60) = -22 ( ) – ( ) = ( ) + ( ) = ( )
32
6-2 نمایش مقادیر اعشاری نمایش اعداد اعشاری در کامپیوتر مشکلتر است.
6-2 نمایش مقادیر اعشاری نمایش اعداد اعشاری در کامپیوتر مشکلتر است. ما معمولا اعداد اعشاری را به شکل ممیز ثابت نشان میدهیم : اما شکل دیگری نیز وجود دارد که به آن نماد علمی یا ممیز شناور گفته میشود و به شکل زیر است : × 100 × 101 × 102 × 10-2 همانطور که دیده میشود، مکان ممیز در این نمایش شناور است و میتواند در هر نقطهای قرار گیرد و البته توان نیز باید متناسب با آن تنظیم گردد. نماد علمی نرمال به حالتی گفته میشود که قسمت صحیح فقط دارای یک رقم غیر صفر باشد. برای نمایش اعداد اعشاری در کامپیوتر استانداردهای مختلفی وجود دارد که همگی در اصول مشترکند و تنها تفاوتهایی در جزئیات دارند.
33
IEEE Standard 754 Floating Point Numbers
6-2 نمایش مقادیر اعشاری ما در اینجا از یک روش استاندارد متداول که توسط انجمن معتبر IEEE ارائه شده است، استفاده میکنیم. این استاندارد بنام IEEE Standard 754 Floating Point Numbers شناخته شده است. برای اطلاعات بیشتر به سایت مراجعه نمایید. در استاندارد مورد نظر هر عدد اعشاری در یک کلمه 32 بیتی ذخیره میگردد. ساختار هر عدد بصورت زیر است: 1 8 23 s e m علامت توان مانتیس
34
6-2 نمایش مقادیر اعشاری برای ذخیره یک عدد اعشاری باید ابتدا آن را به نماد علمی نرمال در مبنای 2 تبدیل کنیم. سپس آن را به شکل زیر ذخیره میکنیم : علامت عدد را در s قرار میدهیم (مثبت = 0 و منفی = 1) توان را در قسمت e قرار میدهیم که یک عدد مثبت بدون علامت است(بین 0 تا 255). نکته مهم آنکه از آنجا که ممکن است توان مثبت یا منفی باشد، ابتدا 127 واحد به توان اضافه میکنیم و سپس آن را ذخیره میکنیم. بنابراین e = 131 باشد بدین معناست که توان برابر 4 بوده است و e=120 به معنای توان برابر -7 است. البته توانهای e=255 و e=0 برای منظورهای خاصی در نظر گرفته شدهاند که بعدا توضیح داده خواهند شد. قسمت پایه عدد را در مانتیس قرار میدهیم. نکته جالب آن است که چون در نمایش نرمال قسمت صحیح تنها یک رقم غیرصفر دارد و در نمایش دودویی نیز تنها رقم غیر صفر، رقم 1 میباشد؛ بنابراین تنها قسمت اعشاری در مانتیس ذخیره میگردد و قسمت صحیح بطور پیش فرض 1 درنظر گرفته میشود. این باعث میشود که یک بیت در ذخیره سازی صرفه جویی گردد.
35
6-2 نمایش مقادیر اعشاری مثال: عدد 486 را بصورت دودویی اعشاری ذخیره نمایید. ابتدا آن را به مبنای 2 تبدیل میکنیم. (486)10 = ( )2 اکنون داریم : = × 28 s : e : = 135 = m : بنابراین جواب نهایی بصورت زیر خواهد شد :
36
6-2 نمایش مقادیر اعشاری مثال 2: عدد را بصورت دودویی اعشاری ذخیره نمایید. ابتدا عدد 121 را به مبنای 2 میبریم: (121)10 = ( )2 واما برای تبدیل قسمت اعشاری باید از روش ضربهای متوالی استفاده نماییم. بدین صورت که ابتدا آن را در 2 ضرب کرده و قسمت صحیح حاصلضرب را ذخیره میکنیم. همین عمل را مجددا برروی قسمت اعشاری حاصلضرب انجام میدهیم و اینکار را تا صفر شدن قسمت اعشاری و یا پر شدن تعداد بیتهای کلمه موردنظر (23 بیت) تکرار میکنیم. در پایان ارقام ذخیره شده را از اول به آخر به ترتیب پس از ممیز قرار میدهیم. داریم : × 2 = قسمت صحیح = 1 × 2 = قسمت صحیح = 0 × 2 = قسمت صحیح = 1 0.125 × 2 = قسمت صحیح = 0 0.25 × 2 = قسمت صحیح = 0 0.5 × 2 = قسمت صحیح = 1 ( )10 = ( )2
37
6-2 نمایش مقادیر اعشاری بنابراین عدد نهایی بصورت زیر درخواهد آمد :
6-2 نمایش مقادیر اعشاری بنابراین عدد نهایی بصورت زیر درخواهد آمد : ( )10 = ( )2 = ( × 26)2 s : 1 e : = 133 = m : 1 نکته مهم : توجه داشته باشید که به دلیل محدود بودن اندازه مانتیس (23 بیت)، در هنگام تبدیل اعداد از مبنای 10 به مبنای 2 مجبور هستیم عمل ضرب را تا زمانیکه بیتها پر شوند ادامه دهیم. این مسئله باعث میشود که مقدار تقریبی اعداد در کلمه 32 بیتی ذخیره گردد. بنابراین در هنگام کار با اعداد اعشاری به این مسئله توجه کنید
38
6-2 نمایش مقادیر اعشاری یک عدد اعشاری ذخیره شده به فرم استاندارد موردنظر به شکل زیر تفسیر میگردد : اگر 0<e<255 آنگاه (-1)s × (1.m) × 2e = عدد اگر e=0 و m غیر صفر باشد آنگاه (-1)s × (0.m) × 2e = عدد که به آن عدد غیرنرمال (unnormalized) گفته میشود. دلیل این مسئله آنست که با کوچکترین توان ممکن یعنی -126 بتوان کوچکترین مانتیس ممکن (بدون اضافه شدن 1) را برای نمایش اعداد کوچک داشت. اگر e=0 و m=0 آنگاه = 0 عدد که البته بسته به میزان s مقدار آن +0 یا -0 خواهد بود. اگر e=255 و m غیرصفر باشد آنگاه حاصل یک عدد نیست (NaN یا Not a Number) اگر e=255 و m=0 و s=0 آنگاه عدد برابر مثبت بینهایت است. اگر e=255 و m=0 و s=1 آنگاه عدد برابر منفی بینهایت است.
39
7-2 نمایش کاراکترها در کامپیوتر
7-2 نمایش کاراکترها در کامپیوتر در کامپیوترها علاوه بر اطلاعات عددی، گاهی لازم است که حروف و علائم نیز ذخیره گردد که به آنها کاراکتر میگوییم. برای ذخیره سازی کاراکترها به هریک از آنها یک کد عددی نسبت داده شده است و در حقیقت کد عددی هر کاراکتر در کامپیوتر ذخیره میگردد. در گذشته پر کاربردترین کد مورد استفاده، کد ASCII بود که برای نمایش هر کاراکتر از یک بایت استفاده میکرد. از آنجا که هر بایت میتواند بین 0 تا 255 تغییر کند، بنابراین تا 256 کاراکتر قابل تعریف است. از این بین کدهای بین 0 تا 127 بصورت استاندارد برای علائم و حروف انگلیسی تعریف شده است و کدهای بالاتر از 127 برای هر کشور خالی گذاشته شده است تا بتوانند حروف خاص زبان خود را تعریف کنند. بعنوان مثال به کدهای ASCII زیر دقت کنید: A=65 B=66 C=67 … 0=48 1=49 … اما امروزه و بدلیل ارتباطات گسترده جهانی از طریق اینترنت، نیاز به تعریف یک کد بین المللی میباشد که کلیه زبانهای جهانی را دربرگیرد. چراکه متنی که در کشور دیگری به زبان فارسی نوشته میشود باید در ایران هم قابل خواندن باشد و لازمه این مسئله یکسان بودن کدها است. بهمین دلیل اخیرا کد بین المللی بنام Unicode ابداع شده است که تقریبا تمام زبانهای زنده دنیا (از جمله زبان فارسی) را دربر میگیرد. البته این کد از 2 بایت برای نمایش هر کاراکتر استفاده میکند و سیستم عاملهای جدید همگی از آن حمایت میکنند.
40
مبانی کامپیوتر و برنامه سازی
فصل سوم :الگوریتم مدرس : دکتر سهیل افراز
41
3 الگوریتم الگوریتم هر الگوریتم باید دارای شرایط زیر باشد
3 الگوریتم الگوریتم مجموعه محدودی از دستورالعملها است که اگر به ترتیب دنبال شوند موجب انجام کار خاصی میگردند. هر الگوریتم باید دارای شرایط زیر باشد ورودی : یک الگوریتم میتواند صفر یا چند ورودی داشته باشد که از محیط خارج تامین میگردد. خروجی : الگوریتم باید یک یا چند کمیت خروجی داشته باشد. قطعیت : هر دستورالعمل باید واضح و بدون ابهام باشد. کارایی : هر دستورالعمل باید قابل اجرا باشد. محدودیت : در تمام حالات، الگوریتم باید پس از طی مراحل محدودی خاتمه یابد.
42
3 الگوریتم در علم کامپیوتر، ما معمولا با یک مسئله مواجهیم که باید آن را حل کنیم. این مسئله میتواند در زمینههای مختلفی همچون علمی، اقتصادی، ریاضی، فنی و ... باشد. معمولا برای حل یک مسئله، مراحل زیر طی میگردد تعریف مسئله بصورت جامع و دقیق (شامل تعریف ورودیها و خروجیها) بررسی راه حلهای مختلف برای حل مسئله انتخاب مناسبترین راه حل و تهیه یک الگوریتم برای آن آزمایش الگوریتم با دادههای ورودی و اشکالزدایی آن تبدیل الگوریتم به یک زبان برنامهنویسی کامپیوتری (مانند C یا Pascal) وارد کردن برنامه به کامپیوتر و تست و اشکالزدایی آن استفاده از برنامه
43
1-3 نحوه بیان الگوریتمها چگونه میتوانیم الگوریتمها را بیان کنیم؟
1-3 نحوه بیان الگوریتمها چگونه میتوانیم الگوریتمها را بیان کنیم؟ الگوریتمها باید برای انسانها قابل فهم و درک باشند و همه بتوانند به راحتی منظور نویسنده الگوریتم را درک کنند معمولا الگوریتمها به یک زبان طبیعی مانند فارسی یا انگلیسی نوشته میشود. این مسئله باعث میشود که بعضی ابهامات در درک الگوریتمها پیش آید. معمولا یکسری از توافقات و تعریفها از قبل بین طراح و خواننده الگوریتم برقرار میگردد. از آنجا که زبانهای برنامهنویسی مانند C به زبان انگلیسی خیلی نزدیک هستند، بعض از طراحان از ترکیب زبان C و انگلیسی (که به آن کد شبه C میگویند) برای بیان الگوریتم استفاده میکنند لازم بذکر است که در گذشته از نمودار گردشی (Flowchart) نیز برای بیان الگوریتمها با استفاده از شکلهای استاندارد استفاده میشد، که تنها برای الگوریتمهای کوچک مناسب بود.
44
2-3 شروع به کار با الگوریتمها
2-3 شروع به کار با الگوریتمها الگوریتمی بنویسید که ضرایب یک معادله درجه دوم بصورت زیر را دریافت و ریشههای آن را محاسبه و چاپ کند. ax2 + bx + c = 0 برای حل این مسئله ابتدا باید ضرائب a ، b و c از کاربر دریافت و در خانههای حافظه ذخیره گردند. برای اینکه بتوانیم بعدا به این خانههای حافظه مراجعه کنیم، به هریک از آنها یک نام نسبت میدهیم. به هریک از این نامها یک متغیر گفته میشود. دلیل این نامگذاری آنستکه مقادیر ذخیره شده در هریک از این خانههای حافظه میتواند تغییر کند. گرچه انتخاب نام بعهده خودشماست و میتواند هر چیزی باشد، ولی توصیه میگردد از اسامی بامعنی و متناسب استفاده گردد. این کار سبب میشود که خواندن و درک الگوریتم شما برای سایر افراد نیز ساده گردد. اکنون به قراردادهای زیر توجه کنید : برای دریافت اطلاعات از کاربر از دستور بخوان استفاده میگردد. برای نوشتن اطلاعات در خروجی از دستور چاپ کن استفاده میگردد. برای انتساب یک مقدار به یک متغیر از علامت ← استفاده میشود.
45
2-3 شروع به کار با الگوریتمها
2-3 شروع به کار با الگوریتمها a و b و c را بخوان delta ← b2 – 4ac و x1و x2 را چاپ کن توقف کن
46
3-3 مکانیزم شرط مکانیزم شرط هنگامی استفاده میشود که قصد داریم درستی یا نادرستی یک عبارت رابررسی کرده و متناسب با نتیجه بررسی شرط، عملیات خاصی را انجام دهیم و یا از انجام بعضی عملیات صرفنظر کنیم. شکل کلی این دستور به شکل زیر است اگر (عبارت شرطی) آنگاه دستورات این دستور به شکل زیر نیز استفاده میشود: اگر (عبارت شرطی) آنگاه دستورات1 درغیر اینصورت دستورات 2
47
3-3 مکانیزم شرط a و b و c را بخوان
3-3 مکانیزم شرط a و b و c را بخوان اگر ( a = 0 ) آنگاه چاپ کن ”معادله درجه 2 نیست“ و توقف کن delta ← b2 – 4ac اگر ( delta < 0 ) آنگاه چاپ کن ”معادله جواب ندارد“ درغیراینصورت و و x1 و x2 را چاپ کن توقف کن
48
4-3 مکانیزم حلقه تکرار در بعضی الگوریتمها لازم است که عملیات مشخصی چندین بار تکرار شوند. بعنوان مثال فرض کنید قصد داریم میانگین معدلهای 100 دانشجو را محاسبه کنیم. قطعا 100 بار دستور خواندن و جمع کردن راه حل چندان مناسبی نیست. راه حل بهتر آنستکه بگونهای به مجری الگوریتم بگوییم بنحوی عمل خواندن معدل و جمع زدن آنها را 100 بار تکرار کند. حلقه تکرار مکانیزمی است که مجموعهای از دستوزات را تا زمانیکه شرط خاصی برقرار باشد تکرار میکند. حلقه تکرار به دو شکل مورد استفاده قرار میگیرد
49
4-3 مکانیزم حلقه تکرار شرط در ابتدای حلقه که مکانیزم کلی آن به شکل زیر است : تا زمانیکه (شرط مورد نظر) دستورات a تا b را تکرارکن … (a . … (b در این حالت ابتدا شرط موردنظر بررسی میگردد؛ درصورتیکه شرط برقرار نباشد به اولین دستور پس از b میرود. اما در صورتیکه شرط درست ارزیابی شود، دستورات شماره a تا b انجام میشوند و سپس مجددا به ابتدای حلقه بازگشته و عملیات فوق را مجددا تکرار میکند.
50
4-3 مکانیزم حلقه تکرار شرط در انتهای حلقه که مکانیزم کلی آن به شکل زیر است : تکرار کن …(a . … (b تا زمانیکه (شرط مورد نظر) در این روش ابتدا دستورات حلقه یکبار انجام میشوند و در پایان حلقه شرط بررسی میگردد. چنانچه شرط برقرار نبود به دستور بعدی میرود و در صورت برقرار بودن شرط، مجددا به ابتدای حلقه باز میگردد.
51
4-3 مکانیزم حلقه تکرار الگوریتمی بنویسید که یک عدد را دریافت و فاکتوریال آن را محاسبه و چاپ کند. N! = 1 × 2 × 3 × … × (N-1) × N الگوریتم n را بخوان 1← i و 1← fact تا زمانیکهn) ( i ≤ دستورات 5-4 را تکرار کن fact × i ← fact i + 1 ← i fact را چاپ کن توقف کن
52
5-3 آزمایش الگوریتم n = i = fact = خروجی = 4 4 5 3 1 2 2 1 6 24 24
5-3 آزمایش الگوریتم n را بخوان 1← i و 1← fact تا زمانیکه( i ≤ n) دستورات 5-4 را تکرار کن fact × i ← fact i + 1 ← i fact را چاپ کن توقف کن n = i = fact = خروجی = 4 4 5 3 1 2 ←اجرای الگوریتم 2 1 6 24 24
53
6-3 چند الگوریتم نمونه الگوریتمی بنویسید که n عدد را دریافت و حداکثر و حداقل آنها را چاپ کند. n را بخوان adad را بخوان min ← adad و max ← adad i ← 2 تا زمانیکه ( i ≤ n ) دستورات 6 تا 8 را تکرار کن اگر ( adad > max) آنگاه max ← adad در غیر اینصورت اگر ( adad < min ) آنگاه min ← adad i ← i + 1 max و min را چاپ کن توقف کن
54
6-3 چند الگوریتم نمونه ←اجرای الگوریتم adad را بخوان
6-3 چند الگوریتم نمونه n را بخوان adad را بخوان min ← adad و max ← adad i ← 2 تا زمانیکه ( i ≤ n ) دستورات 6 تا 8 را تکرار کن اگر ( adad > max) آنگاه max ← adad در غیر اینصورت اگر ( adad < min ) آنگاه min ← adad i ← i + 1 max و min را چاپ کن توقف کن n = i = adad = max = min = خروجی = 5 2 5 4 6 3 18 21 39 27 6 18 27 39 ←اجرای الگوریتم 18 6 39 6
55
6-3 چند الگوریتم نمونه الگوریتمی بنویسید که یک عدد را دریافت و وارون آن را محاسبه و بهمراه خود عدد چاپ کند. مثلا وارون عدد 3872 برابر 2783 میباشد. adad را بخوان اگر ( adad < 0 ) آنگاه a ← -adad در غیر اینصورت a ← adad varoon ← 0 تازمانیکه ( a > 0 ) آنگاه دستورات 5 تا 7 را تکرار کن remain ← a mod 10 a ← a / 10 varoon ← varoon × 10 + remain اگر ( adad < 0 ) آنگاه varoon ← -varoon adad و varoon را چاپ کن توقف کن
56
6-3 چند الگوریتم نمونه ←اجرای الگوریتم
6-3 چند الگوریتم نمونه adad را بخوان اگر ( adad < 0 ) آنگاه a ← -adad در غیر اینصورت a ← adad varoon ← 0 تازمانیکه ( a > 0 ) آنگاه دستورات 5 تا 7 را تکرار کن remain ← a mod 10 a ← a / 10 varoon ← varoon × 10 + remain اگر ( adad < 0 ) آنگاه varoon ← -varoon adad و varoon را چاپ کن توقف کن adad = a = varoon = remain = خروجی = -275 2 27 275 ←اجرای الگوریتم 5 57 -572 572 2 5 7
57
6-3 چند الگوریتم نمونه الگوریتمی بنویسید که مقدار x و تعداد جملات را دریافت و سپس sin(x) را با استفاده از فرمول زیر تخمین بزند: x و n را بخوان sin ← x و fact ← 1 و xPower ← x وsign ← 1 i ← 1 تازمانیکه ( i < n ) دستورات 5 تا 9 را تکرار کن fact ← fact × 2i × (2i+1) xPower ← xPower × x2 sign ← -1 × sign sin ← sin + sign × (xPower / fact) i ← i + 1 sin را چاپ کن توقف کن
58
6-3 چند الگوریتم نمونه الگوریتمی بنویسید که یک عدد را دریافت و تعیین کند که آیا اول است یا خیر؟ adad رابخوان i ← 2 و primeSw ← 1 تازمانیکه ( i ≤ root and primeSw=1 ) دستورات 5 تا 6 را تکرار کن اگر ( adad mod i = 0 ) آنگاه primeSw ← 0 i ← i + 1 اگر ( primeSw = 1) آنگاه چاپ کن "عدد اول است“ درغیراینصورت چاپ کن "عدد اول نیست" توقف کن
59
6-3 چند الگوریتم نمونه الگوریتمی بنویسید که یک عدد صحیح مثبت در مبنای 10 را دریافت و سپس آن را به مبنای b ببرد. مبنای b نیز از کاربر دریافت میگردد. adad و b را بخوان hasel ← 0 و i ← 0 تازمانیکه ( adad > 0 ) دستورات 4 تا 7 را تکرار کن remain ← adad mod b hasel ← hasel + remain × 10 i adad ← adad / b (تقسیم صحیح بر صحیح) i ← i + 1 hasel را چاپ کن توقف کن
60
6-3 چند الگوریتم نمونه الگوریتمی بنویسید که برای تعدادی مشترک این اطلاعات را بخواند : شماره حساب، موجودی اولیه، تعداد برداشت یا واریز و سپس برای هر برداشت یا واریز این اطلاعات را دریافت کند: کد عمل (1 = برداشت، 2 = واریز) و مبلغ. در نهایت برای هرمشترک ، شماره حساب و موجودی نهایی را چاپ کند. n را بخوان i ← 1 تا زمانیکه ( i ≤ n) دستورات 4 تا 11 را تکرار کن shomare و mojodi و tedad را بخوان j ← 1 تا زمانیکه ( j ≤ tedad) دستورات 7 تا 9 را تکرار کن code و mablagh را بخوان اگر ( code = 1) آنگاه mojodi ← mojodi – mablagh درغیراینصورت اگر ( code = 2 ) آنگاه mojodi ← mojodi + mablagh درغیراینصورت چاپ کن "کد اشتباه است" j ← j + 1 shomare و mojodi را چاپ کن i ← i + 1 توقف کن
61
6-3 چند الگوریتم نمونه الگوریتمی بنویسید که معدل و کد جنسیت دانشجویان (پسران=m و دختران= f) یک کلاس را دریافت و در پایان میانگین معدل پسران و میانگین معدل دختران و میانگین معدل کل کلاس را چاپ کند. n را بخوان mSum ← 0 و mCount ← 0 و fSum ← 0 و fCount ← 0 i ← 1 تا زمانیکه ( i ≤ n ) دستورات 5 تا 7 را تکرار کن code و average را بخوان اگر ( code = f ) آنگاه fSum ← fSum + average و fCount ← fCount + 1 در غیراینصورت اگر ( code = m ) آنگاه mSum ← mSum + average و mCount ← mCount + 1 در غیراینصورت چاپ کن "کد اشتباه است" و i ← i – 1 i ← i + 1 اگر ( fCount > 0 ) آنگاه fAve ← fSum / fCount اگر ( mCount > 0 ) آنگاه mAve ← mSum / mCount totalAverage ← (mSum + fSum) / n mAve و fAve و totalAverage را چاپ کن توقف کن
62
6-3 چند الگوریتم نمونه الگوریتمی بنویسید که برای تعدادی دانشجو، نام و شماره دانشجویی و تعداد دروس را دریافت کند و سپس برای هر دانشجو نمره و تعداد واحد هر درس وی را دریافت و معدل وی را محاسبه نماید. در پایان شماره دانشجویی، نام و معدل دو دانشجوی برتر کلاس را چاپ کند. n را بخوان maxAve1 ← -1 و maxAve2 ← -1 i ← 1 تازمانیکه ( i ≤ n) دستورات 5 تا 15 را تکرار کن name و id و tedad را بخوان sum ← 0 و sumVahed ← 0 j ← 1 تازمانیکه ( j ≤ tedad) دستورات 9 تا 12 را تکرار کن nomre و vahed را بخوان sum ← sum + nomre × vahed sumVahed ← sumVahed + vahed j ← j + 1 average ← sum / sumVahed اگر ( average > maxAve1 ) آنگاه maxName2 ← maxName1 و maxId2 ← maxId1 maxAve2 ← maxAve1و maxName1 ← name maxId1 ← id و maxAve1 ← average درغیراینصورت اگر ( average > maxAve2) آنگاه maxName2 ← name و maxId2 ← id و maxAve2 ← average i ← i + 1 maxId1 و maxName1 و maxAve1 و maxId2 و maxName2 و maxAve را چاپ کن توقف کن
63
6-3 چند الگوریتم نمونه الگوریتمی بنویسید که برای تعدادی شهر ابتدا نام شهر را دریافت و سپس دمای هوا در 24 ساعت گذشته دریافت نماید و میانگین دما را برای هر شهر محاسبه و چاپ نماید. درپایان موارد زیر را چاپ نماید : شهری که از همه گرمتر بوده است شهری که از همه سردتر بوده است تعداد شهرهای سرد (کمتر از 10) ، معتدل (بین 10 تا 30) و گرم (بیشتر از 30) به تفکیک درضمن تعداد شهرها مشخص نیست و در پایان هر شهر سوال میشود که آیا ادامه بدهیم یا خیر؟ warmDegree ← -100 و coldDegree ← 100 coldCount ← 0 و warmCount ← 0 و mediumCount ← 0 تکرار کن city را بخوان sum ← 0 و hour ← 1 تازمانیکه ( hour ≤ 24 ) دستورات 7 تا 9 را تکرار کن degree را بخوان sum ← sum + degree hour ← hour + 1 sum ← sum / 24 اگر ( sum > warmDegree) آنگاه warmDegree ← sum و warmCity ← city درغیراینصورت اگر ( sum < coldDegree ) آنگاه coldDegree ← sum و coldCity ← city اگر ( sum < 10 ) آنگاه coldCount ← coldCount +1 در غیر اینصورت اگر ( sum < 30 ) آنگاه mediumCount ← mediumCount + 1 درغیراینصورت warmCount ← warmCount + 1 چاپ کن "آیا مایل به ادامه هستید ؟" answer را بخوان تا زمانیکه ( answer = ‘yes’ ) اطلاعات لازم را چاپ کن توقف کن
64
مبانی کامپیوتر و برنامه سازی
فصل چهارم : آرایه ها مدرس : دکتر سهیل افراز
65
4 متغیرهای اندیس دار یا آرایه ها
4 متغیرهای اندیس دار یا آرایه ها در مثالهایی که در فصل قبل بیان گردید، از متغیرهای معمولی استفاده گردید. اما گاهی نیاز به تعداد زیادی متغیر برای نگاهداری دادهها داریم. درچنین مواردی نه تنها برای نامگذاری این متغیرها دچار مشکل میشویم، بلکه دسترسی به تک تک آنها نیز مشکل است. مثال ) الگوریتمی بنویسید که شماره دانشجویی، نام و معدل تعدادی دانشجو را بخواند و مشخصات دانشجویانی را که معدل آنها از میانگین معدل کلاس بیشتر است را چاپ کند. برای حل این مثال ابتدا باید مشخصات و معدل کلیه دانشجویان دریافت شود تا بتوانیم میانگین معدلهای آنان را محاسبه کنیم. سپس باید معدل تک تک دانشجویان با میانگین کلاس مقایسه گردد. مسلما نمیتوانیم مجددا از کاربر بخواهیم که همان اطلاعات قبلی را مجددا وارد کند، بلکه باید از قبل آنها را در درون متغیرهایی ذخیره کرده باشیم تا اکنون بتوانیم مقایسه را انجام دهیم. برای اینکار نیاز به تعدادی متغیر (به تعداد دانشجویان مثلا 100 عدد) داریم که ما را دچار 2 مشکل اساسی میکند : این متغیرها را چگونه نامگذاری کنیم ؟ بر فرض نامگذاری متغیرها برطبق یک روش خاص، چگونه تک تک آنها را با میانگین کل مقایسه کنیم؟ آیا باید برای مقایسه هر کدام یک دستور مجزا بنویسیم ؟
66
1-4 آرایههای یک بعدی تعریف آرایه : مجموعهای از دادههای همنوع است که تحت یک نام مشترک ذخیره میگردند. برای دسترسی به هریک از اعضا یا عناصر آرایه از نام آرایه بعلاوه یک اندیس استفاده میشود. بنابراین هر عنصر آرایه درحقیقت یک متغیر مستقل از همان نوع مورد نظر است. یک آرایه پیش از آنکه استفاده گردد باید اعلان شود. اعلان آرایه شامل نام آرایه و اندازه آن است. عناصر آرایه برای سهولت در دسترسی (معمولا) در خانههای پشت سرهم حافظه ذخیره میگردند. مثال) آرایه A را با 100 عضو درنظر بگیر ..... ..... A(1) A(2) A(3) A(4) A(i) A(100)
67
1-4 آرایههای یک بعدی مثال) الگوریتمی بنویسید که شماره دانشجویی، نام و معدل تعدادی دانشجو را بخواند و مشخصات دانشجویانی را که معدل آنها از میانگین معدل کلاس بیشتر است را چاپ کند n را بخوان آرایههای idList و nameList و aveList را با n عنصر درنظر بگیر. i ← 1 و sum ← 0 تازمانیکه ( i ≤ n ) دستورات 5 تا 8 را تکرار کن چاپ کن "مشخصات دانشجوی " ، i ، "را وارد کنید" idList(i) و nameList(i) و aveList(i) را بخوان sum ← sum + aveList(i) i ← i + 1 totalAve ← sum / n i ← 1 تازمانیکه ( i ≤ n ) دستورات 12 تا 13 را تکرار کن اگر ( aveList(i) ≥ totalAve) آنگاه idList(i) و nameList(i) و aveList(i) را چا پ کن i ← i +1 توقف کن
68
1-4 آرایههای یک بعدی الگوریتمی بنویسید که تعدادی عدد را دریافت و سپس ابتدا اعداد مثبت و سپس اعداد منفی را بطور جداگانه چاپ کند. n را بخوان آرایههای positive و negative را با n عنصر درنظر بگیر i ← 1 و posCount ← 0 و negCount ← 0 تازمانیکه ( i ≤ n ) دستورات 5 تا 7 را تکرار کن adad را بخوان اگر ( adad ≥ 0 ) آنگاه posCount ← posCount + 1 و positive(posCount) ← adad در غیراینصورت negCount ← negCount و negative(negCount) ← adad i ← i + 1 چاپ کن "لیست اعداد مثبت" i ← 1 تازمانیکه ( i ≤ posCount ) دستورات 11 تا 12 را تکرار کن چاپ کن positive(i) چاپ کن "لیست اعداد منفی" تازمانیکه ( i ≤ negCount ) دستورات 16 تا 17 را تکرار کن چاپ کن negative(i) توقف کن
69
1-4 آرایههای یک بعدی الگوریتمی بنویسید که دو مجموعه از اعداد را خوانده و در دو آرایه قرار دهد. سپس اشتراک آن دو را محاسبه و در یک آرایه دیگر قرار دهد. در پایان اشتراک حاصل را چاپ کند. n و m را بخوان آرایه A را با n عنصر و آرایه B را با m عنصر در نظر بگیر. آرایه C را با min(n,m) عنصر درنظر بگیر آرایههای A با n عنصر و B با m عنصر را بخوان (البته نیاز به حلقه دارد) aCount ← 1 و cCount ← 0 تا زمانیکه ( aCount ≤ n) دستورات 7 تا 11 را تکرار کن bCount ← 1 و sw ← 1 تازمانیکه ( bCount ≤ m and sw = 1) دستورات 9 تا 10 را تکرار کن اگر ( A(aCount) = B(bCount) ) آنگاه cCount ← cCount + 1 و C(cCount) ← A(aCount) و sw ← 0 bCount ← bCount + 1 aCount ← aCount + 1 چاپ کن "اشتراک دو مجموعه برابر است با :" i ← 1 تازمانیکه ( i ≤ cCount ) دستورات 15 تا 16 را تکرار کن C(i) را چاپ کن i ← i + 1 توقف کن
70
1-4 آرایههای یک بعدی A B C آزمایش الگوریتم اشتراک 23 19 23 45 35 10
1-4 آرایههای یک بعدی آزمایش الگوریتم اشتراک 23 45 10 35 8 17 26 12 A 19 35 23 33 17 21 10 B C aCount bCount cCount 23 10 35 17
71
1-4 آرایههای یک بعدی الگوریتمی مثال قبل را برای اجتماع دو مجموعه تکرار کنید. n و m را بخوان آرایه A را با n عنصر و آرایه B را با m عنصر در نظر بگیر. آرایه C را با n+m عنصر درنظر بگیر آرایههای A با n عنصر و B با m عنصر را بخوان (البته نیاز به حلقه دارد) i ← 1 تا زمانیکه ( i ≤ n ) دستورات 7 تا 8 را تکرار کن C(i) ← A(i) i ← i + 1 bCount ← 1 و cCount ← n تا زمانیکه ( bCount ≤ m) دستورات 11 تا 16 را تکرار کن aCount ← 1 و sw ← 1 تازمانیکه ( aCount ≤ n and sw = 1) دستورات 13 تا 14 را تکرار کن اگر ( A(aCount) = B(bCount) ) آنگاه sw ← 0 aCount ← aCount + 1 اگر (sw = 1) آنگاه cCount ← cCount + 1 و C(cCount) ← B(bCount) bCount ← bCount + 1 چاپ کن "اجتماع دو مجموعه برابر است با :" تازمانیکه ( i ≤ cCount ) دستورات 20 تا 21 را تکرار کن C(i) را چاپ کن توقف کن
72
1-4 آرایههای یک بعدی الگوریتمی بنویسید که یک لیست را گرفته و پس از حذف اعداد تکراری آن، حاصل را در یک لیست دیگر قرار دهد. n را بخوان آرایه A و B را با n عنصر درنظر بگیر آرایه A را با n عنصر بخوان B(1) ← A(1) i ← 2 و k ← 1 تا زمانیکه ( i ≤ n ) دستورات 7 تا 11 را تکرار کن j ← 1 تازمانیکه ( j ≤ k and A(i) ≠ B(j) ) دستور 9 را تکرار کن j ← j + 1 اگر ( j > k) آنگاه k ← k + 1 و B(k) ← A(i) i ← i + 1 لیست B را با k عضو چاپ کن (نیاز به حلقه دارد) توقف کن
73
1-4 آرایههای یک بعدی الگوریتم مثال قبل را بگونهای تغییر دهید که عملیات حذف دادههای تکراری را درخود آرایه اصلی (بدون کمک آرایه دیگر) انجام دهد. n را بخوان لیست A را با n عنصر در نظر بگیر لیست A را با n عنصر بخوان (نیاز به حلقه دارد) i ← 1 تازمانیکه ( i ≤ n ) دستورات 6 تا 9 را تکرار کن j ← i + 1 تازمانیکه ( j ≤ n ) دستور 8 را تکرار کن اگر ( A(i) = A(j) ) آنگاه A(j) ← A(n) و n ← n – 1 درغیراینصورت j ← j + 1 i ← i + 1 لیست A را با n عضو چاپ کن توقف کن
74
1-4 آرایههای یک بعدی الگوریتمی بنویسید که یک لیست مرتب بصورت صعودی از اعداد و یک عدد را از کاربر دریافت و سپس بدنبال داده در لیست جستجو کند و آن را حذف نماید. n را بخوان آرایه A را با n عنصر درنظر بگیر آرایه A را با n عنصر بخوان (بصورت مرتب شده) x را بخوان i ← 1 تازمانیکه ( i ≤ n and x≠A(i) ) دستور 7 را تکرار کن i ← i + 1 اگر ( i > n ) چاپ کن "عدد پیدا نشد" و توقف کن تازمانیکه ( i < n ) دستورات 10 تا 11 را تکرار کن A(i) ← A(i + 1) n ← n -1 آرایه A را با n عضو چاپ کن توقف کن
75
1-4 آرایههای یک بعدی A n = 9 n = 10 x = 38
1-4 آرایههای یک بعدی آزمایش الگوریتم حذف از لیست مرتب A i 12 18 n = 9 n = 10 21 35 38 x = 38 42 44 48 52 58
76
1-4 آرایههای یک بعدی الگوریتمی بنویسید که یک لیست مرتب بصورت صعودی از اعداد را از کاربر دریافت و سپس با دریافت یک عدد جدید از کاربر آن را درمکان مناسب لیست درج کند بطوریکه ترتیب حفظ شود. n را بخوان آرایه A را با n + 1 عنصر درنظر بگیر آرایه A را با n عنصر بخوان (بصورت مرتب شده) x را بخوان i ← n تازمانیکه ( i ≥ 1 and x < A(i) ) دستورات 7 تا 8 را تکرار کن A(i + 1) ← A(i) i ← i – 1 A(i + 1) ← x n ← n + 1 آرایه A را با n عضو چاپ کن توقف کن
77
1-4 آرایههای یک بعدی A n = 10 n = 11 x = 39
1-4 آرایههای یک بعدی آزمایش الگوریتم درج در لیست مرتب A 12 18 n = 10 n = 11 21 35 38 x = 39 39 42 44 48 52 i 58
78
1-4 آرایههای یک بعدی الگوریتمی بنویسید که یک لیست از اعداد را دریافت و عددی که بیشترین تکرار را دارد چاپ کند. n را بخوان آرایههای A و sw را با n عضو درنظر بگیر آرایه A را با n عضو بخوان تمام عناصر آرایه sw را برابر 0 قرار بده mod ← 0 و modNo ← 0 i ← 1 تازمانیکه ( i ≤ n) دستورات 8 تا 9 را تکرار کن اگر ( sw(i) = 0 ) آنگاه sw(i) ← 1 j ← i + 1 و sum ← 1 تازمانیکه ( j ≤ n ) دستورات d تا e را تکرار کن اگر ( A(i) = A(j) ) آنگاه sum ← sum + 1 و sw(j) ← 1 j ← j + 1 اگر ( sum > modNo) آنگاه mod ← A(i) و modNo ← sum i ← i + 1 mod و modNo را چاپ کن توقف کن
79
1-4 آرایههای یک بعدی الگوریتمی بنویسید که برای تعداد دانشجو، کد رشته (از 1 تا 15) را خوانده و سپس تعداد دانشجویان هررشته را به تفکیک چاپ کند. آرایه count را با 15 عضو درنظر بگیر تمام عناصر آرایه count را برابر 0 قرار بده n را بخوان i ← 1 تازمانیکه ( i ≤ n) دستورات 6 تا 8 را تکرار کن code را بخوان count(code) ← count(code) + 1 i ← i + 1 آرایه count را با 15 عضو چاپ کن توقف کن
80
2-4 آرایههای چندبعدی مسائلی که تاکنون حل شدند نیاز به آرایههای یک بعدی داشتند. هر عنصر از این آرایهها تنها با یک اندیس مشخص میگردد. اما گاهی در مسائل پیچیده تر نیاز به آرایههایی است که هر عضو آنها نیاز به بیش از یک اندیس دارد، که به آنها آرایههای چند بعدی گفته میشود. چنانچه هر عنصر آرایه به 2 اندیس نیاز داشته باشد، به آن آرایه دو بعدی میگوییم. برای تعریف یک آرایه دوبعدی باید تعداد سطرها و ستونهای آن را مشخص کنیم. معمولا یک آرایه دو بعدی بصورت m × n اعلان میگردد که m تعداد سطرها و n تعداد ستونها است.
81
2-4 آرایههای چندبعدی ستون سطر
2-4 آرایههای چندبعدی بعنوان مثال چنانچه آرایه A را بعنوان یک آرایه دوبعدی به ابعاد 5 × 8 تعریف کنیم، آنگاه داریم : ستون 1 2 3 4 5 6 7 8 1 سطر A(2,7) 2 3 A(3,4) 4 5
82
2-4 آرایههای چندبعدی عمق سطر ستون
2-4 آرایههای چندبعدی برای آرایههای سه بعدی نیز مفاهیم مشابهی قابل طرح است. در این آرایهها هر عنصر نیاز به 3 اندیس دارد و برای تعریف آنها را بصورت p × m × n اعلان میکنیم که p عمق، m تعداد سطرها و n تعداد ستونها است. بعنوان مثال چنانچه آرایه B بعنوان یک آرایه سه بعدی به ابعاد 3 × 4 × 6 تعریف شود، خواهیم داشت : B(2,1,4) عمق سطر B(1,2,6) ستون
83
2-4 آرایههای چندبعدی الگوریتمی بنویسید که برای تعدادی دانشجو، شماره دانشجویی و کد رشته (از 1 تا 15) را خوانده و سپس دانشجویان هررشته را به تفکیک چاپ کند. n را بخوان آرایه دوبعدی student را به ابعاد 15 × n در نظر بگیر آرایه count را با 15 عنصر در نظر بگیر و تمام عناصر آن را برابر 0 قرار بده i ← 1 تازمانیکه ( i ≤ n ) دستورات 6 تا 9 را تکرار کن id و code را بخوان count(code) ← count(code) + 1 student( code , count(code) ) ← id i ← i + 1 چاپ کن "لیست دانشجویان" تازمانیکه ( i ≤ 15) دستورات 13 تا 18 را تکرار کن چاپ کن "رشته "، i j ← 1 تازمانیکه ( j ≤ count(i) ) دستورات 16 تا 17 را تکرار کن student( i , j ) را چاپ کن j ← j + 1 توقف کن
84
2-4 آرایههای چندبعدی الگوریتمی بنویسید که برای تعدادی دانشجو، شماره دانشجویی و کد محل تحصیل (از 1 تا 10) و کد رشته (از 1 تا 15) را خوانده و سپس دانشجویان هر رشته را به تفکیک چاپ کند. n را بخوان آرایه سه بعدی student را به ابعاد 10 × 15 × n در نظر بگیر آرایه count را با 1510 × عنصر در نظر بگیر و تمام عناصر آن را برابر 0 قرار بده i ← 1 تازمانیکه ( i ≤ n ) دستورات 6 تا 9 را تکرار کن id و cityCode و studyCode را بخوان count(cityCode,studyCode) ← count(cityCode,studyCode) + 1 student( cityCode , studyCode , count(cityCode , studyCode) ) ← id i ← i + 1 چاپ کن "لیست دانشجویان" تازمانیکه ( i ≤ 10) دستورات 13 تا 22 را تکرار کن چاپ کن "محل "، i j ← 1 تازمانیکه ( j ≤ 15 ) دستورات 16 تا 21 را تکرار کن چاپ کن "کد رشته "، j k ← 1 تازمانیکه ( k ≤ count(i,j) ) دستورات 19 تا 20 را چاپ کن student( i , j , k) را چاپ کن k ← k + 1 j ← j + 1 توقف کن
85
2-4 آرایههای چندبعدی 50 موضوع مختلف را به رای گذاشته ایم و هرکس میتواند آرای خود را بشرح زیر اعلام کند: 1- موافق 2- مخالف 3- ممتنع 4- بی اطلاع الگوریتمی بنویسید که تعداد افراد رای دهنده را دریافت و سپس پس از دریافت آرای هریک از آنان برای هر 50 موضوع، تعداد آرای مختلف هر موضوع را به تفکیک چاپ کند. n را بخوان i ← 1 تازمانیکه ( i ≤ n ) دستورات را 5 تا 11 تکرار کن j ← 1 تازمانیکه ( j ≤ 50 ) دستورات 7 تا 10 را تکرار کن چاپ کن "موضوع " ، j vote را بخوان count(j , vote) ← count(j , vote) + 1 j ← j + 1 i ← i + 1 آرایه count را به ابعاد 50 × 4 چاپ کن (نیاز به حلقه دارد) توقف کن
86
2-4 آرایههای چندبعدی الگوریتمی بنویسید که دو ماتریس را از کاربر دریافت و حاصلضرب آن دو را محاسبه و چاپ کند. m و n را بخوان (ابعاد ماتریس اول m × n) p و q را بخوان (ابعاد ماتریس دوم p × q) اگر ( n ≠ p ) آنگاه چاپ کن "ماتریسها قابل ضرب نیستند" و توقف کن آرایه A را به ابعاد m × n و آرایه B را به ابعاد p × q درنظر بگیر آرایه C را به ابعاد m × q درنظر بگیر آرایه A را به ابعاد m × n بخوان آرایه B را به ابعاد p × q بخوان i ← 1 تازمانیکه ( i ≤ m) دستورات 10 تا 18 را تکرار کن j ← 1 تازمانیکه ( j ≤ q) دستورات 12 تا 17 را تکرار کن sum ← 0 و k ← 1 تازمانیکه (k ≤ n) دستورات 14 تا 15 را تکرار کن sum ← sum + A(i,k) × B(k,j) k ← k + 1 C(i,j) ← sum j ← j + 1 i ← i + 1 آرایه C را به ابعاد m × q چاپ کن توقف کن
87
2-4 آرایههای چندبعدی دریک آزمون دانشجویان باید به 20 سوال 4 گزینهای جواب بدهند. الگوریتمی بنویسید که ابتدا جواب درست سوالات را دریافت و سپس برای تعدادی دانشجو برگه پاسخنامه را دریافت و نمره آنها را محاسبه و چاپ کند. پاسخنامهها در یک آرایه دوبعدی 20 × 4 است که در جاهایی که دانشجو علامت زده است کاراکتر X قرار گرفته است و سایر مکانها خالی است. هر پاسخ غلط ⅓ نمره منفی دارد. آرایه correct را با 20 عضو درنظر بگیر آرایه answers را به ابعاد 20 × 4 در نظر بگیر i ← 1 تازمانیکه (i ≤ 20) دستورات 5 تا 7 را تکرار کن چاپ کن "پاسخ درست سوال"، i correct(i) را بخوان i ← i + 1 n را بخوان تازمانیکه ( i ≤ n) دستورات 11 تا 22 را تکرار کن آرایه answers را بخوان (از داخل فایل یا ورودی صفحه کلید) grade ← 0 j ← 1 تازمانیکه ( j ≤ 20) دستورات 15 تا 20 را تکرار کن k ← 1 و count ← 0 تازمانیکه (k ≤ 4) دستورات 17 تا 18 را تکرار کن اگر ( answers(j , k) = ‘X’ ) آنگاه count ← count + 1 k ← k + 1 اگر ( count > 1) آنگاه grade ← grade – 1/3 درغیراینصورت اگر (count = 1) آنگاه اگر ( answers(j , correct(j) ) = ‘X’) grade ← grade + 1 درغیراینصورت grade ← grade – 1/3 j ← j + 1 چاپ کن "نمره این دانشجو برابر است با "، grade توقف کن
88
مبانی کامپیوتر و برنامه سازی
فصل پنجم : زیرالگوریتمها مدرس : دکتر سهیل افراز
89
5 زیرالگوریتمها در الگوریتمهای نوشته شده تا کنون، بعضی اعمال مانند خواندن یک آرایه دوبعدی و یا چاپ آن مرتبا مورد استفاده قرار میگرفتند. این قبیل الگوریتمها را میتوان یکبار نوشت و چندین بار مورد استفاده قرار داد، که به آنها زیرالگوریتم گفته میشود. درحقیقت زیرالگوریتم یک قطعه الگوریتم کمکی است که دادههایی را بعنوان ورودی از الگوریتم اصلی دریافت و پس از انجام پردازش برروی آنها، داده یا دادههایی را بعنوان خروجی باز میگرداند. هر زیرالگوریتم دارای یک نام است که الگوریتم اصلی میتواند آن را توسط نامش فراخوانی نماید. زیرالگوریتم دارای مزایای متعدی است که اهم آنها عبارتند از : جلوگیری از تکرار الگوریتمهایی که مرتبا مورد استفاده قرار میگیرند. ساده شدن عیب یابی و اشکالزدایی الگوریتم بالا رفتن خوانایی برنامه امکان تقسیم کار به چند بخش و واگذاری آن به افراد مختلف هر الگوریتم میتواند برای تبادل اطلاعات با زیرالگوریتم، تعدادی از متغیرهای خود را به زیرالگوریتم ارسال کند و یا دادههایی را از آن دریافت کند. متغیرهایی را که برای تبادل اطلاعات بین الگوریتم و زیرالگوریتم بکار میروند را پارامتر میگوییم. بنابراین پارامترها میتوانند ورودی (به زیرالگوریتم) یا خروجی (از زیرالگوریتم) باشند. هر زیرالگوریتم میتواند هر تعداد پارامتر ورودی یا خروجی داشته باشد و یا میتواند اصلا پارامتر نداشته باشد.
90
1-5 نحوه استفاده از زیرالگوریتم
1-5 نحوه استفاده از زیرالگوریتم استفاده از یک زیرالگوریتم دارای دو مرحله است : تعریف زیرالگوریتم: برای تعریف زیرالگوریتم ابتدا نام آن و سپس در داخل پرانتز لیست پارامترهای آن را مشخص مینماییم. پس از آن نیز دستورات تشکیل دهنده زیرالگوریتم را مینویسیم. لازم به ذکر است که زیرالگوریتم حتما باید دارای دستور برگشت باشد. این دستور باعث میشود که کنترل اجرا به الگوریتم اصلی بازگردد. فراخوانی زبرالگوریتم: پس از تعریف یک زیرالگوریتم، میتوان آن را از هر نقطهای از الگوریتم اصلی فراخوانی کرد. فراخوانی شامل نام زیرالگوریتم و سپس در داخل پرانتز لیست پارامترهای ارسالی و دریافتی به زیرالگوریتم میباشد.
91
2-5 انواع زیرالگوریتم زیرالگوریتمها به سه دسته اصلی تقسیم میگردند :
2-5 انواع زیرالگوریتم زیرالگوریتمها به سه دسته اصلی تقسیم میگردند : زیرالگوریتمهایی که مقدار خروجی ندارند. زیرالگوریتمهایی که یک مقدار خروجی دارند. معمولا در این قبیل زیرالگوریتمها، بجای اینکه از یک پارامتر خروجی استفاده شود، نام خود زیرالگوریتم نماینده مقدار بازگشتی است. اینکار در ریاضیات معمولی نیز رایج است. مثلا وقتی از عبارت a = 2 × sin(30) استفاده میکنیم، خود نام تابع یعنی sin(30) جایگزین مقدار حاصل یعنی 2/1 شده است. زیر الگوریتمهایی که چندین مقدار باز میگردانند. این زیر الگوریتمها از پارامترهای خروجی برای بازگرداندن مقادیر استفاده میکنند. البته برای بازگرداندن یک مقدار نیز میتوان از پارامترها استفاده کرد ولی اینکار متداول نیست.
92
3-5 چند نمونه از زیرالگوریتمها
3-5 چند نمونه از زیرالگوریتمها الگوریتمی بنویسید که مقدار ترکیب n به k را محاسبه کند. زیرالگوریتم Factorial(x) i ← 1 و F ← 1 تازمانیکه ( i ≤ x ) دستورات 3 تا 4 را تکرار کن F ← F × i i ← i + 1 Factorial ← F برگشت
93
3-5 چند نمونه از زیرالگوریتمها
3-5 چند نمونه از زیرالگوریتمها الگوریتم اصلی n و k را بخوان اگر ( n < k ) چاپ کن "مسئله جواب ندارد" و توقف کن اگر ( n=k or k=0) چاپ کن "جواب = 1" و توقف کن result ← Factorial(n) / ( Factorial(k) × Factorial(n-k) ) result را چاپ کن توقف کن
94
3-5 چند نمونه از زیرالگوریتمها
3-5 چند نمونه از زیرالگوریتمها روش دیگر حل این مسئله با استفاده از یک پارامتر خروجی زیرالگوریتم Factorial(x,f) i ← 1 و f ← 1 تازمانیکه ( i ≤ x ) دستورات 3 تا 4 را تکرار کن f ← f × i i ← i + 1 برگشت
95
3-5 چند نمونه از زیرالگوریتمها
3-5 چند نمونه از زیرالگوریتمها الگوریتم اصلی n و k را بخوان اگر ( n < k ) چاپ کن "مسئله جواب ندارد" و توقف کن اگر ( n=k or k=1 ) چاپ کن "جواب = 1" و توقف کن Factorial(n,fn) Factorial(k,fk) Factorial(n-k,fnk) result ← fn / (fk × fnk) result را چاپ کن توقف کن
96
3-5 چند نمونه از زیرالگوریتمها
3-5 چند نمونه از زیرالگوریتمها الگوریتمی بنویسید که تعدادی عدد را دریافت و هربار با فراخوانی یک زیرالگوریتم عدد را در مکان مناسب یک آرایه درج کند بطوریکه در انتها آرایه مرتب باشد. زیرالگوریتم insert(A,t,x) i ← t تازمانیکه ( i ≥ 1 and x < A(i) ) دستورات 3 تا 4 را تکرار کن A(i + 1) ← A(i) i ← i – 1 A(i + 1) ← x برگشت
97
3-5 چند نمونه از زیرالگوریتمها
3-5 چند نمونه از زیرالگوریتمها الگوریتم اصلی n رابخوان آرایه List را با n عضو درنظر بگیر i ← 1 تازمانیکه ( i ≤ n ) دستورات 5 تا 7 را تکرار کن adad را بخوان insert(List, i-1, adad) i ← i + 1 آرایه List را با n عضو چاپ کن توقف کن
98
3-5 چند نمونه از زیرالگوریتمها
3-5 چند نمونه از زیرالگوریتمها الگوریتمی بنویسید که لیستی از اعداد را دریافت و در یک آرایه قرار دهد. سپس با دریافت هرعدد از کاربر تعیین کند که آیا این عدد در لیست موجود بوده یا خیر و درصورت وجود مکان آن را چاپ کند. در پایان اعداد، عدد صفر قرار گرفته است. زیرالگوریتم Search(A, t, x) i ← 1 تازمانیکه ( i ≤ t ) دستورات 3 تا 4 را تکرار کن اگر ( A(i) = x) آنگاه Search ← i و برگشت i ← i + 1 Search ← 0 برگشت
99
3-5 چند نمونه از زیرالگوریتمها
3-5 چند نمونه از زیرالگوریتمها الگوریتم اصلی n را بخوان آرایه List را با n عضو درنظر بگیر آرایه List را با n عضو بخوان adad را بخوان تازمانیکه ( adad ≠ 0 ) دستورات 6 تا 8 را تکرار کن place = Search(List, n , adad) اگر ( place = 0 ) آنگاه چاپ کن "عدد در لیست موجود نیست" درغیراینصورت چاپ کن "مکان عدد = "، place توقف کن
100
مبانی کامپیوتر و برنامه سازی
فصل ششم : مقدمهای بر زبان C مدرس : دکتر سهیل افراز
101
6 مقدمهای بر زبان C زبانهای برنامه سازی به سه دسته کلی تقسیم میگردند : زبان ماشین (سطح پایین) : این زبان مستقیما با صفر و یک نوشته میشود و بدون هیچ واسطهای برروی کامپیوتر قابل اجرا است. هر برنامهای که به زبان ماشین نوشته شود، فقط برروی همان ماشین خاص کار میکند، بهمین دلیل برنامههای نوشته شده به زبان ماشین را غیر قابل حمل مینامند. از طرف دیگر یادگیری این زبان بسیار مشکل بوده و برنامهنویسی با آن نیز بسیار سخت است و همچنین احتمال بروز خطا نیز در آن زیاد است. زبان اسمبلی : این زبان شکل ساده تر زبان ماشین است، بدین صورت که برای هر دستورالعمل زبان ماشین، یک اسم نمادین انتخاب شده است (مانند دستور ADD بجای کد دودویی دستورالعمل جمع) که بخاطر سپردن و برنامهنویسی با آنها برای انسانها ساده تر است. اما این برنامهها برای ماشین قابل فهم نیست و باید قبل از اجرا شدن توسط برنامه مترجمی بنام اسمبلر به زبان ماشین تبدیل شود. زبانهای سطح بالا : دستورالعملهای این زبانها بسیار نزدیک به زبان انسانها (بطور مشخص زبان انگلیسی) میباشد و بهمین دلیل برنامهنویسی به آنها بسیار ساده تر بوده و میتوان الگوریتمها را به راحتی به این زبانها تبدیل کرد. بیسیک (Basic): برای کاربردهای آموزشی فرترن (Fortran) : برای کاربردهای علمی و مهندسی پاسکال (Pascal) : برای کاربردهای آموزشی و علمی زبان C
102
1-6 تاریخچه زبان C در سال 1967 مارتین ریچاردز زبان BCPL را برای نوشتن نرم افزارهای سیستم عامل و کامپایلر در دانشگاه کمبریج ابداع کرد. در سال 1970 کن تامپسون زبان B را بر مبنای ویژگیهای زبان BCPL نوشت و از آن برای ایجاد اولین نسخههای سیستم عامل Unix در آزمایشگاههای بل استفاده کرد. زبان C در سال 1972 توسط دنیس ریچی از روی زبان B و BCPL در آزمایشگاه بل ساخته شد و ویژگیهای جدیدی همچون نظارت بر نوع دادهها نیز به آن اضافه شد. ریچی از این زبان برای ایجاد سیستم عامل Unix استفاده کرد اما بعدها اکثر سیستم عاملهای دیگر نیز با همین زبان نوشته شدند. این زبان با سرعت بسیاری گسترش یافت و چاپ کتاب “The C Programming Language” در سال 1978 توسط کرنیگان و ریچی باعث رشد روزافزون این زبان در جهان شد. در سال 1983 انستیتوی ملی استاندارد آمریکا (ANSI) کمیتهای موسوم به X3J11 را را مامور کرد تا یک تعریف فاقد ابهام و مستقل از ماشین را از این زبان تدوین نماید.در سال 1989 این استاندارد تحت عنوان ANSI C به تصویب رسید و سپس در سال 1990، سازمان استانداردهای بین المللی (ISO) نیز این استاندارد را پذیرفت و مستندات مشترک آنها تحت عنوان ANSI/ISO C منتشر گردید. در سالهای بعد و با ظهور روشهای برنامهنویسی شی گرا نسخه جدیدی از زبان C بنام C++ توسط بیارنه استراوستروپ در اوایل 1980 در آزمایشگاه بل توسعه یافت. در C++ علاوه بر امکانات جدیدی که به زبان C اضافه شده است، خاصیت شی گرایی را نیز به آن اضافه کرده است. شرکت سان مایکروسیستمز در سال 1995 میلادی زبان Java را برمبنای C و C++ ایجاد کرد که هم اکنون از آن در سطح وسیعی استفاده میشود و برنامههای نوشته شده به آن برروی هر کامپیوتری که از Java پشتیبانی کند(تقریبا تمام سیستمهای شناخته شده) قابل اجرا میباشد. شرکت مایکروسافت در رقابت با شرکت سان، در سال 2002 زبان جدیدی بنام C# (سی شارپ) را ارائه داد که رقیبی برای Java بشمار میرود.
103
2-6 برنامهنویسی ساختیافته
2-6 برنامهنویسی ساختیافته در دهه 1960 میلادی توسعه نرم افزار دچار مشکلات عدیدهای شد. در آن زمان سبک خاصی برای برنامهنویسی وجود نداشت و برنامهها بدون هیچگونه ساختار خاصی نوشته میشدند. فعالیتهای پژوهشی در این دهه باعث بوجود آمدن سبک جدیدی از برنامهنویسی بنام روش ساختیافته گردید؛ روش منظمی که باعث ایجاد برنامههایی کاملا واضح و خوانا گردید که اشکال زدایی و خطایابی آنها نیز بسیار ساده تر بود. اصلی ترین نکته در این روش عدم استفاده از دستور پرش (goto) است. تحقیقات بوهم و ژاکوپینی نشان داد که میتوان هر برنامهای را بدون دستور پرش و فقط با استفاده از 3 ساختار کنترلی ترتیب، انتخاب و تکرار نوشت. ساختار ترتیب، همان اجرای دستورات بصورت متوالی (یکی پس از دیگری) است. ساختار انتخاب به برنامهنویس اجازه میدهد که براساس درستی یا نادرستی یک شرط، تصمیم بگیرد کدام مجموعه از دستورات اجرا شود. ساختار تکرار نیز به برنامهنویسان اجازه میدهد مجموعه خاصی از دستورات را تا زمانیکه شرط خاصی برقرار باشد، تکرار نماید. هر برنامه ساختیافته از تعدادی بلوک تشکیل میشود که این بلوکها به ترتیب اجرا میشوند تا برنامه خاتمه یابد(ساختار ترتیب). هر بلوک میتواند یک دستورساده مانند خواندن، نوشتن یا تخصیص مقدار به یک متغیر باشد و یا اینکه شامل دستوراتی باشد که یکی از 3 ساختار فوق را پیاده سازی کنند. نکته مهم اینجاست که درمورد دستورات داخل هر بلوک نیز همین قوانین برقرار است و این دستورات میتوانند از تعدادی بلوک به شرح فوق ایجاد شوند و تشکیل ساختارهایی مانند حلقههای تودرتو را دهند. نکته مهم اینجاست که طبق قوانین فوق یک حلقه تکرار یا بطور کامل داخل حلقه تکرار دیگر است و یا بطور کامل خارج آن قرار میگیرد و هیچگاه حلقههای روی هم افتاده نخواهیم داشت. از جمله اولین تلاشها در زمینه ساخت زبانهای برنامهنویسی ساختیافته، زبان پاسکال بود که توسط پروفسور نیکلاس ویرث در سال 1971 برای آموزش برنامهنویسی ساختیافته در محیطهای آموزشی ساخته شد و بسرعت در دانشگاهها رواج یافت. کمی بعد زبان C ارائه گردید که علاوه بر دارا بودن ویژگیهای برنامهنویسی ساختیافته بدلیل سرعت و کارایی بالا مقبولیتی همه گیر یافت و هم اکنون سالهاست که بعنوان بزرگترین زبان برنامهنویسی دنیا شناخته شده است.
104
3-6 مراحل اجرای یک برنامه C
ورودیها ویرایشگر کامپایلر پیوند دهنده اجرای برنامه برنامه مبدا A.C برنامه مقصد A.obj فایل قابل اجرا A.exe توابع آماده خروجیها
105
3-6 مراحل اجرای یک برنامه C
مسلما طی این مراحل برای برنامهنویسان بسیار زمانبر است. راه حل این مشکل استفاده از محیط مجتمع توسعه نرم افزار یا IDE است. IDE (Integrated Development Environment) یک IDE شامل مواردی همچون ویرایشگر متن با امکانات ویژه برای زبان امکان کامپایل و پیوند برنامه امکان اشکال زدایی (Debug) برنامه چند محیط معروف برنامهنویسی عبارتند از : Borland C برای محیط DOS Borland C++ از نسخه 4 به بالا برای Windows Microsoft Visual C++ برای محیط Windows Borland C++ Builder برای محیط Windows
106
3-6 مراحل اجرای یک برنامه C
Borland C++ 3.1
107
4-6 خطاهای برنامهنویسی بنظر میرسد خطاها جزء جداناپذیر برنامهها هستند. بندرت میتوان برنامهای نوشت که در همان بار اول بدرستی و بدون هیچگونه خطایی اجرا شود. بطور کلی خطاها به دو دسته تقسیم میشوند: خطاهای نحوی (خطاهای زمان کامپایل): این خطاها در اثر رعایت نکردن قواعد دستورات زبان C و یا تایپ اشتباه یک دستور بوجود میآیند و در همان ابتدا توسط کامپایلر به برنامهنویس اعلام میگردد. معمولا این قبیل خطاها خطر کمتری را در بردارند. خطاهای منطقی (خطاهای زمان اجرا): این دسته خطاها در اثر اشتباه برنامهنویس در طراحی الگوریتم درست برای برنامه و یا گاهی در اثر درنظر نگرفتن بعضی شرایط خاص در برنامه ایجاد میشوند. متاسفانه این دسته خطاها در زمان کامپایل اعلام نمیشوند و در زمان اجرای برنامه خود را نشان میدهند. ممکن است یک برنامهنویس خطای منطقی برنامه خود را تشخیص ندهد و این خطا پس از مدتها و تحت یک شرایط خاص توسط کاربر برنامه کشف شود. بهمین دلیل این دسته از خطاها خطرناکتر هستند. خود این خطاها به دو دسته تقسیم میگردند: خطاهای مهلک: در این دسته خطاها کامپیوتر بلافاصله اجرای برنامه را متوقف کرده و خطا را به کاربر گزارش میکند. مثال معروف این خطاها، خطای تقسیم بر صفر میباشد. خطاهای غیرمهلک: در این دسته خطا، اجرای برنامه ادامه مییابد ولی برنامه نتایج اشتباه تولید مینماید. بعنوان مثال ممکن است دراثر وجود یک خطای منطقی در یک برنامه حقوق و دستمزد، حقوق کارمندان اشتباه محاسبه شود و تا مدتها نیز کسی متوجه این خطا نشود! بسیار مهم است که در ابتدا سعی کنید برنامهای بنویسید که حداقل خطاها را داشته باشد، در گام دوم با آزمایش دقیق برنامه خود هرگونه خطای احتمالی را پیدا کنید و در گام سوم بتوانید دلیل بروز خطا را پیدا کرده و آنرا رفع نمایید. هر سه عمل فوق کار سختی بوده و نیاز به تجربه و مهارت دارد. در اصطلاح برنامهنویسی به هر گونه خطا، bug و به رفع خطا debug گفته میشود.
108
5-6 یک برنامه نمونه C // This Program Computes the Area of a Circle
#include <stdio.h> void main() { int radius ; float area ; printf("please enter radius : ") ; scanf("%d",&radius) ; area = 2 * 3.14 * radius ; printf("Area is %f",area) ; } توضیحات تابع اصلی اجرای برنامه از این تابع آغاز میگردد دستور پیش پردازنده برای افزودن توابع کتابخانهای به برنامه اعلان متغیرهای برنامه علامت شروع بلوک معادل دستور begin در پاسکال تابع چاپ اطلاعات دندانه گذاری علامت انتهای بلوک معادل دستور end در پاسکال تابع دریافت اطلاعات علامت پایان دهنده دستورات نتیجه اجرای برنامه please enter radius : 10 Area is 62.8
109
مبانی کامپیوتر و برنامه سازی
فصل هفتم : مفاهیم اولیه زبان C مدرس : دکتر سهیل افراز
110
1-7 شناسهها در C شناسه (identifier) نامی است که به یک قسمت از برنامه مانند متغیر، تابع، ثابت و یا ... داده میشود. در زبان C برای انتخاب شناسهها فقط میتوان از علائم زیر استفاده کرد: حروف انگلیسی کوچک و بزرگ (A…Z a…z) ارقام (0…9) علامت خط پایین یا _ البته یک شناسه نمیتواند با یک رقم شروع شود. چند شناسه مجاز: sum ، average ، name2 وstudent_average چند شناسه غیرمجاز 2name و یا student average در برنامهنویسی امروزی پیشنهاد میشود بجای شناسههایی همانند student_average از studentAverage استفاده گردد. نکته مهم دیگری که باید به آن اشاره کرد آنستکه زبان C برخلاف بسیاری از زبانهای دیگر به کوچک و بزرگی حروف حساس است (case sensitive). در نتیجه شناسههای زیر با یکدیگر متفاوتند : Sum ≠ sum ≠ SUM آخرین نکته اینستکه در هنگام انتخاب شناسه نمیتوانید از کلمات کلیدی که برای منظورهای خاص در زبان C رزرو شدهاند استفاده کنید.
111
1-7 شناسهها در C کلمات کلیدی در زبان C : auto break case char const
continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while
112
2-7 انواع دادهها در C نوع داده توضیح اندازه (بیت) محدوده char کاراکتر
8 -128 to +127 int عدد صحیح 16 to float عدد اعشاری 32 3.4e-38 to 3.4e+38 double عدد اعشاری با دقت مضاعف 64 1.7e-308 to 1.7e+308
113
2-7 انواع دادهها در C البته چند نکته مهم درمورد این جدول قابل ذکر است : اندازه int در محیطهای 16 بیتی مانند DOS برابر 16 بیت است. اما در محیطهای 32 بیتی همانند Windows اندازه آن 32 بیت میباشد که در اینصورت محدودهای برابر -2,147,483,648 تا +2,147,483,647 را پوشش میدهد. در بعضی از کامپایلرهای C، نوع داده bool نیز وجود دارد که میتواند یکی از مقادیر true(درست) یا false (غلط) را نشان دهد . اما در نسخههای اولیه C از همان نوع داده صحیح یا int برای اینکار استفاده میشد. بدین صورت که 0 نشاندهنده false و هر عدد غیر صفر (معمولا 1) نشاندهنده true است. از آنجا که برای ذخیره سازی کاراکترها کد اسکی آنها ذخیره میگردد، از یک متغیر کاراکتری یا char میتوان بعنوان یک عدد صحیح کوچک نیز استفاده کرد و اعمال ریاضی برروی آنها نیز مجاز است.
114
2-7 انواع دادهها در C علاوه براین چندین اصلاح کننده نیز وجود دارد که به ما اجازه میدهد نوع داده مورد نظر را با دقت بیشتری برای نیازهای مختلف استفاده نماییم. این اصلاح کنندهها عبارتند از : short, long, signed, unsigned تمام این اصلاح کنندهها میتوانند به نوع داده int اعمال شوند و اثر آنها بستگی به محیط دارد. در یک محیط 16بیتی،short int بازهم برابر 16بیت است ولی long int برابر32بیت میباشد. unsigned int باعث میشود که یک عدد 16 بیتی بدون علامت داشته باشیم که بازه بین 0 تا را پوشش میدهد. signed int نیز همانند int معمولی بوده و تفاوتی ندارد. ترکیب این اصلاح کنندهها نیز ممکن است. مثلا unsigned long int یک عدد 32 بیتی بدون علامت است که بازه 0 تا 4,294,967,295 را پوشش میدهد. برروی نوع داده char فقط اصلاح کنندههای signed و unsigned را میتوان اعمال کرد. معمولا از اصلاح کننده unsigned وقتی استفاده میشود که قصد داشته باشیم از char بعنوان یک عدد صحیح مثبت بین 0 تا 255 استفاده کنیم. برروی نوع داده double تنها اصلاح کننده long قابل اعمال است و دراینصورت عدد اعشاری با 80 بیت را خواهیم داشت که قادر است هر عددی در بازه 3.4e-4932 تا 1.1e+4932 را در خود نگاه دارد.
115
3-7 تعریف متغیرها برای تعریف متغیرها به شکل زیر عمل میکنیم:
3-7 تعریف متغیرها برای تعریف متغیرها به شکل زیر عمل میکنیم: <type> <variable-list>; که type یکی از نوع دادههای گفته شده و variable-list لیستی از متغیرها است که با کاما از یکدیگر جدا شده اند. بعنوان مثال : int sum; float average; long int a, b, c ; unsigned long int i, j, k ; علاوه براین میتوان در هنگام تعریف متغیر به آن مقدار اولیه نیز داد. مثال : int d = 0 ; نکته مهم آنکه زبان C به متغیرها مقدار اولیه نمیدهد (حتی 0) و برنامهنویس خود باید اینکار را صریحا انجام دهد، درغیر اینصورت مقدار اولیه متغیر، نامعین خواهد بود. تعریف متغیرها طبق اصول زبان C میتواند درهرجایی از برنامه صورت پذیرد، و متغیرهای تعریف شده از همان خط به بعد قابل استفاده خواهد بود. اما معمولا توصیه میگردد که تعریف متغیرها در همان خط ابتدایی تابع و بلافاصله پس از { صورت پذیرد.
116
4-7 ثوابت ثابتها مقادیر ثابتی هستند که مقدار آنها در حین اجرای برنامه تغییر نمییابد. ثابتها میتوانند از هریک از نوع دادههای اصلی باشند. ثوابت عددی صحیح : برای نمایش این دسته از ثوابت، از دنبالهای از ارقام بعلاوه علامت + یا - استفاده میکنیم. بعنوان مثال 45- و یا 3489 ثوابت صحیح هستند. در حالت عادی C هر عدد را در کوچکترین نوع دادهای که میتواند قرار میدهد. مثلا عدد 85 در یک int قرار میگیرد، اما عدد در یک long int قرار خواهد گرفت. اگر قصد دارید یک عدد کوچک بعنوان long محسوب گردد، میتوانید از پسوند L در انتهای آن استفاده میکنیم. مثلا 245L یک عدد long محسوب میشود. long int a = 20L; پسوند U در انتهای عدد نیز نشانه بدون علامت بودن آن است. نکته دیگر آنکه C به شما اجازه میدهد درصورت لزوم ثوابت صحیح خود را در مبنای 8 یا 16 نیز که از مبناهای متداول در برنامهنویسی هستند، بنویسید. برای نوشتن عدد در مبنای 8 باید آن را با 0 آغاز کنید، مثلا یک عدد در منای 8 محسوب میگردد. برای نوشتن یک عدد در مبنای 16 باید آن را با 0x آغاز نمایید، مانند 0x27A4.
117
4-7 ثوابت ثوابت عددی اعشاری
4-7 ثوابت ثوابت عددی اعشاری برای نمایش اعداد اعشاری، باید از نقطه اعشار استفاده کنیم، مانند اما نکته جالب آنستکه میتوانید از نماد علمی نیز برای نمایش اعداد اعشاری استفاده کنید. برای اینکار کافی است از حرف e برای نمایش قسمت توان استفاده نمایید. بعنوان مثال : × = e5 × = e-3 دقت کنید که قسمت توان، حتما یک عدد صحیح است. نکته جالب اینجاست که برخلاف مورد قبل، کامپایلر بطور پیش فرض دادههای اعشاری را از نوع double فرض میکند.چنانچه دوست دارید ثابت شما ازنوع float درنظر گرفته شود، در انتهای آن F قرار دهید. ضمنا پسوند L نیز داده اعشاری را از نوع long double درنظر میگیرد.
118
4-7 ثوابت ثوابت کاراکتری :
4-7 ثوابت ثوابت کاراکتری : برای نشان دادن ثوابت کاراکتری، آنها را در داخل ' قرار میدهیم. بعنوان مثال 'A' یک ثابت کاراکتری است. char ch = 'S' ; دقت کنید که همانطور که قبلا گفته شد، کد اسکی کاراکترها در متغیر ذخیره میگردد، بنابراین میتوان از آن بعنوان یک عدد صحیح نیز استفاده کرد. نکته مهم دیگر آنستکه به تفاوت عدد 5 و کاراکتر '5' دقت داشته باشید. در حقیقت '5' برابر است با عدد 53 که همان کد اسکی آن است. روش فوق، برای نمایش کاراکترهای قابل چاپ مناسب است، اما بعضی کاراکترها مانند enter قابل نمایش نبوده و برای آنها شکل خاصی وجود ندارد. در چنین مواردی، زبان C از ترکیب علامت \ به همراه یک کاراکتر دیگر، برای نمایش این قبیل کاراکترها استفاده مینماید. بعنوان مثال، کاراکتر '\n' نشان دهنده خط جدید یا همان enter میباشد. جدول صفحه بعد این قبیل کاراکترها و معادل آنها را نشان میدهد.
119
4-7 ثوابت کد اسکی نحوه نمایش در C نام کاراکتر 7 \a صدای بوق کامپیوتر 8
4-7 ثوابت کد اسکی نحوه نمایش در C نام کاراکتر 7 \a صدای بوق کامپیوتر 8 \b حرکت به عقب backspace 12 \f شروع صفحه form feed 10 \n سطر جدید line feed 13 \r برگشت به ابتدای سطر carriage return 9 \t فاصله افقی horizontal tab 11 \v فاصله عمودی vertical tab 63 \? علامت سوال 39 \' علامت ' 34 \" علامت " 92 \\ علامت \ \0 علامت تهی
120
4-7 ثوابت ثوابت رشتهای : C علاوه بر ثوابت فوق، از یک ثابت دیگر بنام رشته نیز حمایت میکند. رشته، دنبالهای از کاراکترها است که در داخل " قرار میگیرند. بعنوان مثال "this is a test" یک رشته است. دقت کنید که 'a' یک کاراکتر است، اما "a" یک رشته است که فقط شامل یک کاراکتر میباشد.
121
5-7 عملگرها عملگر، نمادی است که به کامپایلر میگوید تا عملیات محاسباتی یا منطقی خاصی را برروی یک یا چند عملوند، انجام دهد. به عملگرهایی که فقط یک عملوند دارند، عملگر یکانی میگوییم و همواره عملگر در سمت چپ عملوند قرار میگیرد(مانند عدد -125). اما عملگرهایی که برروی دو عملوند اثر میکنند را عملگر دودویی نامیده و عملگر را بین دو عملوند قرار میدهیم (مانند 23+86). هر ترکیب درستی از عملگرها و عملوندها را یک عبارت مینامیم. C از نقطه نظر عملگرها یک زبان بسیار قوی است. این عملگرها به چند دسته اصلی تقسیم میگردند که آنها را به ترتیب بررسی میکنیم.
122
عملگرهای محاسباتی این عملگرها، همان اعمال متداول ریاضی هستند که در زبان C مورد استفاده قرار میگیرند. این اعمال عبارتند از : عمل نوع عملگر منفی کردن عملوند سمت راست یکانی - جمع دو عملوند دودویی + تفریق دو عملوند ضرب دو عملوند * تقسیم دو عملوند / محاسبه باقیمانده تقسیم دو عملوند %
123
عملگرهای محاسباتی این عملگرهای برروی همه انواع دادههای C عمل میکنند، بجز عملگر % که فقط برروی نوع دادههای صحیح عمل میکند. اما نکته مهمی که باید به آن اشاره کرد، نحوه کار عملگر تقسیم برروی نوع دادههای مختلف است. درصورتیکه هردو عملوند صحیح باشند، تقسیم بصورت صحیح بر صحیح انجام خواهد شد. اگر یکی یا هر دو عملوند اعشاری باشند، تقسیم بصورت اعشاری انجام خواهد پذیرفت. فرض کنید تعاریف زیر را داریم : int a,b ; float c,d ; a = 10 ; b = 4 ; c = 8.2; d = 4.0; اکنون به نتایج عملیات زیر دقت کنید : a / b => 2 c / d => a / d => 2.5 a / 4 => 2 چنانچه به آخرین مورد توجه کنید، متوجه میشوید که از آنجا که a یک متغیر صحیح است و 4 نیز یک ثابت صحیح در نظر گرفته شده، درنتیجه تقسیم بصورت صحیح بر صحیح انجام گرفته است. چنانچه بخواهیم تقسیم بصورت اعشاری صورت پذیرد، به دو شکل میتوانیم عمل کنیم.
124
عملگرهای محاسباتی برای اینکه عبارت تقسیم صفحه قبل بصورت اعشاری انجام شود، به دو روش میتوان عمل کرد: این عبارت را بصورت a / 4.0 بنویسیم. از عملگر قالب ریزی استفاده کنیم. عملگر قالب ریزی میتواند یک نوع را به نوع دیگری تبدیل نماید. شکل کلی آن به شکل زیر است : (<type>) <expression> که type نوع مورد نظر است که قصد تبدیل عبارت expression به آن نوع را داریم. بعنوان مثال در مورد قبلی میتوان به شکل زیر عمل کرد : (float) a / 4 در این حالت از کامپایلر خواسته ایم که ابتدا عدد a را به اعشاری تبدیل کند (البته بصورت موقت) و سپس آن را بر 4 تقسیم نماید، که مسلما حاصل اعشاری خواهد بود. بطورکلی هرگاه ثابتها و متغیرهایی از انواع مختلف در یک عبارت محاسباتی داشته باشیم، کامپایلر C همه آنها را به یک نوع یکسان که همان بزرگترین عملوند موجود است تبدیل خواهد کرد. بعنوان مثال به مورد صفحه بعد دقت کنید :
125
1-5-7 عملگرهای محاسباتی char ch; int i; float f; double d;
عملگرهای محاسباتی char ch; int i; float f; double d; result = (ch / i) ( f * d ) ( f + i ) int double float double double
126
عملگرهای محاسباتی اولویت عملگرها : در عبارتی که شامل چندین عملگر است، کدامیک در ابتدا اعمال خواهد گردید. اولویت عملگرهای محاسباتی از بالا به پایین بشرح زیر است: عملگر یکانی – عملگرهای * و / و % عملگرهای + و – چنانچه اولویت دو عملگر یکسان باشد، این عملگرها از چپ به راست محاسبه خواهند شد. چنانچه بخواهیم یک عمل با اولویت پایین زودتر انجام شود، باید از پرانتز استفاده کنیم. بنابراین اولویت عملگر پرانتز از همه موارد فوق بیشتراست. در مورد پرانتزهای متداخل، ابتدا پرانتز داخلی محاسبه میشود؛ اما در مورد پرانتزهای هم سطح، ابتدا پرانتز سمت چپتر محاسبه میگردد.
127
1-5-7 عملگرهای محاسباتی چند مثال در مورد اولویت عملگرها عبارت زبان C
عملگرهای محاسباتی چند مثال در مورد اولویت عملگرها عبارت زبان C ترتیب اجرای عملگرها b + c * d ابتدا عمل * و سپس عمل + (b + c) * d ابتدا عمل + و سپس عمل * b + c / d * e ابتدا عمل / سپس عمل * و در انتها عمل + b + c / (d * e) ابتدا عمل * سپس عمل / و در انتها عمل +
128
1-5-7 عملگرهای محاسباتی یک مثال کامل در مورد اولویت عملگرها
عملگرهای محاسباتی یک مثال کامل در مورد اولویت عملگرها result = a + b * (f – (g + b) / d) – c * (a – d) / e 5 4 3 1 2 7 8 6 9
129
عملگرهای انتساب در زبان C برای انتساب چندین عملگر وجود دارد. ساده ترین عملگر انتساب، همان عملگر = است که در بسیاری از زبانها استفاده میشود. بعنوان مثال : a = 5; b = c + 2 * d; این عملگر باعث میشود که عبارت سمت راست در عبارت سمت چپ قرار گیرد. توجه کنید که مقدار سمت چپ باید عبارتی باشد که بتوان به آن یک مقدار را نسبت داد (مانند یک متغیر) که به آن Lvalue گفته میشود، بنابراین یک ثابت نمیتواند در سمت چپ قرار گیرد. نکته دیگر اینکه اولویت عملگر = از عملگرهای ریاضی کمتر است و درنتیجه ابتدا آن عملیات انجام شده و در پایان حاصل در عبارت سمت چپ ریخته میشود. لازم به ذکر است که در هنگام انتساب، درصورت لزوم نوع عبارت سمت راست به نوع عبارت سمت چپ تبدیل میشود. مثال: int a; a = 2.5 * 5.0; که دراینصورت عدد 12 در a ذخیره خواهد شد. شرکت پذیری این عملگر از راست به چپ میباشد، بدین معنا که چنانچه چندین عملگر نسبت دهی داشته باشیم، این عملگرها از راست به چپ محاسبه میشوند. مثلا پس از اجرای دستور زیر، مقدار هر 3 متغیر برابر 10 خواهد شد. a = b = c = 10;
130
عملگرهای انتساب نکته جالب درمورد زبان C آنستکه دارای یک سری عملگرهای انتساب خلاصه شده است که باعث میشوند در بعضی موارد بتوانیم عبارات کوتاهتری را بنویسیم. این عملگرها عبارتند از : عملگرد مثال عبارت انتساب معادل ++ a ++; a = a + 1; -- a --; a = a – 1; += a += 5; a = a + 5; -= a -= 8; a= a – 8; *= a *= 10; a= a * 10; /= a /= 2; a = a / 2; %= a %= 10; a = a % 10;
131
عملگرهای انتساب عملگر اول و دوم، عملگرهای یکانی هستند که بترتیب عملگر افزایش و عملگر کاهش نامیده میشوند. نکته جالب آنستکه این دو عملگر به دوصورت مورد استفاده قرار میگیرند. در حالتی که از دستور a ++; استفاده شود به آن پس افزایش میگویند و بدین معناست که ابتدا از مقدار فعلی a در عبارت موردنظر استفاده کن و سپس آن را افزایش بده. اما دستور ++ a; که به آن پیش افزایش گفته میشود، ابتدا a را افزایش داده و سپس از آن در عبارت استفاده میکند. به برنامه زیر دقت کنید: #include <stdio.h> void main() { int a ,b ; a = 5 ; b = a ++; printf(“a=%d and b=%d \n”,a,b); b = ++ a; } a=6 b=5 a=6 b=6
132
عملگرهای مقایسه ای این عملگرها دو عبارت را بایکدیگر مقایسه کرده و نتیجه را باز میگردانند. نتیجه میتواند درست (true) یا غلط (false) باشد. نتیجه این عملگرها یک عدد صحیح است که درصورت درست بودن 1 و درصورت غلط بودن 0 باز میگردانند. این عملگرها عبارتند از: عملگر مفهوم عملگر مثال < بزرگتر (<) a > b > کوچکتر (>) a < b =< بزرگتر یا مساوی (≤) a >= b => کوچکتر یا مساوی (≥) a <= b == مساوی (=) a == b =! نامساوی (≠) a != b
133
عملگرهای مقایسه ای نکته مهمی که باید به آن دقت کرد عملگر مساوی (==) است، چرا که یک اشتباه بسیار متداول برنامهنویسان C استفاده اشتباه از عملگر انتساب (=) بجای عملگر تساوی (==) است که باعث ایجاد خطا در برنامه میشود. اولویت این عملگرها از بالا به پایین بشرح زیر است: عملگرهای <، > ، =< و => عملگرهای == و =! لازم بذکر است که در هنگام مساوی بودن اولویت چند عملگر، این عملگرها از چپ به راست محاسبه میگردند.
134
عملگرهای منطقی این عملگرها به شما اجازه میدهند که شرطهای سادهای را که با استفاده از عملگرهای مقایسهای ایجاد شدهاند را با یکدیگر ترکیب نموده و شرطهای پیچیده تری را بسازید. این عملگرها عبارتند از : عملگر مفهوم عملگر نحوه کار مثال && AND منطقی اگر هر دو عملوند درست باشند, درست و در غیر اینصورت نادرست باز میگرداند. a>0 && sw==1 || OR منطقی اگر هر دو عملوند نادرست باشند, نادرست و در غیر اینصورت درست باز میگرداند. a<=100 || b!=0 ! NOT منطقی اگر عملوند درست باشد، نادرست و اگر نادرست باشد، درست برمی گرداند. ! (a==1 || b<10)
135
عملگر شرطی گاهی لازم است که ابتدا یک شرط بررسی شده و سپس برمبنای نتیجه (درست یا نادرست بودن آن) یکی از دو عبارت ممکن بازگردانده شود. برای اینکار میتوان از یک عملگر 3تایی (با 3 عملوند) بنام عملگر شرطی استفاده نمود. شکل کلی این عملگر بصورت زیر است: <شرط> ?<عبارت1> :<عبارت2> نحوه کار بدینصورت است که درصورت درست بودن شرط، عبارت1 و در غیراینصورت عبارت 2 بازگردانده میشود. به عنوان مثال به دستور زیر توجه کنید: a = (k<10) ? : 50; که این عبارت معادل دستور زیر است: if (k<10) a=100; else a=50; البته این عبارت به شکلهای پیچیده نیز میتواند مورد استفاده قرار گیرد. مثلا : c += (a>0 && a<10) ? ++a : a/b; که معادل است با : if (a>0 && a<10) { a= a + 1; c = c + a; } else c = c + a/b;
136
6-5-7 اولویت عملگرها اولویت عملگر شرکت پذیری 1 () از چپ به راست 2
اولویت عملگرها اولویت عملگر شرکت پذیری 1 () از چپ به راست 2 ! از راست به چپ 3 % / * 4 - + 5 >> << 6 >= > <= < 7 =! == 8 && 9 || 10 ?: 11 =% =/ =* =- =+ = 12 ,
137
6-7 خواندن و نمایش اطلاعات
همانطور که قبلا نیز گفته شد، یکی از اهداف زبان C قابل حمل بودن آن است. بهمین منظور سعی شده است که از دستوراتی که ممکن است وابسته به ماشین خاصی باشد، اجتناب گردد. بهمین دلیل زبان C برخلاف سایر زبانها دارای هیچ دستوری برای خواندن از ورودی و یا نوشتن در خروجی نیست. اما در عوض دارای تعدادی تابع (زیربرنامه) استاندارد میباشد که تقریبا تمامی کامپایلرها از آنها حمایت میکنند. این کار به کامپایلر این امکان را میدهد که بر حسب نوع سخت افزار موردنظر، توابع ورودی و خروجی را طراحی نماید. این توابع در یک فایل سرآمد بنام stdio.h تعریف شدهاند و بنابراین قبل ازاینکه بتوانید از این توابع استفاده نمایید، باید این فایل را نیز با استفاده از #include در برنامه خود بگنجانید.
138
تابع نمایش در خروجی برای نمایش اطلاعات در خروجی از تابع printf استفاده میشود. این تابع رشته موردنظر شما را به خروجی استاندارد (که در حالت عادی همان صفحه نمایش یا مانیتور است) میفرستد. شکل کلی این تابع بصورت زیر است: printf(<رشته کنترلی> , <لیست متغیرها>) ; رشته کنترلی همان متنی است که قصد چاپ آن را داریم، با ذکر این نکته که در قسمتهایی که باید مقدار یک متغیر چاپ شود، از یک مشخصه تبدیل استفاده میشود. هر مشخصه تبدیل از یک علامت % بعلاوه یک کاراکتر که نوع متغیر مورد نظر را نشان میدهد تشکیل میگردد. لیست متغیرها نیز همان متغیرهایی هستند که قصد چاپ آنها را داریم. این متغیرها باید بترتیب قرار گرفته و با کاما (,) از یکدیگر جدا شوند.
139
عدد اعشاری بدون نماد علمی عدد اعشاری با حالت کوتاهتر بین e و f
تابع نمایش در خروجی مفهوم مشخصه تبدیل کاراکتر %c عدد صحیح در مبنای 10 %d عدد اعشاری بدون نماد علمی %f عدد اعشاری با نماد علمی %e عدد اعشاری با حالت کوتاهتر بین e و f %g رشته %s عدد صحیح بزرگ %ld عدد اعشاری بزرگ %lf %le %lg عدد صحیح در مبنای 8 %o عدد صحیحی در مبنای 16 %x عدد صحیح بدون علامت %u
140
1-6-7 تابع نمایش در خروجی #include <stdio.h> void main() {
تابع نمایش در خروجی #include <stdio.h> void main() { int age = 20; float average = 18.23; printf("You are %d years old and your average is %f \n",age,average); } You are 20 years old and your average is
141
تابع نمایش در خروجی برای کنترل نحوه چاپ اعداد میتوانید از مشخصه طول میدان استفاده کنید. مشخصه طول میدان برای اعداد به شکل زیر استفاده میشود: برای اعداد صحیح از %nd استفاده میکنیم که n تعداد ارقام را نشان میدهد (مثلا %3d). در اینصورت برای هر متغیر n رقم درنظر گرفته میشود. اگر اندازه عدد از n کوچکتر باشد، به سمت چپ آن فضای خالی اضافه میشود و اگر اندازه عدد بیش از n رقم باشد، طول میدان نادیده گرفته شده و عدد بطور کامل چاپ میشود. برای اعداد اعشاری از %n.mf استفاده میکنیم که n اندازه کل عدد (شامل علامت ممیز) و m تعداد ارقام اعشار است (مثلا %5.2f). در صورتیکه تعداد ارقام اعشاری عدد موردنظر از m بیشتر باشد، عدد به m عدد اعشار گرد میشود و در صورتیکه از m کمتر باشد، در سمت راست آن 0 قرار داده میشود.
142
تابع خواندن از ورودی برای خواندن اطلاعات از ورودی از تابع scanf استفاده میشود. این تابع اطلاعات را ازورودی استاندارد (معمولا صفحه کلید) خوانده و در متغیرهای تعیین شده قرار میدهد. شکل کلی این تابع بصورت زیر است: scanf(<رشته کنترلی> , <لیست آدرسهای متغیرها>) ; همانطور که میبینید نحوه احضار تابع scanf نیز مشابه printf است. تنها تفاوت در آن است که در scanf باید لیست آدرسهای متغیرها ارسال شود. مبحث مربوط به آدرسها در فصول بعدی بررسی خواهد شد ولی در حال حاضر بخاطر بسپارید که برای بدست آوردن آدرس یک متغیر از علامت & استفاده میکنیم. بعنوان مثال &age بمعنای آدرس متغیر age است. بطور کلی در C قدیمی هرگاه که یک تابع دارای پارامترهای خروجی بود (یعنی پارامترهایی که یک مقدار را باز میگرداندند) از آدرس متغیرها استفاده میشد که امروزه این مسئله وجود ندارد.
143
تابع خواندن از ورودی #include <stdio.h> void main() { int age; float average ; printf("Please enter your age and average : "); scanf("%d %f",&age,&average); printf("You are %d years old and your average is %5.2f \n",age,average); } Please enter your age and average : You are 19 years old and your average is 16.72
144
3-6-7 ورودی و خروجی اطلاعات در C++
از آنجا که امروزه معمولا برنامهنویسان C از کامپایلرهای C++ استفاده میکنند، میتوانند از اشیای ورودی و خروجی آن نیز استفاده کنند. اینکار در بین بسیاری از برنامهنویسان C متداول است، بهمین دلیل ما در اینجا نحوه کار با اشیای خواندن و نوشتن در C++ را بطور مقدماتی توضیح میدهیم؛ گرچه توضیح کامل این موارد نیاز به آشنایی با شی گرایی و زبان C++ دارد. قبل از هرچیز لازم به ذکر است که کلیه اشیای مربوط به ورودی و خروجی در فایل سرآمدی بنام iostream.h تعیریف شده اند، بنابراین ابتدا باید این فایل به برنامه توسط دستور #include الحاق گردد.
145
3-6-7 ورودی و خروجی اطلاعات در C++
زبان C++ برای نمایش اطلاعات از یک شیئ بنام cout استفاده مینماید. برای ارسال اطلاعات مورد نظر برای چاپ به cout باید از عملگر درج در جریان یا >> استفاده نماییم. بعنوان مثال : cout << “Please enter your name: ” ; و یا مثال دیگر : int a = 10; float b = 2.86; cout << a; cout << b; نکته جالبی که در این مثالها دیده میشود، آنستکه برخلاف تابع printf هیچ نیازی به مشخص کردن نوع متغیری که قصد چاپ آن را داریم نیست و خود شئ cout نوع آن را تشخیص میدهد. علاوه براین میتوان چندین عملگر درج در جریان را با یکدیگر الحاق کرد و چندین متغیر را با یک دستور چاپ کرد.
146
3-6-7 ورودی و خروجی اطلاعات در C++
#include <iostream.h> void main() { int age = 20; floate average = 18.23; cout << “You are ” << age << “ years old and your average is ” << average ; } You are 20 years old and your average is
147
3-6-7 ورودی و خروجی اطلاعات در C++
برای دریافت اطلاعات از کاربر، از شئ دیگری بنام cin استفاده میشود. برای ارسال متغیر مورد نظر به cin باید از عملگر استخراج از جریان یا << استفاده نماییم. بعنوان مثال: int a; cin >> a; بازهم همانطور که میبینید نیازی به تعیین نوع متغیر موردنظر نیست و خود شئ cin نوع متغیر را بطور اتوماتیک تشخیص داده و دادهای از همان نوع را از کاربر دریافت و در متغیر مورد نظر قرار میدهد. عملگرهای استخراج از جریان را نیز میتوان با یکدیگر الحاق کرد. برای رفتن به خط بعد در شئ cout میتوان از دستکاری کننده endl استفاده کرد. مثلا در دستور زیر پس از چاپ پیغام، مکان نما به خط بعد منتقل میشود: cout << “List of students : “ << endl; البته دستکاری کنندههای متعدد دیگری نیز ازجمله موارد مربوط به تعیین طول میدان و نحوه چاپ مقادیر وجود دارد که توضیح آنها نیاز به یک مبحث مستقل دارد.
148
3-6-7 ورودی و خروجی اطلاعات در C++
#include <iostream.h> void main() { int age; float average ; cout << "Please enter your age and average : " ; cin >> age >> average ; cout << "You are " << age << "years old and your average is " << average; } Please enter your age and average : You are 19 years old and your average is 16.72
149
7-7 توابع کتابخانهای همانطور که قبلا نیز گفته شد، زبان C از زیر برنامهها نیز حمایت میکند. هر زیر برنامه در C یک تابع نامیده میشود. تا کنون با توابعی همچون main و یا printf و scanf آشنا شده ایم. معمولا عرضه کنندگان کامپایلرها و یا سایر فروشندگان نرم افزار، برخی از توابع عمومی را که ممکن است مورد نیاز جمع کثیری از برنامهنویسان مختلف باشد را در قالب کتابخانهای از توابع در اختیار برنامهنویسان میگذارند. بعضی از این توابع کتابخانهای مانند printf و scanf بصورت استاندارد درآمده و توسط عرضه کنندگان مختلف ارائه میشوند. در کامپایلر عرضه شده توسط شرکت بورلند (Borland C++ 3.1) نیز کتابخانههای متعددی از توابع برای شما عرضه شدهاند که بتدریج با آنها و کاربردشان آشنا خواهید شد. نکته مهم آنستکه برای استفاده از این توابع ابتدا باید فایل سرآمد مربوط به آنها را نیز در ابتدای برنامه خود اضافه نمایید ( با استفاده از #include). هر فایل سرآمد شامل تعاریف اولیه گروهی از توابع مرتبط با هم و دادههای مربوط به آنها بوده و در استاندارد قدیمی تر دارای پسوند .h میباشد(در استاندارد جدید پسوند این فایلها حذف شده است). برخی از این فایلهای سرآمد عبارتند از: stdio.h : توابع ورودی و خروجی استاندارد math.h : توابع ریاضی graphics.h : توابع مربوط به عملیات گرافیکی string.h : توابع مربوط به کار با رشته ها
150
مبانی کامپیوتر و برنامه سازی
فصل هشتم : ساختارهای کنترلی مدرس : دکتر سهیل افراز
151
8 ساختارهای کنترلی ساختارها در برنامهنویسی ساختیافته
8 ساختارهای کنترلی ساختارها در برنامهنویسی ساختیافته ساختار ترتیب ساختار انتخاب ساختار تکرار زبان C دارای 7 نوع ساختار کنترلی است ساختار ترتیب: دستورهای زبان C در حالت عادی به همان ترتیبی که نوشته شده اند، یکی پس از دیگری اجرا میشوند. 3 نوع ساختار انتخاب: ساختار if یا ساختار تک انتخابی ساختار if / else یا ساختار دو انتخابی ساختار switch یا ساختار چند انتخابی 3 نوع ساختار تکرار while for do / while
152
1-8 ساختار انتخاب if این دستور به شکل زیر استفاده میشود:
if (<expresion>) <statement>; نحوه کار بدینصورت است که ابتدا عبارت موجود در قسمت <expression> ارزیابی میشود. در صورتیکه درست ارزیابی گردد، دستور قسمت <statement> اجرا خواهد شد و در صورتیکه نادرست باشد، بدون اینکه دستور قسمت <statement> را اجرا کند به دستور بعدی خواهد رفت. این دستور میتواند بصورت زیر نیز استفاده گردد: if (<expresion>) <statement 1>; else <statement 2>; در اینصورت ابتدا عبارت موجود در قسمت <expression> ارزیابی میشود. در صورتیکه درست ارزیابی گردد، دستور قسمت <statement 1> اجرا خواهد شد، و در صورتیکه نادرست باشد، دستور قسمت <statement 2> اجرا خواهد شد. در هر حال فقط یکی از این دو قسمت اجرا خواهد گردید.
153
1-8 ساختار انتخاب if بعنوان مثال چنانچه متغیر grade حاوی نمره دانشجو باشد و بخواهیم بر مبنای نمره وی، پیغام مناسبی چاپ کنیم، میتوانیم از دستور زیر استفاده کنیم: if (grade >= 10) printf(“Passed !”); else printf(“Failed!”); در حالت عادی دستور if منتظر یک دستور در بدنه خود میباشد، اما چنانچه میخواهید چندین دستور را در بدنه یک دستور if دهید، باید آنها را در داخل آکولاد باز وبسته { } قرار دهید. این مجموعه دستورات را یک دستور مرکب میگویند. بطور کلی در زبان C هرجا که میتوان یک دستور قرار داد، میتوان از یک دستور مرکب نیز استفاده کرد. به یک دستور مرکب، بلوک نیز گفته میشود.
154
1-8 ساختار انتخاب if بنابراین صورت کلی دستور if به شکل زیر است:
if (<expression>) { <statement 1> ; <statement 2> ; …. <statement n> ; } else { ……. <statement m> ;
155
1-8 ساختار انتخاب if if (!a)
برنامه 1) برنامهای بنویسید که ضرایب یک معادله درجه 2 را دریافت و ریشههای آن را محاسبه و چاپ نماید. #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <math.h> void main() { int a, b, c; float x1, x2, delta; clrscr(); printf(“Please enter a, b and c : “); scanf(“%d %d %d”, &a, &b, &c); if (a==0) { printf(“wrong equation!”); exit(1) ; } if (!a)
156
1-8 ساختار انتخاب if delta = b*b – 4*a*c; if (delta < 0)
printf(“No answer !”); else if (delta == 0) { x1 = -b / (2*a); printf(“There is one answer, x = %8.2f”,x1); } else { delta = sqrt(delta); x1 = (-b+delta) / (2*a); x2 = (-b-delta) / (2*a); printf(“There are two answers, x1= %8.2f and x2 = %8.2f”, x1, x2);
157
1-8 ساختار انتخاب if یک روش متداول استفاده از دستور if، استفاده از if های تودرتو میباشد. if (grade >= 18) printf("good!"); else if (grade >= 15) printf("medium!"); else if (grade >= 12) printf("rather weak!"); else if (grade >= 10) printf("weak"); else printf("failed!"); درچنین حالتی توصیه میگردد که شرطهای نادر را که امکان وقوع آنها کم است، در انتهای کار بررسی نمایید، تا تعداد مقایسه کمتری صورت پذیرد.
158
1-8 ساختار انتخاب if مشکل if های تودرتو : در دستور زیر، else به کدام if تعلق دارد؟ if (a < b) if (c < d) <statement 1>; else <statement 2>; بطور کلی طبق قوانین گرامری، هر else مربوط به نزدیکترین if قبل از خود میباشد.
159
1-8 ساختار انتخاب if اما سوال این است که اگر بخواهیم else به if اول بازگردد از چه روشی استفاده نماییم. دراینصورت میتوان از یکی از دو روش زیر استفاده کرد: if (a < b) if (c < d) <statement 1>; else ; else <statement 2>; if (a < b) { if (c < d) <statement 1>; } else <statement 2>;
160
1-8 ساختار انتخاب if برنامه 2) برنامه ای بنویسید که 3 عدد را دریافت و حداکثر آنها را چاپ کند. #include <stdio.h> void main() { int a, b, c, max; printf("Please enter 3 numbers :"); scanf("%d %d %d",&a, &b, &c); if (a > b) if (a > c) max = a; else max= c; else if (b > c) max = b; else max = c; printf("Maximum is %d",max); }
161
2-8 ساختار تکرار while while (<expression>) {
false ( = 0 ) true ( ≠ 0 ) ? while (<expression>) { <statement 1> <statement 2> … <statement n> } <next statement>
162
2-8 ساختار تکرار while برنامه 3) برنامه ای بنویسید که یک عدد را دریافت و فاکتوریال آن را محاسبه و چاپ نماید. #include <stdio.h> void main() { int i,number; long int factorial; printf("Please enter number :"); scanf("%d",&number); factorial = 1; i = 1; while (i <= number) { factorial *= i; i ++; } printf("Factorial of %d is %ld“,number,factorial);
163
2-8 ساختار تکرار while برنامه 4) برنامه ای بنویسید که یک متن را از کاربر دریافت و آن را با حروف بزرگ چاپ کند. #include <stdio.h> #include <conio.h> void main() { char ch; ch = getch() ; while (ch != 13) { if (ch >= 'a' && ch <= 'z') ch -= 32; putch(ch); ch = getch(); }
164
3-8 ساختار تکرار for همانگونه که در مثال مربوط به حل مسئله فاکتوریال دیده میشود، گاهی نیاز به حلقه تکراری داریم که به تعداد دفعات مشخصی تکرار گردد. در چنین مواقعی با استفاده از یک متغیر شمارنده، تعداد تکرارها را تا رسیدن به مقدار مورد نظر میشماریم و سپس به حلقه پایان میدهیم. به چنین حلقه هایی، تکرار تحت کنترل شمارنده یا تکرار معین میگوییم، چرا که تعداد تکرارها از قبل مشخص است. چنین حلقهای دارای 3 جزء اصلی میباشد: مقداردهی اولیه به متغیر شمارنده حلقه شرط پایان حلقه (پایان شمارش) نحوه افزایش متغیر شمارنده از آنجا که در تمام حلقههایی که تکرار معین دارند، همین ساختار استفاده میشود؛ در اکثر زبانهای برنامه سازی یک ساختار تکرار ویژه، بنام حلقه for، برای اینکار در نظر گرفته شده است.
165
3-8 ساختار تکرار for for (<expression1> ; <expression2> ; <expression3>) <statement>; مقداردهی اولیه شرط تکرار حلقه نحوه افزایش متغیر حلقه
166
3-8 ساختار تکرار for for (<exp1>;<exp2>;<exp3>) {
اجرا ( فقط در شروع حلقه) false (= 0) true (≠ 0) ? اجرا ( از اجرای دوم به بعد) for (<exp1>;<exp2>;<exp3>) { <statement 1> <statement 2> … <statement n> } <next statement>
167
3-8 ساختار تکرار for درحقیقت هر حلقه for معادل با حلقه while زیر است:
<exp1> ; while (<exp2>) { <statement>; <exp3>; }
168
3-8 ساختار تکرار for بعنوان یک مثال ساده، تکه برنامه زیر اعداد بین 0 تا 100 را چاپ مینماید: int count; for (count = 0; count <= 100; count ++) printf(“%d “,count); اگر بخواهیم تنها مضارب 5 چاپ شوند، حلقه را به شکل زیر تغییر میدهیم: for (count = 0; count <= 100; count += 5) حتی میتوان مضارب 5 را از آخر به اول چاپ کرد: for (count = 100; count >= 0; count -= 5) قسمت شرط میتواند یک شرط مرکب نیز باشد. for (count = 0; count < 100 && sw==1; count ++) نکته آخر اینکه قسمت مقدار دهی اولیه و افزایش متغیر نیز میتوانند شامل چند عبارت باشند که در اینصورت با کاما از یکدیگر جدا میشوند. for (a = 0, b = 100; b – a > 50; a++, b--)
169
3-8 ساختار تکرار for برنامه 5) برنامهای بنویسید که تعدادی عدد را از کاربر دریافت و 2 عدد بزرگتر و مجموع کل اعداد را محاسبه و چاپ نماید. #include <stdio.h> void main() { int i, n, number; int sum, max1, max2; printf(“please enter n : “); scanf(“%d”,&n); sum = 0; max1 = max2 = -1; for (i=0 ; i<n ; i++) { printf(“enter number : “); scanf(“%d”,&number); sum += number; if (number > max1) { max2 = max1; max1 = number; } else if (number > max2) max2 = number; } //end for printf(“Sum = %d, Maximum 1=%d, Maximum 2= %d”, sum, max1, max2);
170
3-8 ساختار تکرار for نکته جالب در مورد حلقه for آنستکه میتوان هریک از 3 عبارت آن را حذف کرد. for (; i<100; i++) for (i=0; i<100;) for (; i<100;) for (i=0; ;i++) در مورد آخر حتما باید در داخل حلقه با استفاده از دستور break (که در قسمتهای بعدی توضیح داده خواهد شد)، راهی برای خروج از حلقه قرار داده شود.
171
4-8 حلقه do / while do { <statement 1> ; <statement 2> ; …
<statement n> ; } while (<expression>); <next statement> ; ? false (= 0) true (≠ 0)
172
4-8 حلقه do / while یک مثال کوچک: char answer; do {
فرض کنید از کاربر خواسته اید که اعلام کند آیا مایل به ادامه هست یا خیر؟ وی باید پاسخ y یا n بدهد، اما ممکن است یک حرف اشتباه (مانند m) وارد کند. قصد داریم تکه برنامه ای بنویسیم که عمل دریافت پاسخ را تا زمانیکه یک حرف درست وارد شود، تکرار کند. مسلم است که باید ابتدا یک پاسخ وارد شود و سپس درستی آن بررسی گردد. char answer; do { printf("Do you want to continue (y/n) ?"); answer = getch(); } while (answer != 'y' && answer != 'n') ;
173
4-8 حلقه do / while برنامه 6) فرض کنید نمرات یک گروه از دانشجویان بصورت درجه بندی (A, B, C and D) آماده شده است. برنامه ای بنویسید که نمرات دانشجویان را دریافت و در پایان درصد هریک از نمرات را محاسبه و چاپ نماید. در ضمن از آنجا که تعداد دانشجویان از قبل مشخص نیست، کاربر در انتهای نمرات، حرف Q (مخفف Quit) را وارد مینماید. #include <stdio.h> #include <conio.h> void main() { int aCount, bCount, cCount, dCount, n; char grade; aCount = bCount = cCount = dCount = n = 0; do { printf("Enter grade (Q for Quit) : "); grade = getch() ; n ++; if (grade == 'A') aCount ++; else if (grade == 'B') bCount ++; else if (grade == 'C') cCount ++; else if (grade == 'D') dCount ++; else if (grade == 'Q') n --; else { printf("Wrong grade, try again.\n"); n --; } } while (grade != 'Q' ) ;
174
4-8 حلقه do / while printf("Statistics :\n");
printf("Grade A : %f percent\n", float(aCount)/float(n)); printf("Grade B : %f percent\n", float(bCount)/float(n)); printf("Grade C : %f percent\n", float(cCount)/float(n)); printf("Grade D : %f percent\n", float(dCount)/float(n)); } // end main
175
5-8 ساختار switch / case switch (<expression>) {
case <exp1> : <statement 1> ; <statement 2> ; … <statement n> ; case <exp2> : <statement 1> ; default : <statement 1> ; } <expression> == <exp1> ? false <expression> == <exp2> ? true if there is no match
176
5-8 ساختار switch / case توجه کنید که قسمت default اختیاری بوده و میتوان از آن استفاده نکرد. این ساختار فقط برای عبارات کاراکتری و صحیح معتبر بوده و نمیتوان در آن از عبارات اعشاری استفاده نمود. نکته مهم دیگر در مورد این ساختار این است که چنانچه عبارت <expression> با یک ثابت مانند <constant i> برابر باشد، آنگاه پس از اینکه دستورات مربوط به این حالت اجرا گردید، اجرا ادامه یافته و دستورات مربوط حالتهای بعدی تا انتهای switch انجام خواهد شد! به عنوان مثال چنانچه عبارت <expression> با ثابت <constant 2> برابر باشد، پس از اجرای دسترات مربوط به این حالت، دستورات حالتهای <constant 3> و ... تا <constant m> و حتی قسمت default نیز اجرا خواهد گردید. برای جلوگیری از این وضعیت که معمولا دلخواه برنامهنویسان نیست، میتوان از دستور break استفاده کرد. این دستور که بعدا در مورد آن توضیح بیشتری خواهیم داد، باعث میشود که از ساختار switch خارج شده و به دستور پس از آن برویم. بنابراین معمولا برنامهنویسان در پایان دستورات هر case، از یک دستور break استفاده میکنند. این کار باعث میشود که پس از اجرای دستورات مربوط به هر case، با رسیدن به دستور break بلافاصله از ساختار switch خارج شده و دستورات مربوط به case بعدی اجرا نشوند.
177
5-8 ساختار switch / case اما چرا در زبان C از این روش استفاده شده است بطوریکه برنامهنویسان مجبور به استفاده از دستور break شوند؟ جواب این است که میتوان با استفاده از این خاصیت، چندین case مختلف را با یکدیگر یای منطقی (or) کرد. فرض کنید چند case مختلف دارید که قصد دارید با وقوع هریک از آنها، مجموعه دستورات مشترکی انجام شوند. کافی است این caseها را بصورت پشت سرهم قرار داده و دستورات همگی آنها بجز case آخر را خالی قرار دهید. حال دستورات مشترک را در case آخر قرار داده و در انتها نیز یک دستور break بگذارید. اکنون چنانچه عبارت با هریک از این caseها برابر باشد، از آنجا که هیچیک دارای دستور break نیستند، اجرا تا case آخر ادامه خواهد یافت و در پایان دستورات مشترک اجرا خواهد شد.
178
5-8 ساختار switch / case بعنوان مثال فرض کنید یک متغیر صحیح بنام point داریم که امتیاز یک ورزشکار را بین 1 تا 5 مشخص مینماید. اکنون قصد داریم بسته به امتیاز ورزشکار، پیام مناسبی را برای وی چاپ نماییم. امتیاز 1 یا 2 ضعیف، امتیاز 3 متوسط، و امتیاز 4 یا 5 خوب ارزیابی میگردد. ساختار زیر این کار را انجام میدهد. switch (point) { case 1 : case 2 : printf("weak!\n"); break; case 3 : printf("medium!\n"); case 4 : case 5 : printf("good!\n"); default : printf("out of range!"); }
179
5-8 ساختار switch / case برنامه 7) برنامه 6 را با استفاده از دستور switch / case بازنویسی نمایید. برنامه را بگونه ای بنویسید که حروف بزرگ و کوچک هردو مورد قبول واقع شود. #include <stdio.h> void main() { int aCount, bCount, cCount, dCount, n; char grade; aCount = bCount = cCount = dCount = n = 0; do { printf("Enter grade (Q for Quit) : "); grade = getch() ; n ++;
180
5-8 ساختار switch / case switch (grade) { case 'A' :
case 'a' : aCount ++; break ; case 'B' : case 'b' : bCount ++; break ; case 'C' : case 'c' : cCount ++; break ; case 'D' : case 'd' : dCount ++; break ; case 'Q' : case 'q' : n--; break ; default : printf("Wrong grade, try again.\n"); n --; } //end switch } while (grade != 'Q' && grade!=‘q’) ; printf("Statistics :\n"); printf("Grade A : %f percent\n", float(aCount)/float(n)); printf("Grade B : %f percent\n", float(bCount)/float(n)); printf("Grade C : %f percent\n", float(cCount)/float(n)); printf("Grade D : %f percent\n", float(dCount)/float(n)); } // end main
181
5-8 ساختار switch / case برنامه 8) برنامه ای بنویسید که یک عدد، یک عملگر و یک عدد دیگر را از کاربر دریافت و پس از اعمال عملگر برروی دو عدد، حاصل را چاپ نماید. #include <stdio.h> void main() { int number1, number2, result; char op ; printf("Please enter number1 operator number2 : "); scanf("%d %c %d",&number1, &op, &number2); result = 0; switch (op) { case '+' : result = number1 + number2 ; break; case '-' : result = number1 - number2 ; break; case '*' : result = number1 * number2 ; break; case '/' : if (number2 != 0) result = number1 / number2 ; else printf("There is no answer!\n"); break; case '%' : if (number2 != 0) result = number1 % number2 ; else printf("There is no answer!\n"); default : printf("invalid operator!\n"); } printf("Result = %d",result);
182
6-8 دستور break while (<expression>) { <statements … > …
if (<exp1>) break ; } <next statement> true ( ≠ 0 ) ?
183
6-8 دستور break برنامه 9) برنامه 5 را بگونه ای تغییر دهید که فقط اعداد مثبت را بپذیرد، و درصورتیکه عدد منفی وارد شد، بلافاصله به عملیات خاتمه داده و نتایج تا همین نقطه را چاپ نماید. #include <stdio.h> void main() { int i, n, number; int sum, max1, max2; printf(“please enter n : “); scanf(“%d”,&n); sum = 0; max1 = max2 = -1; for (i=1 ; i<n ; i++) { printf(“enter number : “); scanf(“%d”,&number); if (number < 0) break; // this is the difference sum += number; if (number > max1) { max2 = max1; max1 = number; } else if (number > max2) max2 = number; } //end for printf(“Sum = %d, Maximum 1=%d, Maximum 2= d”, sum, max1, max2);
184
6-8 دستور continue while (<expression>) { <statements … >
if (<exp1>) continue ; } <next statement> true ( ≠ 0 ) ?
185
6-8 دستور continue بعنوان مثال، چنانچه بخواهیم برنامه 9 را بگونه ای تغییر دهیم که از اعداد منفی صرفنظر کند و آنها را در محاسبات لحاظ نکند، کافیست دستور if (number < 0) break; را به دستور زیر تبدیل کنیم: if (number < 0) continue; دراینصورت، چنانچه عدد منفی باشد، بدون اینکه محاسبات بعدی انجام شوند، کنترل به ابتدای حلقه بازگشته و عدد بعدی را دریافت میکند.
186
مبانی کامپیوتر و برنامه سازی
فصل نهم : توابع مدرس : دکتر سهیل افراز
187
9 توابع در مبحث الگوریتمها راجع به مزایای استفاده از زیرالگوریتمها صحبت کردیم. در برنامهنویسی نیز مباحث مشابهی در مورد زیربرنامهها وجود دارد. هنگامی که یک برنامه بیش از حد بزرگ میشود، برنامهنویسی و مدیریت آن مشکل میگردد و ممکن است از عهده یک نفر خارج باشد. در چنین شرایطی، برنامه را به چندین بخش کوچکتر (زیربرنامه) تقسیم کرده و هریک را بعهده یک برنامهنویس میگذاریم. هر قسمت به تنهایی نوشته شده و رفع اشکال میگردد. سپس این زیربرنامهها در کنار یکدیگر قرار گرفته و تشکیل برنامه اصلی را میدهند. اینکار نه تنها در تقسیم کار به ما کمک میکند، بلکه باعث میشود خوانایی برنامه نیز بالاتر رفته و اشکالزدایی آن ساده تر گردد. علاوه براین میتوان یک زیربرنامه را یکبار نوشت، و سپس در برنامه های مختلف از آن استفاده کرد که به این خاصیت، قابلیت استفاده مجدد از نرم افزار گفته میشود.
188
9 توابع در زبان C به هر زیربرنامه، یک تابع گفته میشود.
9 توابع در زبان C به هر زیربرنامه، یک تابع گفته میشود. یک تابع، تکه برنامه ای است که داده یا داده هایی را بعنوان ورودی دریافت، و داده یا داده هایی را بعنوان خروجی باز میگرداند. در زبان C، هر برنامه از یک یا چند تابع تشکیل میگردد، که یکی از آنها باید بنام main نامیده گردد و برنامه از این تابع شروع خواهد گردید. تابع main میتواند سایر توابع را فراخوانی نماید و هر یک از این توابع نیز میتوانند به نوبه خود، توابع دیگر را فراخوانی نمایند. نکته جالب اینجاست که تابع فراخواننده نیازی به دانستن نحوه کار تابعی که فراخوانی میکند، ندارد و تنها باید از نحوه فراخوانی و مقدار خروجی آن آگاه باشد. این نحوه پنهانسازی جزئیات پیاده سازی، نقش بسیار مهمی در مهندسی نرم افزار دارد. تاکنون از توابع کتابخانه های استاندارد C استفاده نموده ایم. کتابخانه استاندارد C مجموعه ای از توابع و نوع دادهها است که برای انجام عملیاتی که عموما مورد نیاز برنامهنویسان است، طراحی شده و همراه کامپایلر در اختیار برنامهنویسان قرار داده شده است. بعنوان مثال توابع ورودی/خروجی مانند printf و scanf و یا توابع ریاضی مانند sqrt و sin که توسط بسیاری از برنامهنویسان مورد استفاده قرار میگیرند. اما ازطرف دیگر، برنامهنویس نیز میتواند توابع مورد نیاز خود را تعریف کرده و از آنها در برنامه خود استفاده نماید. به این دسته از توابع، توابع کاربر میگوییم.
189
1-9 توابع کاربر بکار گیری توابع شامل دو قسمت است:
1-9 توابع کاربر بکار گیری توابع شامل دو قسمت است: تعریف تابع استفاده از تابع (فراخوانی تابع) ما در مثالهای قبلی تابع main را در برنامه های خود تعریف میکردیم. تعریف توابع دیگر نیز بطور مشابه میباشد، که جزئیات آن را بررسی خواهیم کرد. البته تابع اصلی بطور اتوماتیک در ابتدای اجرای برنامه فراخوانی میگردد و برنامهنویس صریحا آن را احضار نمیکند، ولی سایر توابع باید از داخل تابع دیگری (از جمله main) بطور صریح فراخوانی گردند. البته ما قبلا توابعی همچون scanf و printf را فراخوانی کرده ایم، اما جزئیات مربوط به نحوه فراخوانی را در قسمت بعدی بررسی مینماییم.
190
1-1-9 تعریف تابع قالب کلی تعریف تابع بصورت زیر است:
تعریف تابع قالب کلی تعریف تابع بصورت زیر است: <return-type> <function-name> (<param-type param-name> , … ) { <local variable definitions> ; <statements> ; } در این قسمت هرگونه متغیری که برای انجام وظایف محوله به تابع مورد نیاز باشد، تعریف میگردد. این متغیرها نیز همانند پارامترهای تابع، محلی محسوب میشوند و در سایر توابع شناخته شده نیستند. با شروع هر تابع، این متغیرها بطور اتوماتیک ایجاد شده و پس از خاتمه آن از بین میروند. پس از نام تابع و در داخل پرانتز، لیست پارامترهای تابع قرار میگیرد. این لیست شامل تعریف تعدادی پارامتر است که با کاما ',' از یکدیگر جدا شده اند. تعریف هر پارامتر شامل نوع و سپس نام پارامتر میباشد. پارامترها در حقیقت رابط بین تابع احضار کننده و تابع احضار شونده هستند. در این قسمت، دستورات تشکیل دهنده بدنه تابع که وظایف مورد نظر برنامهنویس را انجام میدهند، قرار میگیرند. نوع مقدار بازگشتی : نوع داده مقداری که توسط تابع بازگشت داده میشود را نشان میدهد. نام تابع در حقیقت یک شناسه است که از همان قوانین نامگذاری مربوط به شناسهها تبعیت میکند. یک تابع توسط نام خود فراخوانی میگردد.
191
تعریف تابع مقدار بازگشتی تابع توسط دستور return به تابع فراخواننده برگشت داده میشود. برای این کار کافی است به شکل زیر عمل نماییم: return (<exp>) ; و یا return <exp>; چنانچه تابع مقدار بازگشتی نداشته باشد، از کلمه کلیدی void بجای نوع مقدار بازگشتی استفاده مینماییم. دراینصورت، دستور return نیاز به مقدار بازگشتی ندارد. البته چنانچه تابع بیش از یک مقدار بازگشتی داشته باشد، باید از تکنیکهای گفته شده در قسمت بعد استفاده نماییم. لازم به ذکر است که در قسمت دستورات تابع باید یک (یا چند) دستور return داشته باشیم که کنترل را به تابع فراخواننده باز گرداند. البته درمورد توابعی که مقداری را باز نمیگردانند، درصورت عدم وجود دستور return، کنترل پس از رسیدن به انتهای تابع یعنی } بطور خودکار به تابع فراخواننده باز میگردد.
192
1-1-9 تعریف تابع نکته مهم دیگر مکان تعریف توابع در یک برنامه C است.
تعریف تابع نکته مهم دیگر مکان تعریف توابع در یک برنامه C است. یک برنامه C میتواند دارای یک یا چند تابع باشد که یکی از آنها باید حتما main نامیده شود و همانطور که قبلا نیز گفته شد، اجرای برنامه از این تابع آغاز میگردد. توابع میتوانند به هر ترتیبی تعریف شوند، اما معمولا تابع main در آخر توابع دیگر تعریف میگردد؛ گرچه این مسئله اجباری نیست. توابع باید بصورت پشت سر هم تعریف گردند و برخلاف بعضی از زبانهای دیگر، نمیتوان یک تابع را در داخل تابع دیگر تعریف کرد. بعبارت دیگر، کلیه توابع در یک سطح قرار دارند و هیچ تابعی، شامل تابع دیگر نمیباشد.
193
فراخوانی توابع برای فراخوانی یک تابع باید از نام آن بعلاوه لیست آرگومانهای متناسب با پارامترهای تابع استفاده کرد. نکته مهم آنستکه باید تعداد، ترتیب و نوع آرگومانهای ارسالی با پارامترهای متناظرشان در تعریف تابع، منطبق باشد. در غیراینصورت ممکن است خطای نحوی و یا حتی خطای منطقی رخ دهد. هنگامیکه یک تابع فراخوانی میگردد، اجرای تابع فراخواننده بطور موقت متوقف شده و کنترل اجرا به تابع فراخوانی شده منتقل میگردد. پس از اتمام تابع فراخوانی شده و اجرای دستور return توسط آن، کنترل اجرا به تابع فراخواننده بازگشته و اجرا را از دستور بعدی، از سر میگیرد.
194
فراخوانی توابع چنانچه تابع هیچ مقداری را بازنگرداند، میتوان آن را بصورت یک دستور مستقل فراخوانی کرد. بعنوان مثال : clrscr() ; اما توابعی که یک مقدار خروجی را باز میگردانند، میتوان در یک عبارت نسبت دهی یا محاسباتی نیز بکاربرد. بعنوان مثال میتوان تابع sqrt (که یک عدد را دریافت و جذر آن را باز میگرداند) را بصورت زیر استفاده کرد : a = sqrt(10) ; a = 2 * sqrt(b) + c ; نکته مهم آنستکه چنانچه فراخوانی تابع توسط مقدار باشد، آنگاه میتوان بجای یک متغیر یا یک ثابت، یک عبارت محاسباتی را نیز به تابع ارسال کرد. بعنوان مثال فراخوانی زیر مجاز است: a = sqrt(2*b+8) ; در اینحالت، ابتدا عبارت محاسباتی ارزیابی شده و سپس مقدار آن بعنوان آرگومان به تابع ارسال میگردد. البته درصورتیکه فراخوانی توسط ارجاع باشد، فقط یک متغیر میتواند به تابع ارسال گردد و عبارت محاسباتی و یا حتی یک ثابت به تنهایی نیز مورد قبول نخواهد بود.
195
2-1-9 فراخوانی توابع void main() { int a, b; a = 5 ; b = square(a) ;
فراخوانی توابع void main() { int a, b; a = 5 ; b = square(a) ; printf(“a=%d and b=%d”,a,b) } a : 5 x : 5 int square(int x) { return(x * x) ; } b : 25 return 25 a = 5 and b = 25
196
2-9 چند نمونه از توابع مثال 1) برنامه ای بنویسید که مقدار ترکیب n به k را محاسبه نماید. #include <stdio.h> long int factorial(int number) { int i; long int f = 1L ; for (i=1; i<=number; i++) f *= i ; return(f) ; } void main() { int n, k ; long int result; printf("please enter n and k : "); scanf("%d %d", &n, &k) ; result = factorial(n) / ( factorial(k) * factorial(n-k) ) ; printf("result = %ld", result) ;
197
2-9 چند نمونه از توابع مثال 2) برنامه ای بنویسید که تعدادی عدد را دریافت و سپس حداکثر آنها را محاسبه و چاپ نماید. برای اینکار از تابعی بنام getMax که دو عدد را دریافت و حداکثر آنها را باز میگرداند، استفاده نمایید. #include <stdio.h> #include <values.h> int getMax(int a, int b) { if (a>b) return(a); else return(b) ; } void main() { int i, n, max, number ; printf("Please enter n: "); scanf("%d",&n); max = -MAXINT-1; for (i=0; i<n; i++) { printf("Please enter number: "); scanf("%d", &number); max = getMax(number, max); printf("Maximum is : %d", max);
198
2-9 چند نمونه از توابع مثال 3) تابعی بنویسید که یک خط 40 تایی از علامت * را چاپ نماید. سپس با استفاده از آن برنامهای بنویسید که ابتدا پیام Hello و سپس خط جداکننده فوق را چاپ کند. #include <stdio.h> void starLine() { int i; for (i=0; i<40; i++) printf("*"); printf("\n"); } void main() { printf("Hello\n"); starLine() ;
199
2-9 چند نمونه از توابع البته درچنین مواردی، بهتر است برنامهنویس تابع رسم خط را بصورت کلی تری بنویسد؛ بطوریکه در سایر برنامهها نیز بتواند از آن استفاده نماید. مثلا چنانچه تابع را بگونهای بنویسیم که کاراکتر جداکننده و تعداد آن را بعنوان ورودی دریافت کند، حالت کلی تری پیدا خواهد کرد. #include <stdio.h> void separatorLine(char sep,int n) { int i; for (i=0; i<n; i++) printf("%c",sep); printf(“\n”); } void main() { printf("Hello\n"); separatorLine('-' ,60) ;
200
3-9 نمونه اولیه توابع همانطور که قبلا گفته شد، توابع میتوانند به هر ترتیبی تعریف شوند، ولی معمولا تابع main در انتها قرار میگیرد. اما اگر بخواهیم دقیقتر صحبت کنیم، تعریف هر تابع باید قبل از فراخوانی آن صورت پذیرد. چنانچه تابعی قبل از آنکه تعریف شود، فراخوانی گردد؛ یک خطای کامپایل رخ خواهد داد. اما میتوان این خطا را با استفاده از نمونه اولیه تابع (prototype) که به آن پیش تعریف نیز گفته میشود، از بین برد. یک نمونه اولیه تابع، شامل نام تابع، نوع دادهای که باز میگرداند و همچنین تعداد و نوع پارامترهای تابع است. برای مثال، نمونه اولیه تابع factorial بصورت زیر است: long int factorial(int) ; این نمونه اولیه میگوید که تابع factorial یک آرگومان از نوع int دریافت و یک مقدار از نوع long int باز میگرداند. علامت ; انتهای دستور نشان میدهد که این فقط یک نمونه اولیه بوده و شامل تعریف بدنه تابع نمیباشد. نمونه اولیه یک تابع حتما باید با تعریف آن (که در قسمتهای بعدی برنامه آمده است) یکسان باشد و گرنه یک خطای کامپایل رخ خواهد داد. کامپایلر از نمونه اولیه تابع برای بررسی درستی نحوه فراخوانی تابع (از نظر تعداد و نوع آرگومانها) استفاده میکند.
201
The life goes on…
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.