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