همانطور که در فصل ۱ گفتیم، حلقههای while و for شرط پایان را در ابتدای حلقه بررسی میکنند.
در مقابل، حلقهی سوم در C یعنی do-while شرط را در انتهای حلقه بررسی میکند؛ یعنی بعد از اینکه بدنهی حلقه یکبار اجرا شد.
به همین دلیل، بدنهی حلقهی do-while حداقل یک بار اجرا میشود.
ساختار دستور do به شکل زیر است:
do
statement
while (expression);
در این حالت، ابتدا statement اجرا میشود، سپس عبارت (expression) ارزیابی میگردد.
اگر مقدارش درست (غیرصفر) باشد، دوباره statement اجرا میشود و این روند ادامه دارد.
وقتی عبارت نادرست (صفر) شود، حلقه تمام میشود.
بهجز تفاوت در محل بررسی شرط، do-while تقریباً معادل دستور repeat-until در زبان پاسکال است.
تجربه نشان داده که do-while کمتر از while و for استفاده میشود.
با این حال، گاهی بسیار مفید است؛ مثلاً در تابع زیر به نام itoa که عددی را به رشتهای از کاراکترها تبدیل میکند (برعکس تابع atoi).
کار این تابع کمی پیچیدهتر از چیزی است که در نگاه اول به نظر میرسد، چون روشهای سادهی ساخت ارقام، آنها را به ترتیب معکوس تولید میکنند.
در اینجا رشته را از آخر به اول تولید میکنیم و در پایان آن را معکوس میکنیم:
/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) /* ثبت علامت عدد */
n = -n; /* عدد را مثبت کن */
i = 0;
do { /* تولید رقمها از انتها به ابتدا */
s[i++] = n % 10 + '0'; /* دریافت رقم بعدی */
} while ((n /= 10) > 0); /* حذف آن رقم */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
در اینجا استفاده از do-while ضروری (یا دستکم بسیار مناسب) است، چون حتی اگر n برابر صفر باشد، حداقل یک رقم باید در آرایهی s قرار گیرد.
همچنین اطراف بدنهی do-while از {} استفاده کردهایم — حتی اگر فقط یک دستور وجود دارد — تا خوانندهی عجول while را با ابتدای یک حلقهی دیگر اشتباه نگیرد.
تمرین 4-3:
در نمایش اعداد به روش مکمل دو (two’s complement)، نسخهی ما از itoa بزرگترین عدد منفی را (یعنی مقداری برابر با -(2^(wordsize-1))) درست نمایش نمیدهد.
توضیح دهید چرا، و تابع را طوری تغییر دهید که این مقدار را نیز صرفنظر از نوع ماشین، به درستی چاپ کند.
تمرین 5-3:
تابعی بنویسید به نام itob(n, s, b) که عدد صحیح n را در مبنای b به رشتهای از کاراکترها در s تبدیل کند.
برای مثال، itob(n, s, 16) باید مقدار عدد را به شکل هگزادسیمال در s ذخیره کند.
تمرین 6-3:
نسخهای از itoa بنویسید که بهجای دو آرگومان، سه آرگومان بگیرد.
آرگومان سوم حداقل عرض فیلد است؛ یعنی عدد باید در صورت نیاز با فاصله (space) از سمت چپ پر شود تا به آن عرض برسد.