برنامه سازی ++C (توابع)
در نمایش آنلاین پاورپوینت، ممکن است بعضی علائم، اعداد و حتی فونتها به خوبی نمایش داده نشود. این مشکل در فایل اصلی پاورپوینت وجود ندارد.
- جزئیات
- امتیاز و نظرات
- متن پاورپوینت
امتیاز
برنامه سازی ++C (توابع)
اسلاید 1: بسم الله الرحمن الرحيم
اسلاید 2: تعداد واحد: 3تهيه كننده: دکتر حسن توکلیبرنامه سازي
اسلاید 3: جلسه پنجم« توابع»
اسلاید 4: آنچه در اين جلسه مي خوانيد:1- توابع كتابخانهاي C++ استاندارد2- توابع ساخت كاربر3- برنامۀ آزمون4- اعلانها و تعاريف تابع5- كامپايل جداگانۀ توابع6- متغيرهاي محلي، توابع محلي›››
اسلاید 5: 7- تابع void 8 - توابع بولي 9- توابع ورودي/خروجي (I/O) 10- ارسال به طريق ارجاع (آدرس) 11- ارسال از طريق ارجاع ثابت 12-توابع بيواسطه ›››
اسلاید 6: 13- چندشکلي توابع 14- تابع main() 15- آرگومانهاي پيشفرض
اسلاید 7: هدف کلي:شناخت و معرفي توابع و مزاياي استفاده از تابع در برنامههاهدفهاي رفتاري:انتظار ميرود پس از پايان اين جلسه بتوانيد:- اهميت توابع و مزيت استفاده از آنها را بيان کنيد.- «اعلان» و «تعريف» تابع را بدانيد و خودتان توابعي را ايجاد کنيد.- «برنامۀ آزمون» را تعريف کرده و دليل استفاده از آن را بيان نماييد.- مفهوم «آرگومان» را بدانيد.- تفاوت ارسال به طريق «ارجاع» و ارسال به طريق «مقدار» و ارسال به طريق «ارجاع ثابت» را بيان کنيد و شکل استفاده از هر يک را بدانيد.›››
اسلاید 8: - «تابع بيواسطه» را شناخته و نحوۀ معرفي آن را بدانيد.- چندشکلي توابع را تعريف کنيد و شيوۀ آن را بدانيد.- طريقۀ بهکارگيري آرگومانهاي پيشفرض را بدانيد.- فرق بين تابع void با ساير توابع را بدانيد.
اسلاید 9: 1-مقدمهبرنامههاي واقعي و تجاري بسيار بزرگتر از برنامههايي هستند که تاکنون بررسي کرديم. براي اين که برنامههاي بزرگ قابل مديريت باشند، برنامهنويسان اين برنامهها را به زيربرنامههايي بخشبندي ميکنند. اين زيربرنامهها «تابع» ناميده ميشوند. توابع را ميتوان به طور جداگانه کامپايل و آزمايش نمود و در برنامههاي مختلف دوباره از آنها استفاده کرد.
اسلاید 10: 2- توابع كتابخانهاي C++ استاندارد«كتابخانۀ C++ استاندارد» مجموعهاي است که شامل توابع از پيش تعريف شده و ساير عناصر برنامه است. اين توابع و عناصر از طريق «سرفايلها» قابل دستيابياند.قبلا برخي از آنها را استفاده كردهايم: ثابت INT_MAX که در <climits> تعريف شده ، تابع ()sqrt که در <cmath> تعريف شده است و... .
اسلاید 11: تابع جذر sqrt()ريشۀ دوم يك عدد مثبت، جذر آن عدد است.تابع مانند يک برنامۀ کامل، داراي روند ورودي - پردازش - خروجي است هرچند که پردازش، مرحلهاي پنهان است. يعني نميدانيم که تابع روي عدد 2 چه اعمالي انجام ميدهد که 41421/1 حاصل ميشود.
اسلاید 12: برنامۀ سادۀ زير، تابع از پيش تعريف شدۀ جذر را به کار ميگيرد:#include <cmath> // defines the sqrt() function#include <iostream> // defines the cout object using namespace std;int main(){ //tests the sqrt() function: for (int x=0; x < 6; x++) cout << t << x << t << sqrt(x) << endl;} براي اجراي يك تابع مانند تابع sqrt() کافي است نام آن تابع به صورت يک متغير در دستورالعمل مورد نظر استفاده شود، مانند زير:y=sqrt(x);
اسلاید 13: اين کار «فراخواني تابع» يا «احضار تابع» گفته ميشود. بنابراين وقتي كد sqrt(x) اجرا شود، تابع sqrt() فراخواني ميگردد. عبارت x درون پرانتز «آرگومان» يا «پارامتر واقعي» فراخواني ناميده ميشود. در چنين حالتي ميگوييم كه x توسط «مقدار» به تابع فرستاده ميشود. لذا وقتي x=3 است، با اجراي کد sqrt(x) تابع sqrt() فراخواني شده و مقدار 3 به آن فرستاده ميشود. تابع مذکور نيز حاصل 1.73205 را به عنوان پاسخ برميگرداند…
اسلاید 14: … اين فرايند در نمودار زير نشان داده شده. 31.73205xyMain()doubleintSqrt()31.73205متغيرهاي x و y در تابع main() تعريف شدهاند. مقدار x که برابر با 3 است به تابع sqrt() فرستاده ميشود و اين تابع مقدار 1.73205 را به تابع main() برميگرداند. جعبهاي كه تابع sqrt() را نشان ميدهد به رنگ تيره است، به اين معنا كه فرايند داخلي و نحوۀ کار آن قابل رويت نيست.
اسلاید 15: مثال 2-5 آزمايش يك رابطۀ مثلثاتياين برنامه هم از سرفايل <cmath> استفاده ميكند. هدف اين است که صحت رابطۀ Sin2x=2SinxCosx به شکل تجربي بررسي شود.int main(){ for (float x=0; x < 2; x += 0.2) cout << x << tt << sin(2*x) << t“ << 2*sin(x)*cos(x) << endl;}
اسلاید 16: 0 0 00.2 0.389418 0.3894180.4 0.717356 0.7173560.6 0.932039 0.9320390.8 0.999574 0.9995741 0.909297 0.9092971.2 0.675463 0.6754631.4 0.334988 0.3349881.6 -0.0583744 -0.05837441.8 -0.442521 -0.442521برنامۀ مقدار x را در ستون اول، مقدار Sin2x را در ستون دوم و مقدار 2SinxCosx را در ستون سوم چاپ ميكند. خروجي برنامه:خروجي نشان ميدهد که براي هر مقدار آزمايشي x، مقدار Sin2x با مقدار 2SinxCosx برابر است.
اسلاید 17: بيشتر توابع معروف رياضي كه در ماشينحسابها هم وجود دارد در سرفايل <cmath> تعريف شده است. بعضي از اين توابع در جدول زير نشان داده شده:
اسلاید 19: توجه داشته باشيد که هر تابع رياضي يک مقدار از نوع double را برميگرداند. اگر يك نوع صحيح به تابع فرستاده شود، قبل از اين كه تابع آن را پردازش کند، مقدارش را به نوع double ارتقا ميدهد.
اسلاید 20: بعضي از سرفايلهاي كتابخانۀ C++ استاندارد که کاربرد بيشتري دارند در جدول زير آمده است:اين سرفايلها از كتابخانۀ C استاندارد گرفته شدهاند. استفاده از آنها شبيه استفاده از سرفايلهاي C++ استاندارد (مانند <iostream> ) است. براي مثال اگر بخواهيم تابع اعداد تصادفي rand() را از سرفايل <cstdlib> به كار ببريم، بايد دستور پيشپردازندۀ زير را به ابتداي فايل برنامۀ اصلي اضافه کنيم:#include <cstdlib>
اسلاید 21: 3- توابع ساخت كاربرگرچه توابع بسيار متنوعي در کتابخانۀ C++ استاندارد وجود دارد ولي اين توابع براي بيشتر وظايف برنامهنويسي كافي نيستند. علاوه بر اين برنامهنويسان دوست دارند خودشان بتوانند توابعي را بسازند و استفاده نمايند.
اسلاید 22: مثال 3-5 تابع cube()يك مثال ساده از توابع ساخت كاربر:int cube(int x){ // returns cube of x: return x*x*x;}اين تابع، مكعب يك عدد صحيح ارسالي به آن را برميگرداند. بنابراين فراخواني cube(2) مقدار 8 را برميگرداند.
اسلاید 23: نوع بازگشتي تابع cube() که در بالا تعريف شد، int است. نام آن cube ميباشد و يک پارامتر از نوع int به نام x دارد. يعني تابع cube() يک مقدار از نوع int ميگيرد و پاسخي از نوع int تحويل ميدهد. بدنۀ تابع، يك بلوك كد است كه در ادامۀ عنوان آن ميآيد. بدنه شامل دستوراتي است كه بايد انجام شود تا نتيجۀ مورد نظر به دست آيد. بدنه شامل دستور return است كه پاسخ نهايي را به مكان فراخواني تابع برميگرداند. يك تابع ساخت كاربر دو قسمت دارد: 1-عنوان 2- بدنه. عنوان يك تابع به صورت زير است:(فهرست پارامترها) نام نوع بازگشتي مثال:int cube(int x){… بدنه تابع }
اسلاید 24: دستور return دو وظيفۀ عمده دارد. اول اين که اجراي تابع را خاتمه ميدهد و دوم اين که مقدار نهايي را به برنامۀ فراخوان باز ميگرداند. دستور return به شکل زير استفاده ميشود:return expression;به جاي expression هر عبارتي قرار ميگيرد که بتوان مقدار آن را به يک متغير تخصيص داد. نوع آن عبارت بايد با نوع بازگشتي تابع يکي باشد.عبارت int main() که در همۀ برنامهها استفاده کردهايم يک تابع به نام «تابع اصلي» را تعريف ميکند. نوع بازگشتي اين تابع از نوع int است. نام آن main است و فهرست پارامترهاي آن خالي است؛ يعني هيچ پارامتري ندارد.
اسلاید 25: وقتي يک تابع مورد نياز را ايجاد کرديد، فورا بايد آن تابع را با يک برنامۀ ساده امتحان کنيد. چنين برنامهاي برنامۀ آزمون ناميده ميشود. 4- برنامۀ آزمون برنامۀ آزمون يک برنامۀ موقتي است که بايد «سريع و کثيف» باشد؛ يعني: لازم نيست در آن تمام ظرافتهاي برنامهنويسي – مثل پيغامهاي خروجي، برچسبها و راهنماهاي خوانا – را لحاظ کنيد. تنها هدف اين برنامه، امتحان کردن تابع و بررسي صحت کار آن است.
اسلاید 26: مثال 4-5 يك برنامۀ آزمون براي تابع cube()کد زير شامل تابع cube() و برنامۀ آزمون آن است:int cube(int x){ // returns cube of x: return x*x*x;}int main(){ // tests the cube() function: int n=1; while (n != 0) { cin >> n; cout << tcube( << n << ) = << cube(n) << endl; }}برنامۀ حاضر اعداد صحيح را از ورودي ميگيرد و مكعب آنها را چاپ ميكند تا اين كه كاربر مقدار 0 را وارد كند.
اسلاید 27: هر عدد صحيحي که خوانده ميشود، با استفاده از کد cube(n) به تابع cube() فرستاده ميشود. مقدار بازگشتي از تابع، جايگزين عبارت cube(n) گشته و با استفاده از cout در خروجي چاپ ميشود. ميتوان رابطۀ بين تابع main() و تابع cube() را شبيه اين شکل تصور نمود: 5 nint5125cube()main()5 xintدقت كنيد كه تابع cube() در بالاي تابع main() تعريف شده زيرا قبل از اين كه تابعcube() در تابع main() به كار رود، كامپايلر C++ بايد در بارۀ آن اطلاع حاصل كند.
اسلاید 28: مثال 5-5 يك برنامۀ آزمون براي تابع max()تابع زير دو پارامتر دارد. اين تابع از دو مقدار فرستاده شده به آن، مقدار بزرگتر را برميگرداند:int max(int x, int y){ // returns larger of the two given integers: int z; z = (x > y) ? x : y ; return z;}int main(){ int m, n; do { cin >> m >> n; cout << tmax( << m << , << n << ) = << max(m,n) << endl; } while (m != 0);}
اسلاید 29: توابع ميتوانند بيش از يک دستور return داشته باشند. مثلا تابع max() را مانند اين نيز ميتوانستيم بنويسيم:int max(int x, int y){ // returns larger of the two given integers: if (x < y) return y; else return x;}در اين کد هر دستور return که زودتر اجرا شود مقدار مربوطهاش را بازگشت داده و تابع را خاتمه ميدهد. دستور return نوعي دستور پرش است (شبيه دستور break ) زيرا اجرا را به بيرون از تابع هدايت ميکند. اگرچه معمولا return در انتهاي تابع قرار ميگيرد، ميتوان آن را در هر نقطۀ ديگري از تابع قرار داد.
اسلاید 30: 5- اعلانها و تعاريف تابعبه دو روش ميتوان توابع را تعريف نمود:1-توابع قبل از تابع main() به طور كامل با بدنه مربوطه آورده شوند.2-راه ديگري که بيشتر رواج دارد اين گونه است که ابتدا تابع اعلان شود، سپس متن برنامۀ اصليmain() بيايد، پس از آن تعريف کامل تابع قرار بگيرد.
اسلاید 31: اعلان تابع با تعريف تابع تفاوت دارد. اعلان تابع، فقط عنوان تابع است که يک سميکولن در انتهاي آن قرار دارد.تعريف تابع، متن کامل تابع است که هم شامل عنوان است و هم شامل بدنه. اعلان تابع شبيه اعلان متغيرهاست. يک متغير قبل از اين که به کار گرفته شود بايد اعلان شود. تابع هم همين طور است با اين فرق که متغير را در هر جايي از برنامه ميتوان اعلان کرد اما تابع را بايد قبل از برنامۀ اصلي اعلان نمود.
اسلاید 32: همينها براي کامپايلر کافي است تا بتواند کامپايل برنامه را آغاز کند. سپس در زمان اجرا به تعريف بدنۀ تابع نيز احتياج ميشود که اين بدنه در انتهاي برنامه و پس از تابع main() قرار ميگيرد.در اعلان تابع فقط بيان ميشود که نوع بازگشتي تابع چيست، نام تابع چيست و نوع پارامترهاي تابع چيست.
اسلاید 33: فرق بين «آرگومان» و «پارامتر» :پارامترها متغيرهايي هستند که در فهرست پارامتر يک تابع نام برده ميشوند. پارامترها متغيرهاي محلي براي تابع محسوب ميشوند؛ يعني فقط در طول اجراي تابع وجود دارند. آرگومانها متغيرهايي هستند که از برنامۀ اصلي به تابع فرستاده ميشوند.
اسلاید 34: int max(int,int);int main(){ int m, n; do { cin >> m >> n; cout << tmax( << m << , << n << ) = << max(m,n) << endl; } while (m != 0);}int max(int x, int y){ if (x < y) return y; else return x;}مثال 6-5 تابعmax() با اعلان جدا از تعريف آناين برنامه همان برنامۀ آزمون تابع max() در مثال 5-6 است. اما اينجا اعلان تابع بالاي تابع اصلي ظاهر شده و تعريف تابع بعد از برنامۀ اصلي آمده است:توجه كنيد كه پارامترهاي x و y در بخش عنوان تعريف تابع آمدهاند (طبق معمول) ولي در اعلان تابع وجود ندارند.
اسلاید 35: اغلب اين طور است که تعريف و بدنۀ توابع در فايلهاي جداگانهاي قرار ميگيرد. اين فايلها به طور مستقل کامپايل1 ميشوند و سپس به برنامۀ اصلي که آن توابع را به کار ميگيرد الصاق2 ميشوند. 6- كامپايل جداگانۀ توابع توابع کتابخانۀ C++ استاندارد به همين شکل پيادهسازي شدهاند و هنگامي که يکي از آن توابع را در برنامههايتان به کار ميبريد بايد با دستور راهنماي پيشپردازنده، فايل آن توابع را به برنامهتان ضميمه کنيد. اين کار چند مزيت دارد:
اسلاید 36: 1- اولين مزيت «مخفيسازي اطلاعات» است. 2-مزيت ديگر اين است که توابع مورد نياز را ميتوان قبل از اين که برنامۀ اصلي نوشته شود، جداگانه آزمايش نمود. 3-سومين مزيت اين است که در هر زماني به راحتي ميتوان تعريف توابع را عوض کرد بدون اين که لازم باشد برنامۀ اصلي تغيير يابد.4-چهارمين مزيت هم اين است که ميتوانيد يک بار يک تابع را کامپايل و ذخيره کنيد و از آن پس در برنامههاي مختلفي از همان تابع استفاده ببريد.
اسلاید 37: int max(int x, int y){ if (x < y) return y; else return x;}max.cppتابع max() را به خاطر بياوريد. براي اين که اين تابع را در فايل جداگانهاي قرار دهيم، تعريف آن را در فايلي به نام max.cpp ذخيره ميکنيم. فايل max.cpp شامل کد زير است:
اسلاید 38: حال كافي است عبارت:#include <test.cpp> را به اول برنامه اصلي وقبل ازmain() اضافه كنيم:#include <test.cpp> int main(){ // tests the max() function: int m, n; do { cin >> m >> n; cout << tmax( << m << , << n << ) = << max(m,n) << endl; } while (m != 0);}
اسلاید 39: نحوۀ کامپايل کردن فايلها و الصاق آنها به يکديگر به نوع سيستم عامل و نوع کامپايلر بستگي دارد. در سيستم عامل ويندوز معمولا توابع را در فايلهايي از نوع DLL کامپايل و ذخيره ميکنند و سپس اين فايل را در برنامۀ اصلي احضار مينمايند. فايلهاي DLL را به دو طريق ايستا و پويا ميتوان مورد استفاده قرار داد. براي آشنايي بيشتر با فايلهاي DLL به مرجع ويندوز و کامپايلرهاي C++ مراجعه کنيد.
اسلاید 40: 6- متغيرهاي محلي، توابع محليمتغير محلي، متغيري است که در داخل يک بلوک اعلان گردد. اين گونه متغيرها فقط در داخل همان بلوکي که اعلان ميشوند قابل دستيابي هستند. چون بدنۀ تابع، خودش يک بلوک است پس متغيرهاي اعلان شده در يک تابع متغيرهاي محلي براي آن تابع هستند. اين متغيرها فقط تا وقتي که تابع در حال کار است وجود دارند. پارامترهاي تابع نيز متغيرهاي محلي محسوب ميشوند.
اسلاید 41: * مثال 7-5 تابع فاكتوريلاعداد فاكتوريل را در مثال 8-5 ديديم. فاكتوريل عدد صحيح n برابر است با:n! = n(n-1)(n-2)..(3)(2)(1)تابع زير، فاکتوريل عدد n را محاسبه ميکند:long fact(int n){ //returns n! = n*(n-1)*(n-2)*...*(2)*(1) if (n < 0) return 0; int f = 1; while (n > 1) f *= n--; return f;}اين تابع دو متغير محلي دارد: n و f پارامتر n يک متغير محلي است زيرا در فهرست پارامترهاي تابع اعلان شده و متغير f نيز محلي است زيرا درون بدنۀ تابع اعلان شده است.
اسلاید 42: همان گونه که متغيرها ميتوانند محلي باشند، توابع نيز ميتوانند محلي باشند. يک تابع محلي تابعي است که درون يک تابع ديگر به کار رود. با استفاده از چند تابع ساده و ترکيب آنها ميتوان توابع پيچيدهتري ساخت. به مثال زير نگاه کنيد. تابع محلي در رياضيات، تابع جايگشت را با p(n,k) نشان ميدهند. اين تابع بيان ميکند که به چند طريق ميتوان k عنصر دلخواه از يک مجموعۀ n عنصري را کنار يکديگر قرار داد. براي اين محاسبه از رابطۀ زير استفاده ميشود:
اسلاید 43: پس به 12 طريق ميتوانيم دو عنصر دلخواه از يک مجموعۀ چهار عنصري را کنار هم بچينيم. براي دو عنصر از مجموعۀ {1, 2, 3, 4} حالتهاي ممکن عبارت است از:12, 13, 14, 21, 23, 24, 31, 32, 34, 41, 42, 43كد زير تابع جايگشت را پيادهسازي ميكند:long perm(int n, int k){// returns P(n,k), the number of the permutations of k from n: if (n < 0) || k < 0 || k > n) return 0; return fact(n)/fact(n-k);}اين تابع، خود از تابع ديگري که همان تابع فاکتوريل است استفاده کرده است. شرط به کار رفته در دستور if براي محدود کردن حالتهاي غير ممکن استفاده شده است. در اين حالتها، تابع مقدار 0 را برميگرداند تا نشان دهد که يک ورودي اشتباه وجود داشته است.
اسلاید 44: برنامۀ آزمون براي تابع perm() در ادامه آمده است:long perm(int,int);// returns P(n,k), the number of permutations of k from n:int main(){ // tests the perm() function: for (int i = -1; i < 8; i++) { for (int j= -1; j <= i+1; j++) cout << << perm(i,j); cout << endl; }}0 00 1 00 1 1 00 1 2 2 00 1 3 6 6 00 1 4 12 24 24 00 1 5 20 60 120 120 00 1 6 30 120 360 720 720 00 1 7 42 210 840 2520 5040 5040 0
اسلاید 45: 7- تابع voidلازم نيست يك تابع حتما مقداري را برگرداند. در C++ براي مشخص کردن چنين توابعي از کلمۀ کليدي void به عنوان نوع بازگشتي تابع استفاده ميکنند يک تابع void تابعي است که هيچ مقدار بازگشتي ندارد. از آنجا كه يك تابع void مقداري را برنميگرداند، نيازي به دستور return نيست ولي اگر قرار باشد اين دستور را در تابع void قرار دهيم، بايد آن را به شکل تنها استفاده کنيم بدون اين که بعد از کلمۀ return هيچ چيز ديگري بيايد:return;در اين حالت دستور return فقط تابع را خاتمه ميدهد.
اسلاید 46: 8- توابع بوليدر بسياري از اوقات لازم است در برنامه، شرطي بررسي شود. اگر بررسي اين شرط به دستورات زيادي نياز داشته باشد، بهتر است که يک تابع اين بررسي را انجام دهد. اين کار مخصوصا هنگامي که از حلقهها استفاده ميشود بسيار مفيد است.توابع بولي فقط دو مقدار را برميگردانند: true يا false . اسم توابع بولي را معمولا به شکل سوالي انتخاب ميکنند زيرا توابع بولي هميشه به يک سوال مفروض پاسخ بلي يا خير ميدهند.
اسلاید 47: مثال 10-5 تابعي كه اول بودن اعداد را بررسي ميكندکد زير يك تابع بولي است كه تشخيص ميدهد آيا عدد صحيح ارسال شده به آن، اول است يا خير:bool isPrime(int n){ // returns true if n is prime, false otherwise: float sqrtn = sqrt(n); if (n < 2) return false; // 0 and 1 are not primes if (n < 4) return true; // 2 and 3 are the first primes if (n%2 == 0) return false; // 2 is the only even prime for (int d=3; d <= sqrtn; d += 2) if (n%d == 0) return false; // n has a nontrivial divisor return true; // n has no nontrivial divisors}
اسلاید 48: 9- توابع ورودي/خروجي (I/O)بخشهايي از برنامه که به جزييات دست و پا گير ميپردازد و خيلي به هدف اصلي برنامه مربوط نيست را ميتوان به توابع سپرد. در چنين شرايطي سودمندي توابع محسوستر ميشود. فرض کنيد نرمافزاري براي سيستم آموزشي دانشگاه طراحي کردهايد که سوابق تحصيلي دانشجويان را نگه ميدارد. در اين نرمافزار لازم است که سن دانشجو به عنوان يکي از اطلاعات پروندۀ دانشجو وارد شود. اگر وظيفۀ دريافت سن را به عهدۀ يک تابع بگذاريد، ميتوانيد جزيياتي از قبيل کنترل ورودي معتبر، يافتن سن از روي تاريخ تولد و ... را در اين تابع پيادهسازي کنيد بدون اين که از مسير برنامۀ اصلي منحرف شويد.
اسلاید 49: قبلا نمونهاي از توابع خروجي را ديديم. تابع PrintDate() در مثال 9-5 هيچ چيزي به برنامۀ اصلي برنميگرداند و فقط براي چاپ نتايج به کار ميرود. اين تابع نمونهاي از توابع خروجي است؛ يعني توابعي که فقط براي چاپ نتايج به کار ميروند و هيچ مقدار بازگشتي ندارند. توابع ورودي نيز به همين روش کار ميکنند اما در جهت معکوس. يعني توابع ورودي فقط براي دريافت ورودي و ارسال آن به برنامۀ اصلي به کار ميروند و هيچ پارامتري ندارند. مثال بعد يک تابع ورودي را نشان ميدهد.
اسلاید 50: مثال 11-5 تابعي براي دريافت سن كاربرتابع سادۀ زير، سن کاربر را درخواست ميکند و مقدار دريافت شده را به برنامۀ اصلي ميفرستد. اين تابع تقريبا هوشمند است و هر عدد صحيح ورودي غير منطقي را رد ميکند و به طور مکرر درخواست ورودي معتبر ميکند تا اين که يک عدد صحيح در محدودۀ 7 تا 120 دريافت دارد: int age(){ // prompts the user to input his/her age and returns that value: int n; while (true) { cout << How old are you: ; cin >> n; if (n < 0) cout << atYour age could not be negative.; else if (n > 120) cout << atYou could not be over 120.; else return n; cout << ntTry again.n; }}
اسلاید 51: يك برنامۀ آزمون و خروجي حاصل از آن در ادامه آمده است:int age()int main(){ // tests the age() function: int a = age(); cout << nYou are << a << years old.n;}How old are you? 125 You could not be over 120 Try again.How old are you? -3 Your age could not be negative Try again.How old are you? 99You are 99 years old.
اسلاید 52: تا اين لحظه تمام پارامترهايي كه در توابع ديديم به طريق مقدار ارسال شدهاند. يعني ابتدا مقدار متغيري که در فراخواني تابع ذکر شده برآورد ميشود و سپس اين مقدار به پارامترهاي محلي تابع فرستاده ميشود. مثلا در فراخواني cube(x) ابتدا مقدار x برآورد شده و سپس اين مقدار به متغير محلي n در تابع فرستاده ميشود و پس از آن تابع کار خويش را آغاز ميکند. در طي اجراي تابع ممکن است مقدار n تغيير کند اما چون n محلي است هيچ تغييري روي مقدار x نميگذارد.
اسلاید 53: پس خود x به تابع نميرود بلکه مقدار آن درون تابع کپي ميشود. تغيير دادن اين مقدار کپي شده درون تابع هيچ تاثيري بر x اصلي ندارد. به اين ترتيب تابع ميتواند مقدار x را بخواند اما نميتواند مقدار x را تغيير دهد. به همين دليل به x يک پارامتر «فقط خواندني» ميگويند. وقتي ارسال به وسيلۀ مقدار باشد، هنگام فراخواني تابع ميتوان از عبارات استفاده کرد. مثلا تابع cube() را ميتوان به صورتcube(2*x-3) فراخواني کرد يا به شکل cube(2*sqrt(x)-cube(3)) فراخواني نمود. در هر يک از اين حالات، عبارت درون پرانتز به شکل يک مقدار تکي برآورد شده و حاصل آن مقدار به تابع فرستاده ميشود.
اسلاید 54: 10- ارسال به طريق ارجاع (آدرس)ارسال به طريق مقدار باعث ميشود که متغيرهاي برنامۀ اصلي از تغييرات ناخواسته در توابع مصون بمانند. اما گاهي اوقات عمدا ميخواهيم اين اتفاق رخ دهد. يعني ميخواهيم که تابع بتواند محتويات متغير فرستاده شده به آن را دستکاري کند. در اين حالت از ارسال به طريق ارجاع استفاده ميکنيم.
اسلاید 55: براي اين که مشخص کنيم يک پارامتر به طريق ارجاع ارسال ميشود، علامت را به نوع پارامتر در فهرست پارامترهاي تابع اضافه ميکنيم. اين باعث ميشود که تابع به جاي اين که يک کپي محلي از آن آرگومان ايجاد کند، خود آرگومان محلي را به کار بگيرد. به اين ترتيب تابع هم ميتواند مقدار آرگومان فرستاده شده را بخواند و هم ميتواند مقدار آن را تغيير دهد. در اين حالت آن پارامتر يک پارامتر «خواندني-نوشتني» خواهد بود. &
اسلاید 56: * مثال 12-5 تابع swap()تابع كوچك زير در مرتب کردن دادهها کاربرد فراوان دارد:void swap(float& x, float& y){ // exchanges the values of x and y: float temp = x; x = y; y = temp;}هر تغييري که روي پارامتر خواندني-نوشتني در تابع صورت گيرد به طور مستقيم روي متغير برنامۀ اصلي اعمال ميشود. به مثال زير نگاه کنيد.هدف اين تابع جابجا کردن دو عنصري است که به آن فرستاده ميشوند. براي اين منظور پارامترهاي x و y به صورت پارامترهاي ارجاع تعريف شدهاند:float& x, float& y
اسلاید 57: عملگر ارجاع & موجب ميشود كه به جاي x و y آرگومانهاي ارسالي قرار بگيرند. برنامۀ آزمون و اجراي آزمايشي آن در زير آمده است:void swap(float&, float&)// exchanges the values of x and y:int main(){ // tests the swap() function: float a = 55.5, b = 88.8; cout << a = << a << , b = << b << endl; swap(a,b); cout << a = << a << , b = << b << endl;}a = 55.5, b = 88.8a = 88.8, b = 55.5
اسلاید 58: وقتي فراخواني swap(a,b) اجرا ميشود، x به a اشاره ميکند و y به b. سپس متغير محلي temp اعلان ميشود و مقدار x (که همان a است) درون آن قرار ميگيرد. پس از آن مقدار y (که همان b است) درون x (يعني a) قرار ميگيرد و آنگاه مقدار temp درون y (يعني b) قرار داده ميشود. نتيجۀ نهايي اين است که مقادير a و b با يکديگر جابجا مي شوند. شکل مقابل نشان ميدهد که چطور اين جابجايي رخ ميدهد: 55.5afloatmain()xfloat&88.8bfloatyfloat&88.8afloatswap()main()xfloat&55.5bfloatyfloat&55.5tempfloatهنگام فراخواني تابع swap(a,b)بعد از بازگشتswap()
اسلاید 59: به اعلان تابع swap() دقت کنيد:void swap(float&, float&)اين اعلان شامل عملگر ارجاع & براي هر پارامتر است. برنامهنويسان c عادت دارند که عملگر ارجاع & را به عنوان پيشوند نام متغير استفاده کنند (مثلfloat &x) در C++ فرض ميکنيم عملگر ارجاع & پسوند نوع است (مثل float& x) به هر حال کامپايلر هيچ فرقي بين اين دو اعلان نميگذارد و شکل نوشتن عملگر ارجاع کاملا اختياري و سليقهاي است.
اسلاید 60: مثال 13-5 ارسال به طريق مقدار و ارسال به طريق ارجاعاين برنامه، تفاوت بين ارسال به طريق مقدار و ارسال به طريق ارجاع را نشان ميدهد:void f(int,int&);int main(){ int a = 22, b = 44; cout << a = << a << , b = << b << endl; f(a,b); cout << a = << a << , b = << b << endl; f(2*a-3,b); cout << a = << a << , b = << b << endl;}void f(int x , int& y){ x = 88; y = 99;}a = 22, b = 44a = 22, b = 99a = 22, b = 99تابع f() دو پارامتر دارد که اولي به طريق مقدار و دومي به طريق ارجاع ارسال ميشود. فراخواني f(a,b) باعث ميشود که a از طريق مقدار به x ارسال شود و b از طريق ارجاع به y فرستاده شود.
اسلاید 61: 22aintmain()22xint44bintyint&f()هنگام فراخواني تابع f(a,b) شکل زير نحوۀ کار تابع f() را نشان ميدهد.22aintmain()88xxint99bintyint&f()بعد از بازگشت
اسلاید 62: ارسال از طريق ارجاعارسال از طريق مقدارint& x;int x;پارامتر x يک ارجاع استپارامتر x يک متغير محلي استx مترادف با آرگومان استx يک کپي از آرگومان استميتواند محتويات آرگومان را تغيير دهدتغيير محتويات آرگومان ممکن نيستآرگومان ارسال شده از طريق ارجاع فقط بايد يک متغير باشدآرگومان ارسال شده از طريق مقدار ميتواند يک ثابت، يک متغير يا يک عبارت باشدآرگومان خواندني-نوشتني استآرگومان فقط خواندني استدر جدول زير خلاصۀ تفاوتهاي بين ارسال از طريق مقدار و ارسال از طريق ارجاع آمده است.
اسلاید 63: يكي از مواقعي كه پارامترهاي ارجاع مورد نياز هستند جايي است كه تابع بايد بيش از يك مقدار را بازگرداند. دستور return فقط ميتواند يك مقدار را برگرداند. بنابراين اگر بايد بيش از يك مقدار برگشت داده شود، اين كار را پارامترهاي ارجاع انجام ميدهند.
اسلاید 64: * مثال 14-5 بازگشت بيشتر از يك مقدارتابع زير از طريق دو پارامتر ارجاع، دو مقدار را بازميگرداند: area و circumference (محيط و مساحت) براي دايرهاي که شعاع آن عدد مفروض r است:void ComputeCircle(double& area, double& circumference, double r){ // returns the area and circumference of a circle with radius r: const double PI = 3.141592653589793; area = PI*r*r; circumference = 2*PI*r;}
اسلاید 65: برنامۀ آزمون تابع فوق و يک اجراي آزمايشي آن در شکل زير نشان داده شده است:void ComputerCircle(double&, double&, double);// returns the area and circumference of a circle with radius r;int main(){ // tests the ComputeCircle() function: double r, a, c; cout << Enter radius: ; cin >> r; ComputeCircle(a, c, r); cout << area = << a << , circumference = << c << endl;}
اسلاید 66: 12- ارسال از طريق ارجاع ثابتارسال پارامترها به طريق ارجاع دو خاصيت مهم دارد: اول اين که تابع ميتواند روي آرگومان واقعي تغييراتي بدهد دوم اين که از اشغال بيمورد حافظه جلوگيري ميشود. روش ديگري نيز براي ارسال آرگومان وجود دارد: ارسال از طريق ارجاع ثابت. اين روش مانند ارسال از طريق ارجاع است با اين فرق که تابع نميتواند محتويات پارامتر ارجاع را دستکاري نمايد و فقط اجازۀ خواندن آن را دارد. براي اين که پارامتري را از نوع ارجاع ثابت اعلان کنيم بايد عبارت const را به ابتداي اعلان آن اضافه نماييم.
اسلاید 67: مثال 15-5 ارسال از طريق ارجاع ثابتسه طريقه ارسال پارامتر در تابع زير به کار رفته است:void f(int x, int& y, const int& z){ x += z; y += z; cout << x = << x << , y = << y << , z = << z << endl;}در تابع فوق اولين پارامتر يعني x از طريق مقدار ارسال ميشود، دومين پارامتر يعني y از طريق ارجاع و سومين پارامتر نيز از طريق ارجاع ثابت.
اسلاید 68: برنامۀ آزمون و يک اجراي آزمايشي از مثال قبل:void f(int, int&, const int&);int main(){ // tests the f() function: int a = 22, b = 33, c = 44; cout << a = << a << , b = << b << , c = << c << endl; f(a,b,c); cout << a = << a << , b = << b << , c = << c << endl; f(2*a-3,b,c); cout << a = << a << , b = << b << , c = << c << endl;}a = 22, b = 33, c = 44x = 66, y = 77, z = 44a = 22, b = 77, c = 44x = 85, y = 121, z = 44a = 22, b = 121, c = 44تابع فوق پارامترهاي x و y را ميتواند تغيير دهد ولي قادر نيست پارامتر z را تغيير دهد. تغييراتي که روي x صورت ميگيرد اثري روي آرگومان a نخواهد داشت زيرا a از طريق مقدار به تابع ارسال شده. تغييراتي که روي y صورت ميگيرد روي آرگومان b هم تاثير ميگذارد زيرا b از طريق ارجاع به تابع فرستاده شده.
اسلاید 69: ارسال به طريق ارجاع ثابت بيشتر براي توابعي استفاده ميشود که عناصر بزرگ را ويرايش ميکنند مثل آرايهها يا نمونۀ کلاسها که در جلسههاي بعدي توضيح آنها آمده است. عناصري که از انواع اصلي هستند (مثل int يا float) به طريق مقدار ارسال ميشوند به شرطي که قرار نباشد تابع محتويات آنها را دستکاري کند.
اسلاید 70: 13- توابع بيواسطهتابعي که به شکل بيواسطه تعريف ميشود، ظاهري شبيه به توابع معمولي دارد با اين فرق که عبارت inline در اعلان و تعريف آن قيد شده است.مثال 16-5 تابع cube() به شکل بيواسطهاين همان تابع cube() مثال 3-5 است:inline int cube(int x){ // returns cube of x: return x*x*x;}تنها تفاوت اين است كه كلمۀ كليدي inline در ابتداي عنوان تابع ذکر شده. اين عبارت به كامپايلر ميگويد كه در برنامه به جاي cube(n) کد واقعي (n)*(n)*(n) را قرار دهد.
اسلاید 71: . به برنامۀ آزمون زير نگاه کنيد:int main(){ // tests the cube() function: cout << cube(4) << endl; int x, y; cin >> x; y = cube(2*x-3);}اين برنامه هنگام کامپايل به شکل زير درميآيد، گويي اصلا تابعي وجود نداشته:int main(){ // tests the cube() function: cout << (4) * (4) * (4) << endl; int x, y; cin >> x; y = (2*x-3) * (2*x-3) * (2*x-3);}وقتي كامپايلر کد واقعي تابع را جايگزين فراخواني آن ميکند، ميگوييم که تابع بيواسطه، باز ميشود.احتياط: استفاده از توابع بيواسطه ميتواند اثرات منفي داشته باشد. مثلا اگر يک تابع بيواسطه داراي 40 خط کد باشد و اين تابع در 26 نقطه مختلف از برنامۀ اصلي فراخواني شود، هنگام کامپايل بيش از هزار خط کد به برنامۀ اصلي افزوده ميشود. همچنين تابع بيواسطه ميتواند قابليت انتقال برنامۀ شما را روي سيستمهاي مختلف کاهش دهد.
اسلاید 72: 14- چندشکلي توابعدر C++ ميتوانيم چند تابع داشته باشيم که همگي يک نام دارند. در اين حالت ميگوييم که تابع مذکور، چندشکلي دارد. شرط اين کار آن است که فهرست پارامترهاي اين توابع با يکديگر تفاوت داشته باشد. يعني تعداد پارامترها متفاوت باشد يا دست کم يکي از پارامترهاي متناظر هم نوع نباشند.
اسلاید 73: مثال 17-5 چندشکلي تابع max()در مثال 3-5 تابع max() را تعريف کرديم. حالا توابع ديگري با همان نام ولي شکلي متفاوت تعريف ميکنيم و همه را در يک برنامه به کار ميگيريم:int max(int, int);int max(int, int, int);int max(double, double);int main(){ cout << max(99,77) << << max(55,66,33) << << max(44.4,88.8);}
اسلاید 74: int max(int x, int y){ // returns the maximum of the two given integers: return (x > y ? x : y);}int max(int x, int y, int z){ // returns the maximum of the three given integers: int m = (x > y ? x : y); // m = max(x , y) return ( z > m ? z : m);}int max(double x, double y){ // return the maximum of the two given doubles: return (x>y ? x : y);}
اسلاید 75: در اين برنامه سه تابع با نام max() تعريف شده است. وقتي تابع max() در جايي از برنامه فراخواني ميشود، کامپايلر فهرست آرگومان آن را بررسي ميکند تا بفهمد که کدام نسخه از max بايد احضار شود. مثلا در اولين فراخواني تابع max() دو آرگومان int ارسال شده، پس نسخهاي که دو پارامتر int در فهرست پارامترهايش دارد فراخواني ميشود. اگر اين نسخه وجود نداشته باشد، کامپايلر intها را به double ارتقا ميدهد و سپس نسخهاي که دو پارامتر double دارد را فرا ميخواند.
اسلاید 76: 14- تابع main() برنامههايي که تا کنون نوشتيم همه داراي تابعي به نام main() هستند. منطق C++ اين طور است که هر برنامه بايد داراي تابعي به نام main() باشد. در حقيقت هر برنامه کامل، از يک تابع main() به همراه توابع ديگر تشکيل شده است که هر يک از اين توابع به شکل مستقيم يا غير مستقيم از درون تابع main() فراخواني ميشوند.
اسلاید 77: خود برنامه با فراخواني تابع main() شروع ميشود. چون اين تابع يک نوع بازگشتي int دارد، منطقي است که بلوک تابع main() شامل دستور return 0; باشد هرچند که در برخي از کامپايلرهاي C++ اين خط اجباري نيست و ميتوان آن را ذکر نکرد.مقدار صحيحي که با دستور return به سيستم عامل برميگردد بايد تعداد خطاها را شمارش کند. مقدار پيشفرض آن 0 است به اين معنا که برنامه بدون خطا پايان گرفته است. با استفاده از دستور return ميتوانيم برنامه را به طور غيرمعمول خاتمه دهيم.
اسلاید 78: مثال 18-5 استفاده از دستور return براي پايان دادن به يك برنامهint main(){ // prints the quotient of two input integers: int n, d; cout << Enter two integers: ; cin >> n >> d; if (d = = 0) return 0; cout << n << / << d << = << n/d << endl;}Enter two integers: 99 1799/17 = 5 دستور return تابع فعلي را خاتمه ميدهد و کنترل را به فراخواننده بازميگرداند. به همين دليل است که اجراي دستور return در تابع main() کل برنامه را خاتمه ميدهد.
اسلاید 79: چهار روش وجود دارد که بتوانيم برنامه را به شکل غيرمعمول (يعني قبل از اين که اجرا به پايان بلوک اصلي برسد) خاتمه دهيم:1 - استفاده از دستور return 2 - فراخواني تابع exit()3 - فراخواني تابع abort()4 – ايجاد يک حالت استثنا اين تابع در سرفايل <cstdlib> تعريف شده است. تابع exit() براي خاتمه دادن به کل برنامه در هر تابعي غير از تابع main() مفيد است.
اسلاید 80: مثال 19-5 استفاده از تابع exit() براي پايان دادن به برنامه#include <cstdlib> // defines the exit() function#include <iostream> // defines thi cin and cout objectsusing namespace std;double reciprocal(double x);int main(){ double x; cin >> x; cout << reciprocal(x);}double reciprocal(double x)1 – Exception{ // returns the reciprocal of x: if (x = = 0) exit(1); // terminate the program return 1.0/x; }دراين برنامۀ اگر كاربر عدد 0 را وارد کند، تابع reciprocal() خاتمه مييابد و برنامه بدون هيچ مقدار چاپي به پايان ميرسد
اسلاید 81: 15- آرگومانهاي پيشفرضدر C++ ميتوان تعداد آرگومانهاي يک تابع را در زمان اجرا به دلخواه تغيير داد. اين امر با استفاده از آرگومانهاي اختياري و مقادير پيشفرض امکانپذير است.براي اين که به يک پارامتر مقدار پيشفرض بدهيم بايد آن مقدار را در فهرست پارامترهاي تابع و جلوي پارامتر مربوطه به همراه علامت مساوي درج کنيم. به اين ترتيب اگر هنگام فراخواني تابع، آن آرگومان را ذکر نکنيم، مقدار پيشفرض آن در محاسبات تابع استفاده ميشود. به همين خاطر به اين گونه آرگومانها، آرگومان اختياري ميگويند.
اسلاید 82: double p(double, double, double=0, double=0, double=0);int main(){ // tests the p() function: double x = 2.0003; cout << p(x,7) = << p(x,7) << endl; cout << p(x,7,6) = << p(x,7,6) << endl; cout << p(x,7,6,5) = << p(x,7,6,5) << endl; cout << p(x,7,6,5,4) = << p(x,7,6,5,4) << endl;}double p(double x, double a0, double a1=0, double a2=0, double a3=0){ // returns a0 + a1*x + a2*x^2 + a3*x^3: return a0 + (a1 + (a2 + a3*x)*x)*x;} مثال 20-5 آرگومانهاي پيشفرضبرنامۀ زير حاصل چند جملهاي درجه سوم را پيدا ميکند. براي محاسبۀ اين مقدار از الگوريتم هورنر استفاده شده. به اين شکل که براي کارايي بيشتر، محاسبه به صورت دستهبندي ميشود: p(x,7) = 7p(x,7,6) = 19.0018p(x,7,6,5) = 39.00781 – Defaultp(x,7,6,5,4) = 71.0222
اسلاید 83: دقت کنيد که پارامترهايي که مقدار پيشفرض دارند بايد در فهرست پارامترهاي تابع بعد از همۀ پارامترهاي اجباري قيد شوند مثل:void f( int a, int b, int c=4, int d=7, int e=3); // OKvoid g(int a, int b=2, int c=4, int d, int e=3); // ERRORهمچنين هنگام فراخواني تابع، آرگومانهاي ذکر شده به ترتيب از چپ به راست تخصيص مييابند و پارامترهاي بعدي با مقدار پيشفرض پر ميشوند. مثلا در تابع p() که در بالا قيد شد، فراخواني p(8.0,7,6) باعث ميشود که پارامتر x مقدار 8.0 را بگيرد سپس پارامتر a0 مقدار 7 را بگيرد و سپس پارامتر a1 مقدار 6 را بگيرد. پارامترهاي a2 و a3 مقدار پيشفرضشان را خواهند داشت. اين ترتيب را نميتوانيم به هم بزنيم. مثلا نميتوانيم تابع را طوري فرا بخوانيم که پارامترهاي x و a0 و a3 مستقيما مقدار بگيرند ولي پارامترهاي a1 و a2 مقدار پيشفرضشان را داشته باشند.
اسلاید 84: پايان جلسه پنجم
خرید پاورپوینت توسط کلیه کارتهای شتاب امکانپذیر است و بلافاصله پس از خرید، لینک دانلود پاورپوینت در اختیار شما قرار خواهد گرفت.
در صورت عدم رضایت سفارش برگشت و وجه به حساب شما برگشت داده خواهد شد.
در صورت نیاز با شماره 09353405883 در واتساپ، ایتا و روبیکا تماس بگیرید.
- پاورپوینتهای مشابه
نقد و بررسی ها
هیچ نظری برای این پاورپوینت نوشته نشده است.