繁体   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