در زبان C، یک دستور یا Statement کوچکترین واحد مستقلی است که به کامپیوتر فرمان میدهد تا کاری مشخص را انجام دهد. بدنه هر تابع در C از مجموعهای از دستورات تشکیل شده است که بهصورت ترتیبی (از بالا به پایین) اجرا میشوند، مگر آنکه دستورات کنترلی مسیر اجرا را تغییر دهند .
یک نکته کلیدی برای درک ساختار C این است که دستورات (Statements) با عبارات (Expressions) تفاوت دارند :
عبارت یک محاسبه را مشخص میکند و یک مقدار تولید میکند. مثلاً 3 + 4 یک عبارت است که مقدار 7 را برمیگرداند.
دستور یک عمل را انجام میدهد و معمولاً وضعیت حافظه را تغییر میدهد یا خروجی تولید میکند، هرچند ممکن است خودش مقدار مشخصی را برنگرداند .
با این حال، مرز بین عبارت و دستور در C گاهی مبهم است. C به عباراتی اجازه میدهد که عوارض جانبی (Side Effects) داشته باشند؛ یعنی علاوه بر محاسبه یک مقدار، وضعیت برنامه را نیز تغییر دهند. همچنین C دارای عبارات شرطی (مثل عملگر سهگانه ?:) است که در برخی زبانهای دیگر فقط بهصورت دستور وجود دارند .
زبان C دستورات را به پنج دسته اصلی طبقهبندی میکند :
دستورات مرکب (Compound Statements)
دستورات عبارتی (Expression Statements)
دستورات انتخابی (Selection Statements)
دستورات تکرار (Iteration Statements)
دستورات پرش (Jump Statements)
سادهترین نوع دستور، یک عبارت است که با سمیکالن (;) خاتمه یابد. پرکاربردترین دستورات در برنامههای C از این نوع هستند، مانند انتساب مقدار یا فراخوانی تابع .
#include <stdio.h> int main() { int x, y; // این یک دستور نیست؛ یک اعلان (Declaration) است. x = 5; // یک دستور عبارتی: عبارت انتساب y = x + 10; // یک دستور عبارتی: عبارت انتساب printf("y = %d\n", y); // یک دستور عبارتی: فراخوانی تابع ++x; // یک دستور عبارتی: عملگر افزایش return 0; // دستور پرش (Jump Statement) }
در مثال بالا، x = 5;، printf(...); و ++x; همگی دستورات عبارتی هستند. اجرای آنها باعث ارزیابی عبارت و اعمال عوارض جانبی آن (مانند تغییر مقدار متغیر یا چاپ روی صفحه) میشود .
یک دستور خالی، فقط یک سمیکالن تنها است (;) و هیچ کاری انجام نمیدهد. کاربرد اصلی آن در جاهایی است که دستور مورد نیاز است، اما ما نمیخواهیم کاری انجام شود . یک مورد استفادهی رایج، در حلقههای for یا while است که بدنهٔ خالی دارند:
char *s = "Hello"; while (*s++ != '\0') ; // دستور خالی: حلقه صرفاً تا رسیدن به انتهای رشته پیش میرود
نکته حرفهای: استفاده از دستور خالی در کنار
ifمیتواند منجر به اشتباه شود. بهعنوان مثال،if (x < 10);یک دستور خالی را به شرط x<10 متصل میکند و عملاً شرط هیچ اثری ندارد که معمولاً یک خطای برنامهنویسی است .
یک دستور مرکب یا بلوک (Block)، گروهی از صفر یا چند دستور (و اعلانها تا پیش از C23) است که درون آکولاد ({ }) قرار گرفتهاند . از دیدگاه نحو (Syntax) زبان، یک بلوک معادل یک دستور واحد محسوب میشود و میتوان آن را در هر جایی که زبان انتظار یک دستور دارد، استفاده کرد .
if (x > 0) { // شروع بلوک int result = x * 2; printf("Result is %d\n", result); // پایان بلوک } // بلوک بهعنوان یک دستور برای if عمل میکند
هر بلوک، حوزهٔ دید (Scope) جدیدی را معرفی میکند. متغیرهایی که داخل یک بلوک تعریف میشوند، تنها در همان بلوک و بلوکهای تو در توی آن قابل دسترس هستند .
نکته امنیتی و حرفهای: استفاده از آکولاد برای بدنهٔ دستورات شرطی و حلقهها، حتی اگر بدنه فقط یک دستور باشد، یک روش بسیار توصیهشده است. این کار از بروز خطاهای ناشی از اضافه شدن دستورات جدید به بدنه در آینده جلوگیری میکند و خوانایی کد را افزایش میدهد .
این دستورات به برنامه اجازه میدهند تا بر اساس مقدار یک عبارت، یکی از چندین مسیر اجرایی را انتخاب کند .
ifدستور if در دو شکل اصلی به کار میرود :
بدون else: اگر شرط برقرار بود (مقدار شرط غیرصفر بود)، دستور (یا بلوک) اجرا میشود.
if (score >= 60) { printf("Passed!\n"); }
با else: اگر شرط برقرار بود، دستور اول؛ در غیر اینصورت، دستور دوم اجرا میشود.
if (score >= 60) { printf("Passed!\n"); } else { printf("Failed.\n"); }
نکته بسیار مهم: شرط در C، هر مقدار عددی است. صفر به معنی نادرست (False) و هر مقدار غیرصفر به معنی درست (True) است .
if-else if-elseبرای انتخاب بین بیش از دو حالت، میتوان دستورات if-else را بهصورت زنجیرهای نوشت :
int grade = 85; if (grade >= 90) { printf("A\n"); } else if (grade >= 80) { printf("B\n"); } else if (grade >= 70) { printf("C\n"); } else { printf("F\n"); }
else آویزان (Dangling else)یکی از مباحث کلاسیک در C، تطابق else با if است. قاعده این است که else به نزدیکترین if بدون else قبلی تعلق دارد .
if (x > 0) if (y > 0) printf("x and y are positive.\n"); else // این else به if (y > 0) تعلق دارد، نه به if (x > 0) printf("x is positive but y is not.\n");
برای جلوگیری از سردرگمی و بهبود خوانایی، همیشه از آکولاد برای مشخص کردن محدودهٔ if و else استفاده کنید.
switchدستور switch راهی برای انتخاب بین چندین حالت گسسته (معمولاً صحیح یا کاراکتری) بر اساس مقدار یک عبارت صحیح است .
int day = 3; switch (day) { case 1: printf("Saturday\n"); break; case 2: printf("Sunday\n"); break; case 3: printf("Monday\n"); break; default: printf("Invalid day\n"); break; }
رفتار مهم switch: پس از تطبیق یک case، اجرا به ترتیب به caseهای بعدی نیز سرایت میکند (Fall-through) مگر آنکه با دستور break از آن خارج شویم. به همین دلیل، استفاده از break در انتهای هر case یک رویهٔ استاندارد است .
این دستورات برای اجرای مکرر یک بلوک از کد استفاده میشوند .
whileشرط را قبل از هر بار اجرا بررسی میکند. اگر شرط در ابتدا نادرست باشد، بدنه هرگز اجرا نمیشود .
int i = 0; while (i < 5) { printf("%d ", i); i++; } // خروجی: 0 1 2 3 4
do-whileبدنه را یک بار اجرا کرده و سپس شرط را بررسی میکند. بنابراین، بدنه حداقل یک بار اجرا میشود .
int i = 10; do { printf("%d ", i); i++; } while (i < 5); // خروجی: 10 (با وجود نادرست بودن شرط، یک بار اجرا شد)
forحلقهی for یک ساختار قدرتمند و انعطافپذیر است که از سه بخش اختیاری تشکیل شده است :
for ( init_clause ; cond_expression ; iteration_expression ) statement
ترتیب اجرا به این صورت است :
init_clause: یک بار در ابتدا اجرا میشود (میتواند یک اعلان متغیر یا یک عبارت باشد).
cond_expression: قبل از هر بار اجرای بدنه، بررسی میشود. اگر نادرست (صفر) بود، حلقه پایان مییابد.
statement: بدنه حلقه اجرا میشود.
iteration_expression: پس از اجرای بدنه، اجرا میشود و سپس به مرحله ۲ برمیگردد.
// چاپ اعداد 0 تا 4 for (int i = 0; i < 5; i++) { printf("%d ", i); } // خروجی: 0 1 2 3 4 // متغیر i در خارج از حلقه قابل دسترس نیست (به دلیل اعلان داخل init_clause)
نکته پیشرفته: تمام بخشهای
forاختیاری هستند.for (;;)یک حلقهٔ بینهایت ایجاد میکند که معادلwhile (1)است . همچنین میتوان با استفاده از عملگر کاما (,) عبارات متعددی را در بخشهایinitوiterationنوشت:for (i=0, j=10; i<j; i++, j--).
این دستورات باعث میشوند که جریان اجرا بهطور غیرشرطی به نقطهٔ دیگری از برنامه منتقل شود .
breakبرای خروج فوری از حلقه (while, do-while, for) یا دستور switch استفاده میشود. اجرا از اولین دستور بعد از حلقه یا switch ادامه مییابد .
for (int i = 0; i < 10; i++) { if (i == 5) { break; // وقتی i=5 شد، حلقه را ترک کن } printf("%d ", i); } // خروجی: 0 1 2 3 4
continueدر داخل حلقهها، اجرای بقیهٔ بدنه را برای تکرار فعلی نادیده گرفته و به تکرار بعدی میپرد (یعنی به مرحلهی ارزیابی شرط در while و do-while یا بخش iteration در for میرود) .
for (int i = 0; i < 5; i++) { if (i == 2) { continue; // عدد 2 چاپ نمیشود } printf("%d ", i); } // خروجی: 0 1 3 4
returnاجرای تابع کنونی را پایان داده و کنترل را به تابع فراخواننده برمیگرداند. اگر تابع مقداری را برگرداند، آن مقدار باید پس از return ذکر شود. در توابع با نوع خروجی void، میتوان از return; بدون مقدار استفاده کرد .
int find_first_positive(int arr[], int size) { for (int i = 0; i < size; i++) { if (arr[i] > 0) { return arr[i]; // با پیدا شدن اولین عدد مثبت، تابع را ترک کن } } return -1; // اگر هیچ عدد مثبتی پیدا نشد }
دستور return در تابع main باعث پایان یافتن اجرای کل برنامه میشود .
gotoاین دستور باعث میشود اجرا به یک برچسب (Label) مشخص در همان تابع منتقل شود. استفاده از goto بهشدت در برنامهنویسی مدرن C توصیه نمیشود و اغلب نشانهی طراحی ضعیف است .
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: منبع مستندات