• پایان فعالیت بخشهای انجمن: امکان ایجاد موضوع یا نوشته جدید برای عموم کاربران غیرفعال شده است

آموزش C++ سي پلاس پلاس از پايه

programmer

کاربر تازه وارد
تاریخ عضویت
1 نوامبر 2005
نوشته‌ها
85
لایک‌ها
0
return در یک تابع در واقع مشخص میکنه که باید از تابع خارج بشیم.

یعنی انتهای یک تابع رو مشخص میکنه ! جایی که تابع به کار خود پایان داده و نتیجه را برمیگرداند !

کد:
#include<iostream.h>
int Max(int a,int b){
[COLOR="Red"]if(a>b)[/COLOR]
return 1;
[COLOR="red"]else if(b>a)[/COLOR]
return -1;
[COLOR="red"]else[/COLOR]
return 0;
}
int main (){
int a,b;
cin>>a>>b;
cout<<Max(a,b);
return 0;
}

در هر بار اجرای تابع فقط یکی از return ها کار میکنه !

به خطوط قرمز که شرط هایی رو مشخص میکنن دقت کنید ! در هر بار اجرای تابع فقط یکی از این شروط درست

هستند و return اون شرط اجرا میشه.بعدش هم از تابع خارج میشه و کنترل اجرا اصلآ به بقیه return ها نمیرسه.


کد:
#include<iostream.h>
int calculate(int a,int b){
int Mul,Sum,Div;
Mul=a*b;
[COLOR="Red"]return Mul;[/COLOR]
Sum=a+b;
return Sum;
Div=a/b;
return Div;
}
int main (){
int a,b;
cin>>a>>b;
cout<<calculate(a,b);
return 0;
}

در مورد برنامه بالا وقتی خط قرمز رنگ اجرا میشه تابع به کار خودش پایان میده. و دستورهای بعد از اون خط اصلآ اجرا نمیشن.

در واقع اگر دستور return کلیه خطوطی که بعد از return قرار دارند اجرا نمیشوند !!!

در برنامه اول شما فقط یک خروجی داشتین که بنا به حالات مختلف تغییر میکرد ولی در برنامه دوم شما سه خروجی دارید.

بهتره به بحث توابعی که چند خروجی دارند مراجعه کنید.اونجا در این مورد بحث کردیم.(صفحه 13 پستهای 189 به بعد)
 

programmer

کاربر تازه وارد
تاریخ عضویت
1 نوامبر 2005
نوشته‌ها
85
لایک‌ها
0
سوال دیگه هم مربوط به return کردن یک ارایه است.مثلا تابعی که یه ماتریس بگیره و عناصر روی قطر اصلی رو توی یک ارایه ذ خیره کنه و اون ارایه رو return کنه ؟

ارسال آرایه به یک تابع بطور خودکار از طریق ارجاع میباشد.

یعنی شما یک آرایه رو به تابع ارسال میکنید و روی اون تغییرات رو اعمال میکنید ، همین !!!

تابع احتیاجی به خروجی نداره !

اگه نامفهوم بود بگید تا بیشتر بحث کنیم.
 

لیلی

کاربر تازه وارد
تاریخ عضویت
7 نوامبر 2005
نوشته‌ها
15
لایک‌ها
0
سن
38
محل سکونت
Esf
return ها رد کاملا متوجه شدم.ممنون.
در مورد ارایه ها من توی صورت 2 تا سوال اشکال دارم.
1)برنامه ای که تابعی را پیاده سازی کند که ماتریس 10*10 را دریافت کرده عناصر قطر اصلی ان را در ارایه خطی ذخیره کرده و ان ارایه را برگرداند.
2)برنامه ای که تابعی را پیاده سازی کرده که ماتریس 10*10 را دریافت کرده و ترانهاده ان را در برنامه اصلی چاپ کند.
اگه درست فهمیده باشم.در سوال اول باید نوع تابع int ودر فراخوانی تابع باید از cout استفاده کنیم.ولی در سوال دوم نوع تابع باید void باشد و در فراخوانی cout لازم نیست.درسته؟
کلا من تو فراخوانی ارایه خیلی مشکل دارم.
مثلا وقتی در prototype می نویسیم.
کد:
void modifyelement(int []);

کد:
void modifyelement(const int [])

