遇到的问题
今天遇到了一个很奇怪的问题,当使用malloc
分配了一个堆空间后,分别尝试用cout
和printf
尝试打印该地址,出现了两个地址不一样的情况:
int *pp = (int*)malloc(10*sizeof(int));
*pp = 1234;
cout << pp << '\t' << *pp << endl;
printf("0x%x\t%d\n", pp, *pp);
free(pp);
可以看出两个地址低32位是一致的,出现问题的原因应该是printf
显示不全导致的。
后来弄明白了,这是C/C++里占位符之间的区别导致的。
C/C++占位符%x和%p
实际上,上面cout
流输出的pp表示的就是实际的地址值,和%p
是一个意思,当我们使用%p
输出时,结果就是正常的:
printf("%p\t%d\n", pp, *pp);
那么%x
输出的时候为什么不对呢?这是因为%x
是按照int
占位4字节来表示的,在16位和32位系统里,由于地址不超过4字节,所以不会导致%x和%p的输出区别。
但是在64位系统里,%p
占位变成了8字节,而%x
则还是4字节,所以高位就被截断了。
如果需要正确输出,我们可以指定%llx
,这样输出结果就是一致的了:
C/C++占位符总结
格式化占位符(format placeholder),语法是:
%[*parameter*][*flags*][*field width*][.*precision*][*length*]*type*
Parameter可以忽略或者是:
Flags可为0个或多个:
Field Width给出显示数值的最小宽度,典型用于制表输出时填充固定宽度的表目。实际输出字符的个数不足域宽,则根据左对齐或右对齐进行填充。实际输出字符的个数超过域宽并不引起数值截断,而是显示全部。宽度值的前导0被解释为0填充标志,如上述;前导的负值被解释为其绝对值,负号解释为左对齐标志。如果域宽值为*
,则由对应的函数参数的值为当前域宽。
Precision通常指明输出的最大长度,依赖于特定的格式化类型。对于d、i、u、x、o的整型数值,是指最小数字位数,不足的位要在左侧补0,如果超过也不截断,缺省值为1。对于a,A,e,E,f,F的浮点数值,是指小数点右边显示的数字位数,必要时四舍五入或补0;缺省值为6。对于g,G的浮点数值,是指有效数字的最大位数;缺省值为6。对于s的字符串类型,是指输出的字节的上限,超出限制的其它字符将被截断。如果域宽为*
,则由对应的函数参数的值为当前域宽。如果仅给出了小数点,则域宽为0。
Length指出浮点型参数或整型参数的长度。此项Microsoft称为“Size”。可以忽略,或者是下述:
类型 Type,也称转换说明(conversion specification/specifier),可以是:
参考文献
如有疑问或错误,欢迎和我私信交流指正。
版权所有,未经授权,请勿转载!
Copyright © 2023 by Mr.Idleman. All rights reserved.