C while循环中具有相同条件的If语句

C while循环中具有相同条件的If语句,c,if-statement,while-loop,conditional-statements,C,If Statement,While Loop,Conditional Statements,有没有更好的方法通过消除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) {

有没有更好的方法通过消除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我通常编写代码的方式如中所示。正如一些人所指出的,优化通常使这个简单的情况不值得担心,但问题不限于像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);
但你不应该

脚注
1通常,软件工程师必须使用他人编写的代码,因此他们必须准备好识别和理解语言中任何可表达的内容,即使这只是将其改写为更好代码的第一步。有时,出于商业或其他实际原因,“难看”的代码会变得令人满意。

这是IMO最好通过一些重构来实现的:

#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");
}
然后调用代码是:

while ((n = read_positive_integer()) < 0)
    printf("Error: please enter a positive integer\n");

这个主题有很多变化;您可以将while循环包装成一个函数;您可以将提示转换为函数的参数。与scanf在输入中返回0个非数字数据或EOF在输入中没有更多数据相比,您可能会决定更小心地报告printf失败时出现的错误不同操作。

另一种选择是拆分为一个函数:

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;
}
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");
}

你说更好是什么意思?更安全的?更快?更具可读性?另外,n的类型是什么?首先,最好检查scanf的返回值。在while循环之前n>=0是否可能?如果不是,您可以将其转换为一个无限循环,并在If块中添加一个中断。n是一个int。我的意思是更好地消除If语句中的重复条件。启用优化后,一个好的编译器应该优化掉重复条件,因此可能不值得担心。消除重复条件的唯一其他方法是打破无限循环。Upped。我经常使用第二种方式,尽管我的格式略有不同;我写开关0做什么{一句话:我不知道你为什么说你不应该使用它。你知道……Eric对使用goto是诚实的。这只是把它伪装成结构化的东西。@StoryTeller:goto的问题和它的运行时效果一样与它向翻译单元泄漏标签有关。我这样做的方式绕过前者。开关0 do是某种时髦习语的明确信号。不是转换单元,而是函数。标签有函数范围,所以不会泄漏到任何全局。@StoryTeller:在某些方面,我很高兴我不知道。一直都是这样吗?我在大学时使用了C的一个非常早期的版本。似乎和我一样古老。我但我不知道在K&R是不是这样。
while ((n = func()) < 0){
    printf("Error: please enter a positive integer\n");
}
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);