اینها با هم چه فرقی می کنه؟وفراخوانیشون به چه صورتیه؟
یا مثلا اگه بخوایم یه مسئله رو این طوری حل کنیم که یه تابع 2 تا عدد بگیره و جمع و ضرب. تفریق و....حساب کنه و جواب ها رو توی یک ارایه بریزه و بعد اون ارایه رو برگردونه به برنامه اصلی.در این صورت حتما باید ارایه return بشه؟درسته؟
لطفا اگه میشه برام توضیح بدید.
 

programmer

کاربر تازه وارد
تاریخ عضویت
1 نوامبر 2005
نوشته‌ها
85
لایک‌ها
0
برنامه ای که تابعی را پیاده سازی کند که ماتریس 10*10 را دریافت کرده عناصر قطر اصلی ان را در ارایه خطی ذخیره کرده و ان ارایه را برگرداند

مقدار max رو به 10 تغییر بدهید تا برای ماتریس 10 در 10 کار کند.

تابع آرایه یک بعدی را که حاوی عناصر روی قطر اصلی است را برمیگرداند.

به خطوط سبز رنگ بیشتر دقت کنید.

کد:
#include<iostream.h>
#include<conio.h>
const max=3;
int* func(int x[][max],int z[])
{
 for(int i=0;i<max;i++)
  z[i]=x[i][i];
 return z;
}
// Main \\
int main()
{
 int a[max][max];
 int b[max];
 [COLOR="Green"]int *q;[/COLOR]
 int i,j;
 clrscr();
 for(i=0;i<max;i++)
 {
  for(j=0;j<max;j++)
  {
   cout<<"Enter a["<<i<<","<<j<<"] = ";
   cin>>a[i][j];
  }
 }
[COLOR="green"] q = func(a,b);[/COLOR]
 for(j=0;j<max;j++)
   cout<<q[j]<<endl;
 getch();
 return 0;
}
 

programmer

کاربر تازه وارد
تاریخ عضویت
1 نوامبر 2005
نوشته‌ها
85
لایک‌ها
0
برنامه ای که تابعی را پیاده سازی کرده که ماتریس 10*10 را دریافت کرده و ترانهاده ان را در برنامه اصلی چاپ کند.

به این برنامه توجه کنید :


کد:
#include<iostream.h>
#include<conio.h>

const max=3;
void complement(int x[][max])
{
 int z[max][max];
 int i,j;
 for(i=0;i<max;i++)
  for(j=0;j<max;j++)
    z[i][j]=x[j][i];
 for(i=0;i<max;i++)
 {
  for(j=0;j<max;j++)
    cout<<z[i][j]<<"  ";
  cout<<endl;
 }
 return;
}

int main()
{
 int a[max][max];
 clrscr();
 for(int i=0;i<max;i++)
  for(int j=0;j<max;j++)
  {
    cout<<"Enter > ";
    cin>>a[i][j];
  }
 for(int ii=0;ii<max;ii++)
 {
  for(int jj=0;jj<max;jj++)
   cout<<a[ii][jj]<<"  ";
  cout<<endl;
 }
 cout<<"^^^^^^^^^^^^^^^^^^^^^"<<endl;
 complement(a);
 getch();
 return 0;
}
 

programmer

کاربر تازه وارد
تاریخ عضویت
1 نوامبر 2005
نوشته‌ها
85
لایک‌ها
0
ا
گه درست فهمیده باشم.در سوال اول باید نوع تابع int ودر فراخوانی تابع باید از cout استفاده کنیم.ولی در سوال دوم نوع تابع باید void باشد و در فراخوانی cout لازم نیست.درسته؟

در مثال اول نوع خروجی تابع * int هست. یعنی اشاره گری به یک integer .

حتمآ میدونید که آرایه هم با مفهوم اشاره گر پیاده سازی شده.در واقع نام آرایه اشاره گری به اولین عنصر آرایه است.

arr.JPG


پس هر کاری با یک آرایه میشه انجام داد با اشاره گر هم میشه.

من هم خروجی تابع را داخل یک اشاره گر قرار دادم. وقتی خروجی تابع در متغیر q ریخته میشه در واقع q به خانه اول

آرایه اشاره میکند.در اصل آرایه در q قرار میگیرد.

در ضمن یک آرایه را نمیشه با دستور cout در خروجی نوشت !

حدس بزنید اگه این کار رو بکنید چی چاپ میشه ؟

