c语⾔printf输出中⽂报错,c++-C语⾔中printf输出的奇怪错误⼩⽪2017-04-17 11:44:341楼
你留意⼀下标准库⾥⾯的stdarg.h⽂件,它⾥⾯定义了⼏个宏,分别是va_start、va_arg、va_end,这⼏个宏都是⽤来做不定参数传递的。特别注意的是va_arg在获取传递进来的参数时依赖它的第⼆个参数(t,类型),如果类型不对应的话会导致整个不定参数的传递没法正常的解析(错位)。prinft依赖于vsprintf,⽽vsprintf的实现依赖这⼏个宏,它会根据格式字符串(也就是那些%d %f ...)来调⽤va_arg,如果你的格式字符串和你后⾯的不定参数没有正确对应起来,那么也有可能在获取不定参数时出现错位(⽽你第⼆个输出对了两次也是因为错位了两次之后刚好⼜对上了的缘故)。
还有float(32位)参数在传递printf的时候会⾃动转换成double(64位)(这也是%f和%lf没区别的缘故),int参数占32位。
有了上⾯的铺垫之后,下⾯来解释你的这个问题。
环境:Windows XP 32, gcc version 3.4.0 (mingw special)
注:以下连续的⼗六进制数据从左到右对应于内存地址的由低到⾼
你传⼊的参数a,a,b,b,对应⼗六进制的00 00 00 00 00 00 04 40 00 00 00 00 00 00 04 40 02 00 00 00 02 00 00 00正确的分割应该是:
a: [00 00 00 00 00 00 04 40]
a: [00 00 00 00 00 00 04 40]
b: [02 00 00 00]
b: [02 00 00 00]
根据你的第⼀次输出的格式字符串,printf做了如下的分割:
c语言中文网汇编语言
%d: [00 00 00 00] int,对应0x00000000,也就是0了
%f: [00 00 04 40 00 00 00 00] double,0.0,(看double的表⽰法)
%d: [00 00 04 40] int,对应0x40040000,也就是10进制的1074003968
%f: [02 00 00 00 02 00 00 00] double,0.0
所以输出也就是:
0.000000
1074003968
0.000000
⽽根据你第⼆次输出的格式字符串,printf做了如下的分割:
%f: [00 00 00 00 00 00 04 40] double, 对应2.5
%d: [00 00 00 00] int 对应0
%f: [00 00 04 40 02 00 00 00] double,对应0
%d:[02 00 00 00] int 对应0
也就是你看到的:
2.500000
0.000000