【问题标题】:Unlogical output of C codeC代码的非逻辑输出
【发布时间】:2016-08-25 06:39:35
【问题描述】:

我写了以下几行代码。

#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

谁能给我一个解释?

【问题讨论】:

  • printf() 期望 res,而不是 &res
  • scanf("%s",&c); --> scanf(" %c",&c);
  • "当我给 t = 25 和 c = 'R'" 怎么样?如果您从标准输入而不是调试器输入R,您将通过访问超出范围来调用未定义行为。应该使用%c 而不是%s 来读取一个字符。
  • 也许需要c = getchar(); 而不是scanf("%s",&c);
  • 整数除法:res = 4/5 * t; 应该是 res = 4.0/5.0 * t; 或类似于强制浮点除法的东西。在你想要的浮点运算中使用浮点常量——使用整数会带来问题。此外,最好用换行符结束打印操作。

标签: c pointers char nested-if


【解决方案1】:
  • 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 是否成功并且读取的数据是否有效,以免通过使用具有自动存储持续时间的未初始化变量的值来调用未定义的行为,这些值是不确定的。

【讨论】:

    【解决方案2】:
    • 首先,你使用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

    【讨论】:

      【解决方案3】:

      当然,

      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');

      【讨论】:

        【解决方案4】:

        改变

        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;
        

        【讨论】:

        • 我做到了,但没有任何改变
        猜你喜欢
        • 1970-01-01
        • 2013-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多