我有以下计划。
int main () {
int a = 1;
long long b = 100000000;
printf("size of a is: %d \t sizeof b is:%d \n",sizeof(a),sizeof(b));
printf("a= %d b=%d a=%d \n", a, b, a);
printf("a= %d b=%Ld a=%d \n", a, b, a);
b = 10000000000;
printf("a= %d b=%d a=%d \n", a, b, a);
printf("a= %d b=%Ld a=%d \n", a, b, a);
}
当我使用gcc -m32
编译它时输出
size of a is: 4 sizeof b is:8
a= 1 b=100000000 a=0
a= 1 b=100000000 a=1
a= 1 b=1410065408 a=2
a= 1 b=10000000000 a=1
但是当使用gcc -m64
编译时输出是。
size of a is: 4 sizeof b is:8
a= 1 b=100000000 a=1
a= 1 b=100000000 a=1
a= 1 b=1410065408 a=1
a= 1 b=10000000000 a=1
为什么在打印第三个printf参数(a)时显示错误的值?
我的gcc版本是
priyanka@priyanka-N551JB:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
答案 0 :(得分:3)
您必须使用long long
打印%lld
个值。您无法使用%d
打印它们。如果您尝试使用%d
进行打印,则无法正常工作。 (事实证明%Ld
也不对,虽然听起来像gcc让你逃脱它。)
数字10000000000需要34位来表示它。正如您所发现的那样,它不适合16位或32位普通int
。但是,它将适合64位long long int
。
当您尝试使用long long
打印64位%d
时,很难确切知道会发生什么。你可以想象,8个字节被推入堆栈,%d
将其中的4个字节关闭。因此,其他四个仍然留在堆栈中,因此它们会弹出第三个%d
,而不是a
的实际值。这并不一定恰好发生了什么,实际上它可能比这更复杂。并发症可能很容易取决于您是否在32位或64位模式下进行编译。
这最终只是一个重要点的简单说明:当程序使用未定义的行为时,程序的所有方面可能会变得未定义。如果您做了一些非常错误的事情,比如尝试使用b
打印long long
%d
值,那么出现的问题不仅仅是b
' s值打印不当 - 其他事情也出错了。
这是一个类比。假设你购买一款全新的赛车,配备薄而快的轮胎。推销员提醒你,它只是一辆公路自行车,只能在光滑的铺砌道路上行驶。如果你试图越野越野,推销员警告你,如果你撞到岩石,轮胎很可能会爆裂。
现在,假设你做骑自行车离开马路。并且假设你越过一块岩石,轮胎爆裂,因此你失去控制,撞击,弯曲车把,并削减你的额头。假设你回到自行车店然后说,"好吧,我骑着自行车离开了路,轮胎就像你说的那样弹出。但你能解释为什么把手弯曲了,我的头上有这个切口吗?"