【问题标题】:C program : help about variable definition sequenceC程序:关于变量定义序列的帮助
【发布时间】:2012-02-20 20:14:52
【问题描述】:
void main()
{
    float x = 8.2;
    int r = 6;
    printf ( "%f" ,  r/4);
}

很奇怪,我没有明确地将 printf func 中的 r(int 类型)强制转换为浮点数。但是,如果我更改声明 x 和 r 的顺序并先声明 r 然后 x 我会得到不同的结果(在这种情况下它是垃圾值)。我再次没有使用 x 在程序中的任何地方.. 这些都是我的意思是错的......我想让它们保持原样。但是当我执行第一段代码时,我得到 157286.375011 作为结果(一个垃圾值)。

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

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

为什么会这样?

【问题讨论】:

  • 你需要#include <stdio.h>,而void main()应该是int main(void)
  • 任何未定义的行为就是:未定义。如果您想详细了解为什么未定义的行为会以某种方式“表现”,您最好询问编译器作者。 . .谁可能会回答“谁在乎?”但是,如果我不得不猜测,我会说这与 printf 期望浮点数的位数以及这些位在内存中的对齐方式有关,这可能会受到声明顺序的影响。
  • 是的,我在编译器中使用了它们。 “未定义”未定义。你说的对。 :) 感谢您的回答。

标签: c variables floating-point int definition


【解决方案1】:

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

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

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

【讨论】:

  • 或者,打开适当的编译器警告,为您进行类型检查(-Wformat 用于 gcc)。
  • 是的,有一个 GCC 扩展;了解更多here。不幸的是,我不知道微软的编译器有什么这样的东西,我 99% 的时间都在使用它。
  • 谢谢你,谢谢你的回答。在某种程度上满足了我...!
【解决方案2】:

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

在这个表达式中:

r / 4

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

这是你想要的:

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

【讨论】:

  • 是的,但希望它是那样的......我知道它很奇怪,但我对“未定义的行为”了解不多?感谢您回答我的问题。
  • @user1174382 C 标准告诉你不要这样做。如果您坚持实施可以得到“任意数量的报复”,例如在您运行程序时使您的机器崩溃或擦除您的硬盘驱动器。这就是未定义的行为。
【解决方案3】:

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

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

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

因此,您不仅获得了包含 没有人知道什么 的 4 字节内存,而且还解释了该内存 - 即 4 字节的 int 和 4 字节的随机内容无处——好像是double

所以是的,奇怪的事情会发生。当你重新编译(甚至多次重新运行)一个程序,它只是肆意从内存中挑选出它没有malloc'd 并且它没有存储的东西,你就是会得到不可预测且变化很大的值。

别这样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多