问候,今天当我尝试新的东西(概念和风格突然出现在我脑海中)时,我遇到了一些我不明白为什么会发生的问题。
守则
// This program would get two numbers from user , and request for an arithmetic operator , and carry out arithmetic.
#include <stdio.h>
int main(void)
{
int fNum;
int sNum;
int status = 1;
int operator;
int ans;
printf("Enter the first operand :");
while(scanf("%d" , &fNum) == 0)
;
printf("Please enter the second operand :");
while(scanf("%d" , &sNum) == 0)
;
printf("Which operator you wanted to use\n");
printf("1 for +\n2 for -\n");
while(status)
{
scanf("%d" , &operator);
status = 0;
switch(operator)
{
case 1:
ans = fNum + sNum;
break;
case 2:
ans = fNum - sNum;
break;
default:
status = 1;
}
}
printf("The answer is %d\n" , ans);
return 0;
}
我的分析和问题
第一部分:
1.)有一点我不明白,当我尝试运行此代码时,我收到编译器的警告消息,“C:\ Users \ Znet \ Documents \ Pelles C Projects \ Test1 \ Test.c(10):警告#2229:本地'ans'可能在未初始化的情况下使用。“,但当然我仍然可以运行程序,因为它不是错误信息。
2.)我只是想知道为什么这个警告消息出于好奇,而不是仅仅声明变量ans
,我用整数值(0或任何整数)初始化它,以及警告消息刚刚走了。导致这种情况发生的原因是什么呢?是因为变量ans
用在switch
语句中,这就是为什么我们应该在使用它之前给它赋值?因为所有的时间(当我'编码其他程序)在使用它来存储由算术表达式计算的值之前,我甚至没有用值初始化变量。
第二部分:
1.)当程序要求用户输入数字switch
或1
作为算术符号时,问题会在2
语句中引起。
2.)如果我输入一个不在1和2之间的整数,程序将不会继续,而是等我重新输入正确的值,这是我的主要目的。
3.)但问题是,如果我输入的值不是整数而是字符,程序只会冻结,光标仍然闪烁但是它不响应我的键盘输入。最后,我必须杀死该程序才能关闭它。
4.)我知道我有很多方法来编写这种程序,但我只是想知道为什么在这段代码中,这种情况会发生?
感谢您阅读我的问题,希望得到您们的解释和知识:)
答案 0 :(得分:2)
第一个问题:
编译器检测到ans
仅有条件地为其分配值(对于switch语句中的两个特定情况)。一些编译器警告这个,而其他编译器则没有。通常,初始化您创建的任何变量始终是一种好习惯。
第二个问题:
此问题之前已多次得到解答 - 请参阅infinite scanf loop。问题是scanf在这种情况下只接受整数。正如此链接中所提到的“任何与格式字符串不匹配的字符都会导致它停止扫描并使无效字符仍在缓冲区中。”这导致你的while循环永不退出。如果您对更多细节感兴趣,这里提到的链接应该对您有所帮助。
答案 1 :(得分:0)
问:“警告#2229:可能会使用本地'ans'而不进行初始化。”
答:这意味着ans可以在声明时包含任何值(因为堆栈变量在声明时没有被删除) - 并且由于编译器没有看到编程逻辑,保证在打印时设置变量 - 它会抛出这个警告。执行int ans = 0;
会将其删除。
问:如果我输入的值不是整数而是字符,程序就会冻结,光标仍然闪烁但是它不响应我的键盘输入。最后,我要杀了程序是为了关闭它。
A
do {
printf("Which operator you wanted to use\n");
printf("1 for +\n2 for -\n");
} while ( scanf("%d", &operator) != 1 );
scanf
返回匹配量 - 如果它与整数不匹配,则返回0.因此;检查返回值。
答案 2 :(得分:0)
编译器可以在使用变量时发出警告而不显式初始化。这是因为未初始化的变量可能会在代码中产生令人讨厌的错误。例如,请考虑以下代码段。
int main()
{
/* NOTE: 'f' is uninitialized */
int f, n;
printf ("\nn : ");
scanf ("%d", &n);
while (n)
f = f * n--;
printf ("\nfactorial = %d", f);
return 0;
}
在上面的代码中,程序的输出未定义。 f
是一个局部变量(automatic
),所以当main
开始执行f
时可以有任何值,即垃圾,并且因子计算依赖于初始值f
。因此,在这种情况下,未初始化的变量将导致您陷入灾难。要解决它,您需要执行int f = 1;
并获得正确的输出。这不是错误,但可能是一个逻辑错误,因此编译器可以帮助您,您可能不会意外地保留未初始化的变量。在您的情况下,不需要初始化,因此您只需执行ans = 0;
停止警告。
字符和整数的解释方式不同。例如12
是两个字符,我们也可以说它是一个整数。要将其作为整数输入,您应使用"%d"
和字符scanf ("%c%c",&var1, var2);
,因为有两个字符。当格式字符串为"%d"
时输入字符时,它将检测到输入不是整数(它是一个字符),并将在此时停止并返回。 operator
变量中不会存储任何内容。 scanf
返回它已读取的组件数。在这种情况下,当遇到您输入的字符时,它将返回0
,因为它没有在输入中读取并且已经停止。但是当您输入一个整数时,它将在operator
中正确读取并返回1
。所以请检查一下:
/* Ask for input while the user does not input a
* valid integer.
*/
while (scanf ("%d", &operator) != 1)
{
/* Body is entered whenever an invalid integer is entered */
/* Your message */
}
/* When the user inputs a valid integer the condition
* in 'while' loop is false and program continues
*/