درسته آدرس اولین خونه آرایه !!!
 

programmer

کاربر تازه وارد
تاریخ عضویت
1 نوامبر 2005
نوشته‌ها
85
لایک‌ها
0
کلا من تو فراخوانی ارایه خیلی مشکل دارم.
مثلا وقتی در prototype می نویسیم.
کد:
void modifyelement(int []);
کد:
void modifyelement(const int [])
اینها با هم چه فرقی می کنه؟وفراخوانیشون به چه صورتیه؟

کار با آرایه ها و اشاره گرها دقت خیلی زیادی میخواد. اما مطمئن باشید با تمرین براتون آسون میشه.

در تابع دوم const نشون میده که آرایه ای که به تابع فرستاده میشه باید ثابت بمونه و در تابع نباید اون رو تغییر بدیم.

اگه بخواهیم دقیق تر بگیم عناصر آرایه نباید تغییر کنند.

فراخوانی این دو هیچ تفاوتی با هم نداره . فقط نام یک آرایه رو داخا پرانتزها قرار میدیم و لازم نیست const و یا چیز دیگه ای بنویسیم.
 

لیلی

کاربر تازه وارد
تاریخ عضویت
7 نوامبر 2005
نوشته‌ها
15
لایک‌ها
0
سن
38
محل سکونت
Esf
ممنون.توضیحاتتون خیلی خوب بود.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
با تشکر از دو دوست گرامی که این بحث مفید و سطح بالا را برگذار کردند.
ولی خوانندگان استرس به خود راه ندهند چون انواع فراخوانی را با هم تمرین خواهیم کرد.
من کمی روند آموزش را کند کرده ام چون فصل امتحانات است ولی بحث ادامه خواهد داشت.
.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
من برای جا افتادن قضیه فراخوانی تابع به روش ارجاع مثال ساده زیر را میاورم.
تابع تاریخ و ساعت کارش خیلی ساده است.
و در زیر ورودی و خروجی آن را می بینید.
از هل÷ توربو سی

197a1.gif




197a2.gif


برنامه بالا
برای این آورده شده که ببینید که اصلا از خروجی تابع استفاده نشده.
و ورودی چون از نوع اشاره گر بوده روی خود آن اعمال شده.
دوستان اگر اشتباه برداشت کردم بگید.
کلا نوع
char
یک نوع آرایه است و آرایه خودش نوعی اشاره گر است.
برنامه بالا بسیار ساده است و کمک می کند تا مفهوم اشاره گر و صدا کردن با ارجاع مشخص شود.

برنامه بالا را به شکل کد زیر درآوردم و اجرا کردم.

کد:
#include <conio.h>		
#include <iostream.h>				
#include <time.h>

void main()						
{		
clrscr();char c ;
 menu:
 // ----------- shoroe ghaaleb -------------
   
      char dateStr [9];
      char timeStr [9];
     _strdate( dateStr);
              //  printf( "The current date is %s \n", dateStr);
     _strtime( timeStr );
              // printf( "The current time is %s \n", timeStr);
    
cout<<"dateStr= "<<dateStr<<endl;
cout<<"timeStr= "<<timeStr<<endl;

 // ----------- entehaye ghaaleb -----------
    cout<<"----------------------new run"<<endl;
	c=getch();if(c != 'q') goto menu;
}


197a3.gif


جناب
Programmer
آیا می شود این طرز استفاده در اینجا را نوعی تابع بی
Return
دانست؟

از
http://www.codersource.net/codersource_cppprogramming.html

من هر چی سرچ کردم هیچ جا از این تابع خروجی نگرفته کسی. و همه به روش بالا با عمل بر روی ورودی تاریخ را دریافت کرده اند.
.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها

در مورد تابع بالا این سئوال برای من پیش آمده که چرا کامپایلر وقتی خروجی اش را تحویل نمی گیریم و در یک متغیر نمی ریزیم چرا خطا نمی گیره.
آیا میشه بگیم چون خروجی اش از نوع اشاره گره - با علامت ستاره مشخص کرده _ پس کامپایلر نیازی نمی بینه که خروجی اش را تحویل بگیریم.
و این اشاره گر به کجا اشاره می کنه؟ یعنی خروجی اش را کجا میریزه؟ آیا روی همان ورودی اش میریزه.
یعنی آیا ورودی و خروجی این تابع یک جای حافظه قرار داره؟
.
 

