C代码的不合逻辑输出
Unlogical output of C code
我写了以下几行代码。
#include "stdio.h"
int main(){
float t,res;
char c;
scanf("%f",&t);
getchar();
scanf("%s",&c);
if (c=='R') res = 4/5 * t;
else if (c=='F') res = (9/5 * t) + 32;
else if (c=='K') res = t + 273;
printf("%.2f",&res);
return 0;
}
我不知道为什么当我给定 t = 25 和 c = 'R' 时输出显示 0.00。控制台看起来像这样。
25
R
0.00
有没有大佬给我解释一下?
改变
scanf("%s",&c);
到
scanf("%c",&c); // %c format specifier for character
改变
printf("%.2f",&res);
到
printf("%.2f",res); // No address of operator required
在
res = 4/5 * t;
/
和 *
具有相同的优先级,因此表达式从左到右求值。所以运算符出现很重要。
由于 4 和 5 都被计算为整数,因此除法结果为零
这就是结果为零的原因。要强制编译器将 4/5
视为浮点数,您可以明确提及至少一个值作为浮点数:
res = 4/5.0F * t;
首先,您按以下方式使用printf
:
printf("%.2f",&res);
但是根据你要打印的内容,你应该把它改成:
printf("%.2f", res);
其次,由于您正在阅读一个简单的字符,请修改此行:
scanf("%s",&c);
至:
scanf("%c", &c);
最后也是最重要的声明:
res = 4/5 * t;
将计算 整数商 (在 4/5
的情况下将得到 0
),但您想进行浮点除法。所以你应该把它改成:
res = (float)4/5 * t;
或:
res = 4/(float)5 * t;
因为该部门的两名成员之一需要 float
才能获得您想要的结果。
当然你也可以这样做:
res = 4.0/5 * t;
或:
res = 4/5.0 * t;
同样适用于9/5*t
,应改为9.0/5*t
或9/5.0*t
。
当然,
printf("%.2f",res); // without &
和
4.0/5 9.0/5 // .0 makes literal of double type
或更好
4.0F/5 9.0F/5 // .0F makes literal of float type
在表达式中。
但我的第二个建议是针对以下代码
scanf("%f",&t);
getchar(); // cleaning the input stream from one `'\n'`
scanf("%s",&c);
这部分最好写成
scanf("%f",&t);
while (getchar() != '\n'); // cleaning the input stream from everithing
c = getchar(); // reading one character
这种方法允许在输入类似
的内容后读取正确的字符
1.34abdfsk
R
在那种情况下 abdfsk
以及 \n
将被循环跳过 while (getchar() != '\n');
scanf("%s",&c);
很有可能导致超出范围的访问,从而调用 未定义的行为 。使用 scanf("%c",&c);
(%c
而不是 %s
)只读取一个字符。
printf("%.2f",&res);
将通过将错误类型的数据传递给 printf()
来调用 未定义的行为 。使用 printf("%.2f",res);
(没有 &
)打印类型为 double
(或 float
的数据,在可变长度参数中将自动转换为 double
)
- 表达式
res = 4/5 * t
和 res = (9/5 * t) + 32
可能无法满足您的要求,因为 4/5
和 9/5
是整数除法,其中的余数被截断。尝试使用 res = 4.f/5 * t
和 res = (9.f/5 * t) + 32
- 您应该检查
scanf()
s是否成功以及读取的数据是否有效,以免使用具有自动存储的未初始化变量的值调用未定义的行为持续时间,不确定。
我写了以下几行代码。
#include "stdio.h"
int main(){
float t,res;
char c;
scanf("%f",&t);
getchar();
scanf("%s",&c);
if (c=='R') res = 4/5 * t;
else if (c=='F') res = (9/5 * t) + 32;
else if (c=='K') res = t + 273;
printf("%.2f",&res);
return 0;
}
我不知道为什么当我给定 t = 25 和 c = 'R' 时输出显示 0.00。控制台看起来像这样。
25
R
0.00
有没有大佬给我解释一下?
改变
scanf("%s",&c);
到
scanf("%c",&c); // %c format specifier for character
改变
printf("%.2f",&res);
到
printf("%.2f",res); // No address of operator required
在
res = 4/5 * t;
/
和 *
具有相同的优先级,因此表达式从左到右求值。所以运算符出现很重要。
由于 4 和 5 都被计算为整数,因此除法结果为零
这就是结果为零的原因。要强制编译器将 4/5
视为浮点数,您可以明确提及至少一个值作为浮点数:
res = 4/5.0F * t;
首先,您按以下方式使用
printf
:printf("%.2f",&res);
但是根据你要打印的内容,你应该把它改成:
printf("%.2f", res);
其次,由于您正在阅读一个简单的字符,请修改此行:
scanf("%s",&c);
至:
scanf("%c", &c);
最后也是最重要的声明:
res = 4/5 * t;
将计算 整数商 (在
4/5
的情况下将得到0
),但您想进行浮点除法。所以你应该把它改成:res = (float)4/5 * t;
或:
res = 4/(float)5 * t;
因为该部门的两名成员之一需要
float
才能获得您想要的结果。当然你也可以这样做:
res = 4.0/5 * t;
或:
res = 4/5.0 * t;
同样适用于
9/5*t
,应改为9.0/5*t
或9/5.0*t
。
当然,
printf("%.2f",res); // without &
和
4.0/5 9.0/5 // .0 makes literal of double type
或更好
4.0F/5 9.0F/5 // .0F makes literal of float type
在表达式中。
但我的第二个建议是针对以下代码
scanf("%f",&t);
getchar(); // cleaning the input stream from one `'\n'`
scanf("%s",&c);
这部分最好写成
scanf("%f",&t);
while (getchar() != '\n'); // cleaning the input stream from everithing
c = getchar(); // reading one character
这种方法允许在输入类似
的内容后读取正确的字符1.34abdfsk
R
在那种情况下 abdfsk
以及 \n
将被循环跳过 while (getchar() != '\n');
scanf("%s",&c);
很有可能导致超出范围的访问,从而调用 未定义的行为 。使用scanf("%c",&c);
(%c
而不是%s
)只读取一个字符。printf("%.2f",&res);
将通过将错误类型的数据传递给printf()
来调用 未定义的行为 。使用printf("%.2f",res);
(没有&
)打印类型为double
(或float
的数据,在可变长度参数中将自动转换为double
)- 表达式
res = 4/5 * t
和res = (9/5 * t) + 32
可能无法满足您的要求,因为4/5
和9/5
是整数除法,其中的余数被截断。尝试使用res = 4.f/5 * t
和res = (9.f/5 * t) + 32
- 您应该检查
scanf()
s是否成功以及读取的数据是否有效,以免使用具有自动存储的未初始化变量的值调用未定义的行为持续时间,不确定。