آموزش ساختارها- بخش دوم { ارسال ساختارها به تابع }
مقدمه
با سلام خدمت همه شما دوستان. در این جلسه قصد داریم درباره روش های ارسال یک ساختار به یک تابع صحبت کنیم. برای فهم بهتر این مطلب ، پیشنهاد میکنم ابتدا جلسه مربوط به آموزش ساختارها که در لینک زیر آورده شده است رو بخونید:
ارسال یک متغیر ساده به توابع
اجازه بدید قبل از این که وارد بحث اصلی بشیم ، نحوه ارسال یک متغییر ساده به یک تابع رو با هم دیگه بررسی کنیم.
برای ارسال یک متغیر به یک تابع میتونیم از دو روش استفاده میشه :
- روش By value
- روش By reference
اجازه دهید برای توضیح این دو روش از یک مثال استفاده کنید. ابتدا تابع زیر را در نظر بگیرید:
void swap(int a, int b); void swap(int a, int b) { int tmp = a; a = b; b = tmp; } int main() { int a = 1; int b = 2; printf("before swap a = %d\n", a); printf("before swap b = %d\n", b); swap(a, b); printf("after swap a = %d\n", a); printf("after swap b = %d\n", b); }
انتظاری که ما از این تابع داریم این است که دو مقدار را بیگیرد و جای این دو مقدار را با یکدیگر عوض می کند و سپس آن را در خروجی نمایش می دهد. حالا ببینیم آیا واقعا این کار را برای ما انجام میدهد یا خیر. شکل زیر خروجی این کد را نمایش میدهد:
همانطور که مشاهده میکنید ، دو عدد بدون آن که در آنها جا به جایی اتفاق بیفتد ، در خروجی چاپ شده اند. اما علت چیست؟ علت این موضوع این است که یک کپی از متغیرهای a و b به تابع swap ارسال شده است و نه خود متغیرها. به همین دلیل هم هست که پس از جا به جا شدن مقدار آنها در تابع swap ، در تابع main ، همان مقادیر قبلی چاپ شده اند. این روش ارسال ، همان روش By value است.
حالا اجازه بدید از روش By reference استفاده کنیم. ابتدا کد زیر را در نظر بگیرید:
void swap(int *a, int *b); void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } int main() { int a = 1; int b = 2; printf("before swap a = %d\n", a); printf("before swap b = %d\n", b); swap(&a, &b); printf("after swap a = %d\n", a); printf("after swap b = %d\n", b); }
خروجی این کد مطابق شکل زیر می باشد:
همانطور که میبینید ، جای مقادیر دو متغیر a و b جا به جا شده است. علت این موضوع این است که ما آدرس این دو متغیر را ارسال کرده ایم. برای ارسال آدرس هم تنها کافی است ، آرگومان های تابع مورد نظر ( در اینجا swap ) را اشاره گر تعریف کنید و سپس هنگام فراخوانی تابع به جای a و b ، عبارت های a& و b& رو ارسال کنید.
ارسال ساختارها به توابع
پاس دادن ساختارها به تابع هم دقیقا مشابه با پاس دادن یک متغیر به تابع هست. اگه با روش By value ساختار مورد نظر پاس داده بشه ، همه تغییراتی که روی ساختار انجام میشه درون همون تابع میمونه و تاثیری رو مقادیر ساختار اصلی ندارند. در واقع ، در این حالت یک کپی از ساختار مورد نظر تهیه میشه و اون تابع ارسال میشه و بدیهی هم هست که هر گونه تغییراتی روی کپی ساختار ، بر روی ساختار اصلی تاثیری نخواهد داشت.در مثال زیر این موضوع رو مقداری دقیق تر بررسی کردیم:
struct foo { int width; int height; }; void swap(struct foo input); void swap(struct foo input) { int tmp = input.width; input.width = input.height; input.height = tmp; } int main() { struct foo first; first.width = 1; first.height = 2; printf("before swap first.width = %d\n", first.width); printf("before swap first.height = %d\n", first.height); swap(first); printf("after swap first.width = %d\n", first.width); printf("after swap first.height = %d\n", first.height); }
توضیح خطوط کد:
در خطوط 1 الی 4 یک ساختار با نام foo ، تعریف کردیم که دارای دو پارامتر با نام های width و height از نوع int هستند.
در خط 6 ، یک کپی از نام تابع و آرگومان ورودی اون تعریف میشه. همونطور که میدونید ، برای تعریف یک تابع ، در ابتدای برنامه باید یک کپی از اون رو بنویسید.
در خطوط 8 الی 12 ، تابع swap ، تعریف شده که وظیفه این تابع این هست که مقدار پارامترهای width و height رو جا به جا کنه.
در خط 16 یک عنصر از ساختار foo با نام first ، تعریف شده.
در خط 17 , 18 ، پارامترهای width و height از ساختار first ، مقدار دهی شده اند.
در خطوط 19 و 20 ، مقادیر پارامترهای width و height چاپ شده اند.
در خط 21 ، تابع swap ، فراخوانی شده . در این خط عنصر first ، از روش By value فراخوانی شده.
در خطوط 22 و 23 هم دوباره مقادیر width و height ، مقدار دهی شده اند تا ببینیم که آیا تابع swap ، تغییری در مقادیر آنها ایجاد میکند یا خیر.
پس از کامپایل و اجرای این کد ، خروجی به صورت زیر می باشد:
همونطور که مشاهده میکنید ، ساختار اصلی بدون تغییر باقی مونده و در واقع بر روی یک کپی از ساختار اصلی ، تغییرات انجام شده.
حالا اجازه بدید با استفاده از روش By reference هم یک ساختار رو فراخوانی کنیم تا ببینیم آیا تغییری روی ساختار اصلی اتفاق میفته یا خیر. ابتدا کد زیر رو در نظر بگیرید:
struct foo { int width; int height; }; void swap(struct foo *input); void swap(struct foo *input) { int tmp = input->width; input->width = input->height; input->height = tmp; } int main() { struct foo first; first.width = 1; first.height = 2; printf("before swap first.width = %d\n", first.width); printf("before swap first.height = %d\n", first.height); swap(&first); printf("after swap first.width = %d\n", first.width); printf("after swap first.height = %d\n", first.height); }
توضیح این کد ، دقیقا مشابه کد قبلی است ، با این تفاوت که در اینجا از اشاره گرها استفاده شده است. استفاده از اشاره گرها در واقع همان استفاده از روش By reference است.
برای استفاده از روش By reference همانطور که میبینید ، در خط 6 کد ، هنگام تعریف تابع ، آرگومان ورودی آن به صورت اشاره گر تعریف شده است و همچنین ، هنگام فراخوانی تابع swap ، از علامت “&” استفاده شده است.
پس از کامپایل و اجرا این کد در خروجی خواهیم داشت:
همانطور که مشاهده میکنید ، بر روی ساختار تغییرات اعمال شده است و مقادیر width و height جایشان عوض شده است. در واقع در این روش ، خود ساختار اصلی به تابع مورد نظر ارسال می شود و تغییرات بر روی خود آن صورت میگیرد.
خوب دوستان. این جلسه هم به پایان رسید. مثل همیشه میتونید ما رو در تلگرام و یا اینستاگرام دنبال کنید.
دیدگاهتان را بنویسید