Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么不同的格式说明符在printf中给出不同的输出?_C - Fatal编程技术网

C 为什么不同的格式说明符在printf中给出不同的输出?

C 为什么不同的格式说明符在printf中给出不同的输出?,c,C,我想知道为什么这段代码的输出是0? y.beta和p->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;

我想知道为什么这段代码的输出是0?
y.beta
p->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;
}

通过将错误类型的参数传递给
printf
,调用未定义的行为:

printf("%d", y.beta + p->beta);
%d
期望传递一个
int
y.beta+p->beta
是一个
双值

将代码更改为:

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

正如正确指出的,
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
):

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

在某些体系结构(x86 32位)上可能会发生类似的情况,在其他体系结构上可能会发生更糟的情况,
double
值以不同的方式传递,并且
printf
从调用方未写入任何特定值且可能存在任何随机值的位置获取
int
,例如
0

解决方法是将代码修改为
printf(“%f”,y.beta+p->beta)
正如

所指出的,
%d
需要是
%f
谢谢,为什么%d不工作@user3386109@Nona:%d表示数字(整数),%f表示浮点数。
%d
用于打印整数,例如
alpha
%f
用于打印
浮点
双精度
,例如
beta
。即使您试图打印的数字恰好是一个整数,如果您在编译器中启用了警告(例如,
gcc-Wall-g
),则表达式
y.beta+p->beta
的类型为
double
然后,您将在
printf
上收到一条警告,并且本可以在不询问的情况下纠正您的错误。谢谢您的额外解释,但您的示例有点误导:
%hu
需要
无符号int
,但将其解释为un
无符号short
。这不会调用未定义的行为,而在
sizeof(long-long)!=sizeof(int)
。将其更正为%hd。现在看起来不错,还不完全好
%hd
%hu
都通过将
int
无符号int
参数分别强制转换为
short
无符号short
来重新解释参数。在您的解释中,您提到了最后8位,但实际上是最后16位,或者更多,这取决于
short
的实际大小。此外,不同的类型可能会在不同的位置传递到
printf
,因此关于如何解释位模式的讨论可能并不相关。我纠正了你的回答。
00000000 00010000 00000000 00000001