簡體   English   中英

如果條件相同的while循環中的if語句

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM