[英]If statement inside while loop with the same condition
通過消除C中if
語句中的重復條件,是否有更好的方式編寫以下代碼?
while (n < 0) {
printf("Enter a positive integer: ");
scanf("%d", &n);
if (n < 0) {
printf("Error: please enter a positive integer\n");
}
}
謝謝。
只要給出正確的輸入,只需對回路中斷進行重新處理。 這樣,檢查僅執行一次:
while (1)
{
printf("Enter a positive integer: ");
scanf("%d", &n);
if (n >= 0)
break;
printf("Error: please enter a positive integer\n");
}
並且,如注釋中所述,優化的編譯器應該能夠自行反轉循環。
提出以下示例是出於人們應該了解該語言可用內容的精神。 1 Frankie_C的答案顯示了我通常編寫代碼的方式 。 正如某些人指出的那樣,優化通常會使這種簡單情況不值得擔心,但問題並不局限於簡單的評估,如n < 0
; 該測試可能是對較復雜的標准進行一些昂貴評估的函數調用。
人們不會喜歡這樣,但是:
goto middle;
do
{
printf("Error, please enter a positive integer\n");
middle:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n < 0);
如果您強烈反對goto
,則可以使用精簡版的Duff設備 :
switch (0)
do
{
printf("Error, please enter a positive integer\n");
case 0:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n < 0);
但是你不應該。
1通常,軟件工程師將不得不使用其他人編寫的代碼,因此他們必須准備好識別和理解該語言可表達的任何內容,即使這只是將其重寫為更好的代碼的第一步。 有時會出現出於商業或其他實際原因而需要“丑陋”代碼的情況。
這是通過一些重構可以最好地完成的:
#include <stdio.h>
#include <stdbool.h>
static bool get_postive_integer(int *pOut) {
int n;
printf("Enter a positive integer: ");
scanf("%d", &n);
if(n < 0)
return false;
*pOut = n;
return true;
}
int main(void)
{
int n;
while (!get_postive_integer(&n)) {
printf("Error: please enter a positive integer\n");
}
}
給操作起一個名字 ,檢查它是否失敗,然后才相應地打印一條消息。 在指定的操作中,成功或失敗條件僅在此處編碼一次。
您可以使用:
while (printf("Enter a positive integer: ") > 0 &&
scanf("%d", &n) == 1 &&
n < 0)
{
printf("Error: please enter a positive integer\n");
}
如果printf()
失敗, scanf()
失敗或n
值為非負值,則此操作將停止。 始終檢查scanf()
成功是個好主意。 printf()
返回它寫入的字符數(或在失敗時返回負數printf()
只是方便的,因此它也可以在某種情況下使用。 您也可以將fflush(stdout) == 0 &&
到操作堆棧中。
或者,您可以決定條件中的代碼應該在函數中:
static int read_positive_integer(void)
{
int value;
if (printf("Enter a positive integer: ") > 0 &&
fflush(stdout) == 0 &&
scanf("%d", &value) == 1 &&
value >= 0)
return value;
return -1;
}
然后調用代碼是:
while ((n = read_positive_integer()) < 0)
printf("Error: please enter a positive integer\n");
主題有很多變體。 您可以將while
循環包裝到一個函數中; 您可以將提示變成函數的參數。 您可能決定更謹慎地報告問題所在( printf()
失敗時采取不同的操作,而scanf()
返回0(輸入中為非數字數據)或EOF(輸入中沒有更多數據)會發生什么。
另一種選擇是將其拆分為一個函數:
int func(){
int n;
printf("Enter a positive integer: ");
scanf("%d", &n);
return scanf("%d", &n) == 1 ? n : -1;
}
循環變成
while ((n = func()) < 0){
printf("Error: please enter a positive integer\n");
}
盡管條件檢查中的分配並不符合每個人的口味。 請注意,如果scanf
的返回值不為1,我將返回-1,您應始終檢查該值。
在這種情況下,我要做的是(請參閱Eric的回答)
switch (0) do {
printf("Error, please enter a positive integer\n");
case 0:
printf("Enter a positive integer: ");
scanf("%d", &n);
} while (n/*ToDo - make sure n is initialised if scanf fails*/ < 0);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.