4.4 حلقه while اساسی ترین حلقه در زبان c حلقه while است.دستور while کاری شبیه تکرار دستور if را انجام می دهد. اگر شرط دستور صحیح باشد دستورات انجام می شوند با این تفاوت که پس از اجرای دستورات شرط مجددا بررسی می شود تا در صورتیکه هنوز صحیح باشد دستورات بار دیگر انجام شوند. و این حلقه تا زمانی تکرار می شود که شرط مقدار غلط پیدا کند. در صورتیکه در همان مرتبه اول بررسی شرط مقدار ناصحیح داشته باشد دستورات به هیچ وجه اجرا نمی گردند. به عبارت دیگر درصورتیکه شرط هرگز مقدار غلط پیدا نکند حلقه به طور بی نهایت تکرار می شود. برای کنترل تعداد دفعاتی که یک حلقه کدهایش را اجرا می کند شما حداقل یک متغییر در جمله شرط دارید که در بلوک کد متعاقب تغییر می یابد. این موضوع به جمله شرط امکان می دهد در برخی مراحل نادرست گردد. نمونهی را که پیش رو دارید یک بازی ساده حدس زدن عدد است:
نمونه 4.5 guess_my_number.c
کد:
#include
int
main()
{
const int MAGIC_NUMBER = 6;
int guessed_number;
printf("Try to guess what number I'm thinking of\n");
printf("HINT: It's a number between 1 and 10\n");
printf("enter your guess: ");
scanf("%d", &guessed_number);
while (guessed_number != MAGIC_NUMBER);
{
printf("enter your guess: ");
scanf("%d", &guessed_number);
}
printf("you win.\n")
return 0;
}
بلوک کد حلقه while در نمونه بالا تا زمانی که بازیکن عدد 6 را حدس بزند مرتب تکرار می شود. 4.5 حلقه for معمولا در مواردیکه تعداد دفعات تکرار حلقه از قبل معیین است از حلقه for استفاده می کنیم. در ساختار حلقه for متغییری وجود دارد که تعداد دفعات تکرار حلقه را تعیین می کند و اصطلاحا شمارنده نامیده می شود. در پرانتز بعد از کلمه for سه عبارت وجود دارند که توسط سمی کالون (;) از یکدیگر جدا شده اند. اولین عبارت مقدار اولیه متغییر شمارنده را مشخص می کند. آخرین عبارت معیین می کند که با هر بار اجرای دستورات حلقه مقدار متغییر شمارنده به چه میزان اضافه یا کم می شود و بالاخره عبارت وسط که شرط حلقه است مشخص می کند حلقه تا چه زمانی باید اجرا شود.
فرم کلی حلقه if به صورت زیر است:
کد:
for (initialization; expression; action )
{
statement1;
statement2;
statement3;
}
در نمونه زیر متغییر i متغییر شمارنده حلقه for می باشد:
نمونه 4.6 for_ten.c
کد:
#include
int
main()
{
int i;
/* display the numbers from 0 to 9 */
for (i = 0; i < 10; i++)
printf("%d\n", i);
return 0;
}
4.6 حلقه do… while حلقه do … while شبیه حلقه while عمل می کند با این تفاوت که شرط حلقه به جای ابتدا در انتهای حلقه بررسی می شود. پس حتی اگر شرط حلقه مقدار نادرست داشته باشد دستورات حلقه حداقل یک بار اجرا می شوند. در ذیل نمونهی از کاربرد این حلقه آمده است:
نمونه 4.7 guess_my_number.c
کد:
#include
int
main()
{
const int MAGIC_NUMBER = 6;
int guessed_number;
printf("Try to guess what number I'm thinking of\n");
printf("HINT: It's a number between 1 and 10\n");
do
{
printf("enter your guess: ");
scanf("%d", &guessed_number);
}
while (guessed_number != MAGIC_NUMBER);
printf("you win.\n")
return 0;
}
4.7 عملگر شرطی عملگر ?: شبیه دستور if … else عمل می کند با این تفاوت که چون یک عملگر است ( و نه یک دستور )در میان عبارتها نیز کار برد دارد.
نمونه 4.8 apples.c
کد:
#include
int
main()
{
apples = 6;
printf("I have %d apple%s ", apples, (apples == 1) ? "" : "s");
return 0;
}
?: تنها عملگر سه گانه در زبان c است.در نمونه بالا عبارت (apples == 1) شرط ماست که درستی آن بررسی می شود. در صورتی که شرط صحیح باشد ( که در نمونه بالا نیست ) در خروجی کلمه apple بدون s و در صورت اشتباه بودن شرط کلمه apple همراه با s چاپ خواهد شد. 4.9 break و continue زبان c راه بسیار سادهای برای خارج شدن از حلقههای تکرار در مواقع لزوم فراهم میکند. برای این کار باید از دستور break که پیش از این به منظور بیرون جهیدن از ساختار switch از آن بهره برده بودیم استفاده کرد. نمونه زیر اعداد یک تا 12 را چاپ می کند:
نمونه 4.9 break.c #include int main() { for (i = 1; i <= 20; i++) { if (i == 12) { break; } printf ( “%d “ ,i); } return 0; } به کار بردن دستور continue در یک حلقه تکرار باعث می شود تا دستورات بعدی نادیده گرفته شده و مفسر به ابتدای حلقه باز گردد. نمونه زیر حاصل تقسیم عدد بیست را بر اعداد محدوده منفی ده تا مثبت ده چاپ می کند اما برای جلوگیری از تقسیم شدن عدد بیست بر عدد صفر از یک شرط و دستور continue استفاده شده است.
نمونه 4.10 continue.c
کد:
#include
int
main()
{
for (i = -10; i <= 10; i++)
{
if (i == 0)
{
continue;
}
printf ("%d", 20/i);
}
return 0;
}
فصل پنجم : اشاره گرها
5.1 اصول اولیه محدودیتی که ممکن است شما نیز متوجه آن شده باشید این است که توابع تنها از طریق مقادیر بازگشتی خود در برنامه شما تاثیر گذراند. با این وصف اگر بخواهید تا یک تابع با بیش از یک متغییر سر و کار داشته باشد چه خواهید کرد؟ پاسخ استفاده از اشاره گرهاست.
یک اشاره گر نوع خاصی از متغییرهاست که برای نگهداری آدرسهای حافظه کاربرد دارد یعنی یک اشاره گر آدرس متغییر دیگری را به عنوان مقدار خود نگهداری میکند. اعلان اشاره گرها به مانند اعلان متغییرهای عادی است با این تفاوت که شما باید یک کاراکتر ستاره “*” را به ابتدای نام اشاره گر اضافه کنید. دو عملگر جدید برای کار با اشاره گرها وجود دارد که شما باید آنها را بشناسید:عملگر & و عملگر * که هر دو جزء عملگرهای یگانی پیشوندی محسوب می شوند . زمانی که شما یک علامت آمپرسند "&" را در آغاز نام یک متغییر اضافه می کنید شما آدرس آن متغییر را دریافت خواهید کرد که می تواند در یک اشاره گر نگهداری شود. اما زمانیکه علامت ستاره را در آغاز نام یک اشاره گر به کار می برید شما مقدار نگهداری شده در آدرس حافظهای را که اشاره گر به آن اشاره می کند دریافت خواهید کرد. مثل همیشه بحث را با یک نمونه دنبال می کنیم :
نمونه 5.1 pointers_are_simple.c
کد:
#include
int
main()
{
int my_variable = 6, other_variable = 10;
int *my_pointer;
printf("the address of my_variable is : %p\n", &my_variable);
printf("the address of other_variable is : %p\n", &other_variable);
my_pointer = &my_variable;
printf("\nafter \"my_pointer = &my_variable\":\n");
printf("\tthe value of my_pointer is %p\n", my_pointer);
printf("\tthe value at that address is %d\n", *my_pointer);
my_pointer = &other_variable;
printf("\nafter \"my_pointer = &other_variable\":\n");
printf("\tthe value of my_pointer is %p\n", my_pointer);
printf("\tthe value at that address is %d\n", *my_pointer);
return 0;
}
خروجی برنامه آدرس حافظه دو متغییر را به شما نشان می دهد. مقادیر در رایانه من با رایانه شما متفاوت خواهند بود. در تابع ()printf همانطور که شما هم متوجه شدهاید از %p برای نمایش آدرسها بهره بردیم که شاخص تبدیل برای تمام اشاره گرهاست. به هر حال خروجی برنامه در رایانه من به صورت زیر بود :
خروجی برنامه
کد:
the address of my_variable is : 0xbffffa18
the address of other_variable is : 0xbffffa14
after "my_pointer = &my_variable":
the value of my_pointer is 0xbffffa18
the value at that address is 6
after "my_pointer = &other_variable":
the value of my_pointer is 0xbffffa14
the value at that address is 10
5.2 آدرس یک متغییر برنامهها در زمان اجرا ، وقتی به اعلان یک متغییر می رسند از سیستم عامل درخواست تخصیص مقداری حافظه برای آن متغییر را می نمایند. سیتم عامل قطعهای از حافظه را که اندازه آن برای نگهداری مقادیر متغییر مناسب است انتخاب و آدرس آن را به برنامه اعلام میکند. هر زمان که برنامه قصد خواندن دادههایی را که درون آن متغییر نگهداری می شوند داشته باشد ، به آدرس حافظه آن متغییر مراجعه کرده و به برابر با اندازه آن متغییر بایتهای حافظه را می خواند. در صورتی که شما یک بار دیگر برنامهای را که در اغاز این فصل ذکر کردیم اجرا کنید ممکن است نتایج مشابه یا متفاوتی را نسبت به بار اول در مورد آدرسهای حافظه بدست آورید کهاین امر بستگی به شرایط سیستم شما دارد اما حتی اگر در بار دوم نتایج یکسانی را نسبت به یار اول بدست آورید هیچ تضمینی برای اینکه اجرای برنامه در فردا نیز همین نتایج را داشته باشد وجود نخواهد داشت. در واقع این احتمال که فردا نیز برنامه همین نتایج را داشته باشد تقریبا محال است.