saeedsmk

مدیر بازنشسته
تاریخ عضویت
6 سپتامبر 2003
نوشته‌ها
1,518
لایک‌ها
4
نه خروجيشو رو ورديش نميريزه تو يه حافظه ميريزه كه بعد از برگشت از تابع اون رو پاك ميكنه ( يعني دوبارعه استفاده ميكنه )
ما اصولا دو نوع صدا زدن تابع داريم
يكي با برگشت متغيير با مشخص كردن اسم متغير در سمت راست اسم تابع
و ديگري بدون برگشت متغيير هر چند كه تابع متغيري برگرداند.
حالت اول كه معلوم است .اما حالت دوم در حالت اسمبلي چون برگشت دهنده تابع معمولا در مقدار eax ذخيره ميشود اگر ما بخواهيم ار اين برگشت دهنده استفاده ميكنم وگرنه مثل دستور getch() بدون هيچ ورودي و خروجي فقط عمل گرفتن رو خواستار مي شيم . به كد زير نگاه كن
کد:
#include <iostream.h>
#include <conio.h>
   char *ShowChar(char *a)
	{
		int b;
		char *z;
		b=*a+1;
		*a=b;
		return(z);
	}

void main(){
	clrscr();
	char a;
	a=110;
	ShowChar(&a);
	cout<<a;
	getch();
	return;
}
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
ممنون از لطفت.
كاملا فهميدم. زحمت كشيديد.
.
اين هم يك مثال كه داشتم كار مي كردم.
کد:
#include <conio.h>
#include <iostream.h>

void main()
{
clrscr();char c ;
 menu:
 // ----------- shoroe ghaaleb -------------
 

char buffer[83];
   char *p;

   buffer[0] = 6;

  cout<<"Input some chars"<<endl;
   p = cgets(buffer);
  cout<<endl;

cout<<"p="<<p<<endl;
cout<<"buffer="<<buffer<<endl;


 // ----------- entehaye ghaaleb -----------
    cout<<"----------------------new run"<<endl;
c=getch();if(c != 'q') goto menu;
}

200a1.gif

شرح توربو سي راجع به اين تابع

کد:
Reads string from console

 Declaration:  char *cgets(char *str);

 Remarks:
cgets reads a string of characters from the console and stores the string
(and the string length) in the location *str.

Before you call cgets, set str[0] to the maximum length of the string to be
read.

cgets reads characters until it encounters a carriage-return/linefeed
combination (CR/LF), or until the maximum allowable number of characters
have been read.

If cgets reads a CR/LF, it replaces the CR/LF with a \0 (null terminator)
before storing the string.

On return, str[1] is set to the number of characters actually read.

The characters read start at str[2] and end with a null terminator, so str
must be at least (str[0] + 2) bytes long.

 Return Value:
  ‏ On success, returns a pointer to str[2].

طرز كار اين تابع بسيار جالبه. در خانه اول به تابع مي گيم كه چند كاراكتر به كاربر اجازه تايپ بدهد.
در خانه دوم ، تابع تعداد كاراكتري كه كاربر وارد كرده ثبت ميشه.
خروجي اصلي يعني p فرق داره با خود buffer .
اين طوري كه p همان چيزي خواهد بود كه كاربر وارد كرده ولي در buffer دو خانه اضافه داريم علاوه بر چيزي كه كاربر وارد كرده. كه خانه اول همان تعداد مجاز است كه كاربر مي تواند وارد كند و خانه دوم تعداد كاراكتري را نشان مي دهد كه كاربر وارد كرده .
و از خانه سوم ، آنچه كاربر وارد كرده به نمايش درمياد.
تابع مفيدي است. ولي اگر مي خواهيد با آن ساده كار كنيد ، بهتره كه از p استفاده كنيد نه buffer تا به پيچيدگي نيافتيد. ولي شايد به دلايلي استفاده از buffer در جاهايي ارجح باشه. مثلا برنامه نويس بخواهد با توابع رشته اي كار كند و بخواهد در اول آرايه تعداد كاراكتر را هم داشته باشد و از اين چيزها كه من كار نكردم و به ذهنم نمي رسد.
.

200a2.gif

