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*t9/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 * tres = (9/5 * t) + 32 可能无法满足您的要求,因为 4/59/5 是整数除法,其中的余数被截断。尝试使用 res = 4.f/5 * tres = (9.f/5 * t) + 32
  • 您应该检查scanf()s是否成功以及读取的数据是否有效,以免使用具有自动存储的未初始化变量的值调用未定义的行为持续时间,不确定。