记一次使用printf的坑
printf输出错误?
32位编译
#include <stdio.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
int64_t a = 20;
int32_t b = 10;
printf("a:%d b:%d\n", a,b);
getchar();
return 0;
}
输出:
a:20 b:0
这是模拟当时的情况,printf想用’’%d’的方式打印两个变量。但是另一个输出为0.
原因分析
调用的堆栈情况。一行4字节
返回mian的地址 |
---|
a低位 |
a高位 |
b |
指向"a:%d b:%d\n"的地址 |
printf可以是用va_start,va_end,va_arg这些宏实现的,大体的代码逻辑
va_list va;
va_start(va,_Format);
char *p = _Format;
for(;p;p++){
if(*p == '%'){
char ch = *(p + 1);
switch(ch){
case 'd':
...
int num = va_arg(va,int); //问题点
break;
...
}
}
...
}
出现问题的原因是因为使用’%d’输出64位的变量。‘%d’意味着内存偏移只有4字节,而正真需要的是偏移8字节
验证:
把输出改为:
printf("a:%d b:%d c:%d\n", a,b);
输出:
a:20 b:0 c:10
甚至可以这样写:
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
struct student
{
int a;
int b;
int c;
int d;
};
int main(int argc, char *argv[])
{
struct student stu = { 2,3,4,5 };
printf("a:%d b:%d c:%d d:%d\n", stu);
getchar();
return 0;
}
输出:
a:2 b:3 c:4 d:5
以上出现这种情况是32位程序,64位没有。