.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
از فرمايشات آقا سعيد و تمرينات خودم كه در پست قبلي نوشتم ، كلا من به اين نتيجه تاسف بار رسيدم كه در سي ، هر تابع رفتارش خاص است و نميشه دسته بندي كنيم به انواع و يادگيري اش را براي خود ساده كنيم.
البته اين نتيجه گيري من است و ممكنه غلط باشه.
فعلا تنها راهي مي ماند اينه كه با ديدن سورسها ، بفهميم كه از هر تابع چطور ميشه استفاده كرد. و كم كم براي خودمان در ذهنمان قوائدي بسازيم.
.
اهل فن اگر لطف كنند از تجربيات خود در اين زمينه بگويند ، كمك بزرگي كرده اند.
.
 

saeedsmk

مدیر بازنشسته
تاریخ عضویت
6 سپتامبر 2003
نوشته‌ها
1,518
لایک‌ها
4
ببين شايد بد توضيح دادم يه فانكشن هميشه خروجي داره ولي به ساب خروجي نداره
ما ميتونيم توابع رو طوري تعريف كنيم كه خروجي داشته باشن و هميشه بايد در حالت اي استفاده بشن كه خروجي ميخوان يعني خروجي رو از نوع ثابت تعريف كنيم .
اما يه راه حلي وجود داره كه بشه از توابع بصورت چندين منظوره استفاده نمود يعني اينكه كاري كرد كه اگه خروجي تابع مصرف نشد اشكالي نداشته باشد و در واقع تابع به يه سابروتين تغيير پيدا كند . و اگر ما خواستيم از اين تابع به عنوان يه انجام دهنده چندين دستور استفاده كنيم . و اگر هم خواستيم مثل يك تابع از ان استفاده كنيم . اين خيلي راحته نميدونم با كجاش مشكل داري . يه قاعده كلي اينه
تابع خروجي داره . مگر اينكه شما ان را چند منظوره تعريف نموده باشيد.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
من كلا منظورم اين بود كه نميشه در همه توابع انتظار داشت كه خروجي اشان را با يك طريق برگردانند.
و گفتم كه بايد براي هر تابع بايد صاحب تجربه شد. تا بفهميم چطور با آن كار كنيم. يعني نميشه با كار با يك تابع به تعداد بيشمار تابع مسلط شد. البته اين قانون من فكر كنم نه صفر درصده نه 100 درصد، يعني خيلي از توابع به هم شبيه هستند. و ممكنه جاهايي هم با هم فرق كنه رفتارشان.
كلا من از صحبتهاي شما در پست قبلي اتان ، به اين نتيجه رسيدم كه بهتره گاهي به فكر استفاده از توابع باشيم و به خروجي اشان كاري نداشته باشيم.
من فقط براي كنجكاوي خودم ، مي خواهم سر از كار توابع دربيارم. ولي فكر كنم ضرورتي نداشته باشه اين كار.

راجع به پست اخير شما ، قسمت آخر ، :
بله مي توان از تابع بعنوان زيربرنامه استفاده كرد كه چند خط برنامه را در خود نگه دارد. يا به شكل تابع استفاده كرد.

در حقيقت ميشه گفت كه تابع هايي كه ما مي سازيم ، به نوعي همه زيربرنامه اند. چون واقعا كاري علاوه بر تركيب چند دستور انجام نمي دهند. و در آخر هم هرچي دلمان خواست بازمي گردانيم. البته شايد من بخاطر تجربه كم خود دارم اشتباه مي گم.

ولي راجع به تابع هاي خود سي (نه آنها كه ما مي سازيم) وضع فرق مي كنه. بايد به رفتار آنها مسلط شد تا بهترين استفاده را از آنها كرد. البته اين جمله را با شما نبودم. منظورم روال آموزش است.
بهر صورت ما محتاج رهنمودهاي شما هستيم.
.
====================
كلا من قصدم از اين بحث ها اينه كه قبل از اين كه برويم به سراغ توابع مختلف سي ، مثل توابع گرافيكي ، رياضي ، رشته اي ، ، يك دورنمايي از رفتار((توابع سي)) داشته باشيم.

و مي خواهم ديدگاههاي مختلف به طور مقدماتي بحث بشه تا بعدا فشار كمتري احساس بشه.

در كل ، ((سي)) ، بدون توابع اش چيز زيادي در اختار ما نمي گذارد. حدود 10 تا 15 كلمه كليدي سي محيط باز و راحتي براي كار فراهم نمي كنه و استفاده از توابع حاضر و آماده سي – كه خيلي هم قوي هستند – تقريبا اجتناب ناپذيره.

