دستورهای زیر:
if (a > b)
z = a;
else
z = b;
مقدار بزرگتر بین a و b رو داخل z قرار میدن.
عبارت شرطی (Conditional Expression) که با عملگر سهتایی ?: نوشته میشه، یه روش دیگه برای نوشتن همین منطق و ساختارهای مشابهه.
در عبارت:
expr1 ? expr2 : expr3
اول expr1 ارزیابی میشه.
اگه مقدارش ناصفر (یعنی درست) باشه، اون وقت expr2 اجرا میشه و مقدارش همون نتیجهی کل عبارت خواهد بود.
در غیر این صورت، expr3 اجرا میشه و مقدار اون برمیگرده.
فقط یکی از expr2 یا expr3 اجرا میشه.
مثلاً برای اینکه مقدار بزرگتر بین a و b داخل z قرار بگیره، میتونیم بنویسیم:
z = (a > b) ? a : b; /* z = max(a, b) */
نکتهی مهم اینه که عبارت شرطی خودش یه عبارت کامله — یعنی میتونه هر جایی که یه عبارت عادی استفاده میکنی، به کار بره.
اگه expr2 و expr3 از نوعهای متفاوت باشن، نوع نهایی طبق قوانین تبدیل نوع (type conversion) که قبلاً توی این فصل گفتیم، تعیین میشه.
برای مثال، اگه f یه float و n یه int باشه، آنگاه:
(n > 0) ? f : n
از نوع float هست، مهم نیست مقدار n مثبت باشه یا نه.
پرانتز دور عبارت اول لازم نیست، چون اولویت (precedence) عملگر ?: پایینتر از بیشتر عملگرهاست، فقط کمی بالاتر از عملگر انتساب (=).
با این حال، گذاشتن پرانتز معمولاً کار خوبیه چون شرط رو واضحتر نشون میده و خوندن کد رو راحتتر میکنه.
عبارت شرطی معمولاً باعث میشه کد کوتاهتر و تمیزتر نوشته بشه.
مثلاً این حلقه، n تا از اعضای آرایه رو چاپ میکنه، در هر خط ۱۰ تا، با یه فاصله بین هر ستون، و در انتهای هر خط (حتی خط آخر) یه خط جدید (newline) میذاره:
for (i = 0; i < n; i++)
printf("%6d%c", a[i], (i%10==9 || i==n-1) ? '\n' : ' ');
اینجا بعد از هر دهمین عنصر و بعد از آخرین عنصر (n-اُمین) یه خط جدید چاپ میشه.
بقیهی عناصر با یه فاصله از هم جدا میشن.
در نگاه اول ممکنه کمی پیچیده به نظر برسه، ولی در واقع خیلی کوتاهتر و تمیزتر از حالت معادلش با if-else هست.
یه مثال خوب دیگه هم اینه:
printf("You have %d items%s.\n", n, n==1 ? "" : "s");
که باعث میشه وقتی فقط یه آیتم داری، کلمهی “items” بهصورت مفرد چاپ بشه (بدون s).
تمرین ۱۰-۲:
تابع lower رو که حروف بزرگ رو به حروف کوچک تبدیل میکنه، با استفاده از عبارت شرطی (?:) به جای if-else بازنویسی کن.