C程序:帮助变量定义序列

时间:2012-01-27 21:08:39

标签: c variables floating-point int definition

void main()
{
    float x = 8.2;
    int r = 6;
    printf ( "%f" ,  r/4);
}

很明显,我没有明确地将printf函数中的r(int类型)强制转换为float。但是,如果我改变声明x和r的顺序并首先声明r然后x i得到不同的结果(在这种情况下它是一个垃圾值)。我再次使用x 在程序的任何地方..这些是我想要错的东西......我想保持他们的方式。但是当我执行第一段代码时,我得到了157286.375011(垃圾值)。

void main()
{
    int r = 6;
    float x = 8.2;
    printf ( "%f" ,  r/4);
}

如果我执行上面的代码,我得到0.000000作为结果。我知道结果可能会出错,因为我在printf中使用%f时应该是%d ...结果可能是错误的...但我的问题是当我改变变量定义序列时结果会发生变化的原因。无论是对还是错,不应该是一样的吗?

为什么会这样?

3 个答案:

答案 0 :(得分:8)

printf没有任何类型检查。它依赖于您自己进行检查,验证所有类型都与格式说明符匹配。

如果你这样做,你就进入了未定义行为的领域,任何事情都可能发生。 printf函数正在尝试根据您使用的格式说明符来解释指定的值。如果它们不匹配,就会繁荣。

%f指定int是无稽之谈,但您已经知道......

答案 1 :(得分:3)

f转换说明符采用double参数,但您传递的是int参数。将int参数传递给f转换说明符是未定义的行为。

在这个表达式中:

r / 4

两个操作数都是int类型,结果也是int类型。

这是你想要的:

printf ("%f",  r / 4.0);

答案 2 :(得分:1)

printf抓取可选变量(即char *之后的变量告诉它要打印什么)时,它必须将它们从堆栈中取出。 double通常为64位(8字节),而int为32位(4字节)。

此外,与整数相比,浮点数具有奇怪的内部结构。

由于您传递int代替doubleprintf正试图从堆栈中取出8个字节而不是4个字节,并且它正在尝试解释字节一个int作为double的字节。

因此,您不仅得到包含没有人知道的4个字节的内存,而且您还要解释该内存 - 这是int的4个字节和4个字节的随机从不知道的东西 - 好像它是double

所以是的,奇怪的事情将要发生。当你重新编译(甚至是重新运行)一个程序时,你只需要在没有malloc'并且没有存储的情况下肆无忌惮地选择内存,将会变得无法预测并且变化很大。

不要这样做。