如何在 c 中打印 0x0000000 而不是 (nil) 和 0x08ffffff 而不是 0x8ffffff
how to printf 0x0000000 instead of (nil) and 0x08ffffff instead of 0x8ffffff in c
我正在尝试使用 stdout stream
来打印 0x00000000
而不是 (nil)
和 0x08ffffff
而不是 0x8ffffff
。
所以基本上,char *ptr1 = 0x00000000
和 char *ptr2 = 0x08ffffff
。
当我运行
printf("start of address is %p and end of address is %p", ptr1, ptr2);
我明白了
start of address is (nil) and end of address is 0x8ffffff
我实际上找到了解决这个问题的方法,我实际上会这样做:
char *ptr1 = 0x00000000;
char *ptr2 = 0x08ffffff;
printf("start 0x%08x and end 0x%08x\n",ptr1, ptr2);
这会生成
start 0x00000000 and end 0x08ffffff
但是,编译器发出以下警告:
warning: format ‘%x’ expects argument of type ‘unsigned int’,
but argument 3 has type ‘void *’ [-Wformat=]
我应该如何修改printf来调整输出打印?
首先,要控制地址的打印方式,您必须将它们转换为整数类型。 %p
打印指针的规范不充分。为此,您可以包含 <stdint.h>
并使用 uintptr_t
类型,这是一种无符号整数类型,适用于某些地址工作。
其次,header <inttypes.h>
提供了一个宏 PRIxPTR
,它提供了一个 printf
转换说明符,用于以十六进制打印 uintptr_t
值。
第三,您可以添加一个标志 0
和一个最小字段宽度 8
以请求将零转换为至少八位数字。
示例代码如下:
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
static void PrintAddress(const void *p)
{
uintptr_t u = (uintptr_t) p;
printf("0x%08" PRIxPTR, u);
}
int main(void)
{
char *ptr1 = (char *) 0x00000000;
char *ptr2 = (char *) 0x08ffffff;
printf("Start of address is ");
PrintAddress(ptr1);
printf(" and end of address is ");
PrintAddress(ptr2);
printf(".\n");
}
更好的是,您可以通过包含 <limits.h>
并计算所需的位数来调整字段宽度以适应 C 实现中 uintptr_t
的大小:
printf("0x%0*" PRIxPTR, ((int) sizeof u * CHAR_BIT + 3) / 4, u);
请注意,像初始化 ptr1
和 ptr2
那样直接将指针设置为 hard-coded 常量值的情况很少见。它通常用于对硬件做特殊的事情。当你故意将整数转换为指针时,你应该使用强制转换以避免编译器警告。
我正在尝试使用 stdout stream
来打印 0x00000000
而不是 (nil)
和 0x08ffffff
而不是 0x8ffffff
。
所以基本上,char *ptr1 = 0x00000000
和 char *ptr2 = 0x08ffffff
。
当我运行
printf("start of address is %p and end of address is %p", ptr1, ptr2);
我明白了
start of address is (nil) and end of address is 0x8ffffff
我实际上找到了解决这个问题的方法,我实际上会这样做:
char *ptr1 = 0x00000000;
char *ptr2 = 0x08ffffff;
printf("start 0x%08x and end 0x%08x\n",ptr1, ptr2);
这会生成
start 0x00000000 and end 0x08ffffff
但是,编译器发出以下警告:
warning: format ‘%x’ expects argument of type ‘unsigned int’,
but argument 3 has type ‘void *’ [-Wformat=]
我应该如何修改printf来调整输出打印?
首先,要控制地址的打印方式,您必须将它们转换为整数类型。 %p
打印指针的规范不充分。为此,您可以包含 <stdint.h>
并使用 uintptr_t
类型,这是一种无符号整数类型,适用于某些地址工作。
其次,header <inttypes.h>
提供了一个宏 PRIxPTR
,它提供了一个 printf
转换说明符,用于以十六进制打印 uintptr_t
值。
第三,您可以添加一个标志 0
和一个最小字段宽度 8
以请求将零转换为至少八位数字。
示例代码如下:
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
static void PrintAddress(const void *p)
{
uintptr_t u = (uintptr_t) p;
printf("0x%08" PRIxPTR, u);
}
int main(void)
{
char *ptr1 = (char *) 0x00000000;
char *ptr2 = (char *) 0x08ffffff;
printf("Start of address is ");
PrintAddress(ptr1);
printf(" and end of address is ");
PrintAddress(ptr2);
printf(".\n");
}
更好的是,您可以通过包含 <limits.h>
并计算所需的位数来调整字段宽度以适应 C 实现中 uintptr_t
的大小:
printf("0x%0*" PRIxPTR, ((int) sizeof u * CHAR_BIT + 3) / 4, u);
请注意,像初始化 ptr1
和 ptr2
那样直接将指针设置为 hard-coded 常量值的情况很少见。它通常用于对硬件做特殊的事情。当你故意将整数转换为指针时,你应该使用强制转换以避免编译器警告。