البته يك نفر مي تواند بگويد : ((من از هيچ تابعي استفاده نمي كنم الا اين كه خودم آن را نوشته باشم.)) ولي اين جوري او مجبور است زحمت زيادي بكشد و كاملا به ساختار سيستم مسلط باشد. به نظر من كسي كه اين قدر به ساختار سيستم مسلط باشد ، به راحتي مي تواند از توابع آماده سي استفاده كند و حتي لذت بيشتري از استفاده از اين توابع هم خواهد برد. زيرا به ((زيبايي كاركرد و ساختار)) آنها پي خواهد برد.
 

saeedsmk

مدیر بازنشسته
تاریخ عضویت
6 سپتامبر 2003
نوشته‌ها
1,518
لایک‌ها
4
من نميخوام بحث كنم ولي چند نكته به نظرم رسيد گفتم بگم
اول قصد شما در جهت اموزش و داشتن يه دور نما بسيار عاقلانه و مورد پسند است .
و اما نكاتي كه به نظرم رسيد.
ببينيد زير برنامه يا ساب روتين تكه كدي است كه كاري را به انجام مينمايدكه خروجي ندارد
اما تابع يا فانكشن تكه كدي است كه پس از انجام عمليات برنامه خروجي به برنامه برميگداند.
پس با اين تعريف ما هميشه هم از توابع هم از ساب روتين استفاده ميكنيم .
شناخت توابع سي در كل امكان پذير است و كمك بالايي به برنامه نويس ميكند و استفاده بجا از يك تابع يا ساب روتين جلوي هزينه هاي بعدي( وقت برنامه نويس - زمان صرف شده توسط كاربر و ...) را ميگيرد.
اگه يه نگاهي به تاريخچه سي بندازيد مي بنيد كه بيشتر توابع اون توسط برنامه نويساني چون شما تهيه شده است پس الكي خودتون رو دست كم نگيريد. چرا توابع ما با توابع نوشته شده در برنامه فرق ميكنه ؟ تابع ، تابع است چون خروجي دارد .هميشه توابع براي بهبود نوشتاري و كاهش هزينه طراحي ميشن وگرنه استفاده از آنها بدون مزيت و كار بيهوده اي است اينطور نيست ؟
در هر صورت بعلت زحماتي كه براي اين بخش ميكشيد از شما تشكر ميكنم اميدوارم هميشه بر همين منوال موضوع اموزش را ادامه دهيد.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
يك قسمتهايي را شما مي گيد كه من چون دورم ازش اصلا نمي پرسم.
مثل فرق تابع و ساب روتين.
لطفا اين گونه قسمتها را خودتان شرح بدهيد. يا حداقل تاكيد كنيد تا من آشنا بشم تا بتونم برم دنبالش و بگم.
يك چيزي هم بود در پستهاي اخير شما كه من نفهميدم. يك برنامه اي كه خروجي نگيريم هم مشكل ايجاد نمي كنه. اگر ميشه آن را هم شرح بدهيد.
.
 

programmer

کاربر تازه وارد
تاریخ عضویت
1 نوامبر 2005
نوشته‌ها
85
لایک‌ها
0
سلام ، ببخشید که وسط بحث شما میام

فرق تابع و ساب روتين.

اگه پاسکال کار کرده باشید میدونید که از function و procedure برای نوشتن توابع و زیر برنامه ها استفاده میکنیم.
فرق بین تابع و پروسجر تقریبآ همین موضوع رو روشن میکنه !

ببینید ، کدی که برای تابع مینویسیم یک سری اعمال رو روی داده ها انجام میده و نتیجه ای رو بعنوان خروجی برمیگردونه .

در توابع بیشتر اون نتیجه (خروجی) مد نظر ماست نه اون کاری که تابع میکنه.یعنی صرف نظر از نحوه عمل تابع فقط خروجی برای ما مهمه.

اما در زیر برنامه (ساب روتین / روال) ما خروجی نداریم وفقط به خاطر صرفه جویی در کد و زمان یک تکه برنامه رو بعنوان زیر برنامه تعریف میکنیم و از نام اون استفاده میکنیم. در این مورد کاری که این زیر برنامه انجام میدهد برای ما مهم است.

به مثالهای ساده زیر توجه کنید :

