为什么不同的格式说明符使用printf提供不同的输出?

时间:2016-01-17 05:58:38

标签: c

我想知道为什么这段代码的输出是0? y.betap->beta是相同的变量,因此输出不应该是3?

int main() {
    struct MyType {
        int alpha;
        double beta;
    };
    static struct MyType y;
    struct MyType *p = &y;
    y.alpha = 1;
    p->alpha = 2;
    p->beta = 2.5;
    y.beta = 1.5;
    printf("%d", y.beta + p->beta);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

通过将错误类型的参数传递给getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); 来调用未定义的行为:

printf

printf("%d", y.beta + p->beta); 期望传递%dinty.beta + p->beta值。

将代码更改为:

double

未定义的行为意味着任何事情都可能发生;尝试理解打印printf("%f\n", y.beta + p->beta); 的原因是徒劳的。其他东西可能发生在不同的机器上,或者在不同的时间,或者即使下雨或者老板来了,也可能发生; - )

答案 1 :(得分:1)

正如chqrlie正确指出的那样,printf("%d", somevariable)期望变量作为int传递,而您的结果是double类型值。

%d被称为格式说明符。这些是必需的,因为处理器以不同的方式传递和解释不同的数据类型,可能在存储器中的不同位置或不同的寄存器中(如x86_64平台的情况)。因此,基于数据类型,即使具有相同位模式的相同存储器位置也可以被非常不同地解释。这是另一个例子中发生的事情:

int main() {
    int a = 1048577;;
    printf("%d\n", a);
    printf("%hd", a);  //hd is the format specifier for short int
    return 0;
}

输出:

 1048577 
 1

如您所见,相同的变量a根据您指定的数据类型进行不同的解释。

为什么会这样? 这是1048577的二进制表示(假设为32位int):

00000000 00010000 00000000 00000001

如果格式说明符为short int%hd),则短路为16位宽,仅使用该值的16个低位,因此输出为1

在某些体系结构(x86 32位)上可能会出现类似情况,或者在double值以不同方式传递而printf获取{{1}的其他结构上更糟糕的情况来自调用者没有写入任何特定内容的位置,可能会出现任何随机值,例如int

解决方法是将代码修改为 chqrlie

指出的0