کد:
#include<iostream.h>
#include<conio.h>

int function_power(int x,int y)
{
 int sum=1;
 for(int i=1;i<=y;i++)
  sum=sum*x;
 return sum;
}

int main()
{
  int b ,p ;
  clrscr();
  cout<<"This program compute  x^y ."<<endl;
  cout<<"Enter x :";
  cin>>b;
  cout<<"Enter y :";
  cin>>p;
  cout<<"X^Y = "<<function_power(b,p)<<endl;
  cout<<"press any key to exit...";
  getch();
  return 0;
}

در مثال بالا تابع function_power برای محاسبه x^y (ایکس به توان ایگرگ) بکار میرود.برای ما خروجی تابع مهم است و نه نحوه عمل تابع ! تابع هر طور که پیاده سازی شده باشد اگر درست عمل کند ،خروجی درستی به ما میدهد و برنامه ما هم درست کار میکند.

کد:
#include<iostream.h>
#include<conio.h>
const Max=10;
void procedure_line()
{
 for(int i=0;i<70;i++)
 {
  cout<<"_";
  if(i == 34)
    cout<<endl;
 }
 cout<<endl<<endl;
}

int main()
{
  clrscr();
  int x;
  float sum=0;
  for(int i=0;i<Max;i++)
  {
    cout<<"Enter an integer:";
    cin>>x;
    sum=sum+x;
    procedure_line();
  }
  procedure_line();
  cout<<"Average= "<<sum/Max<<endl;
  procedure_line();
  cout<<"\nPress any key to exit...";
  getch();
  return 0;
}
اما در مورد مثال بالا (10 عدد را از کابر میگیرد و میانگین آنها را محاسبه میکند): زیر برنامه procedure_line برای چاپ یک خط بکار میرود. در برنامه اصلی چندین بار از این زیربرنامه استفاده شده. ما می توانستیم به جای اینکه این زیر روال را تعریف کنیم در آن قسمتها کد داخل این زیر روال رو قرار بدیم.اما به خاطر صرفه جویی در وقت و کد برنامه از زیر روال استفاده میکنیم.

نمیدونم تونستم فرق بین زیر روال با تابع رو بگم یا نه !!!
 

programmer

کاربر تازه وارد
تاریخ عضویت
1 نوامبر 2005
نوشته‌ها
85
لایک‌ها
0
يك برنامه اي كه خروجي نگيريم هم مشكل ايجاد نمي كنه.

کامپایلر به این مورد حساس نیست و خطا نمیگیره. یعنی اگر شما یک تابع داشته باشید که خروجی تولید میکنه اما در برنامه از خروجی اون استفاده نکنید،مشکلی پیش نمی آید.حالا خروجی از هر نوعی میخواد باشه.

در واقع با این کار (تحویل نگرفتن خروجی تابع) از تابع به صورت ساب روتین (زیر برنامه) استفاده کرده اید.
بهترین مثال برای این کار ،تابع getch هست که دوستمون جناب saeedsmk گفتند.

این تابع (getch) منتظر فشرده شدن یک کلید می ماند و سپس کاراکتری را که کلید فشرده شده مشخص میکند برمیگرداند.
اما در برنامه های بالا میبینید که در آخر برنامه برای خروج از برنامه استفاده شده.یعنی خروجی تابع برای ما مهم نیست بلکه فقط میخواهیم منتظر بمانیم تا کاربر با فشردن کلید به برنامه خاتمه دهد.

به همین ترتیب گاهی ما از توابع استفاده میکنیم اما خروجی آنها برای ما مهم نیست بلکه کاری که انجام میدهند مورد نظر ماست.

در مورد تابع strdate_ : ببینید چون متغیر به صورت اشاره گر استفاده میشود،در واقع میشد این تابع به صورت بدون return نوشته شود .(بحث توابع با بیش از یک خروجی رو که خروجی ها در لیست پارامترها بودند را به خاطر بیاورید)
در این مورد هم پارامتر ارسالی به تابع همان خروجی است،اما برای تاکید بر این که این یک تابع است، خروجی با استفاده از return هم برای آن در نظر گرفته شده است.
اگر از خود پارامتر ارسالی به تابع استفاده کنیم (از return تابع استفاده نکنیم) به اندازه یک اشاره گر کاراکتری در برنامه صرفه جویی شده !!!!!
 
بالا