c - 如何在c中打印0x0000000而不是(nil)和0x08ffffff而不是0x8ffffff

标签 c pointers printf stdout

我正在尝试使用stdout流来打印0x00000000而不是(nil)0x08ffffff 0x8ffffff

基本上,char *ptr1 = 0x00000000char *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 ,这是一种无符号整数类型,适合某些地址工作。

二、表头<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");
}

更好的是,您可以将字段宽度调整为 uintptr_t 的大小在您的 C 实现中包含 <limits.h>并计算所需的位数:

    printf("0x%0*" PRIxPTR, ((int) sizeof u * CHAR_BIT + 3) / 4, u);

请注意,直接设置指向硬编码常量值的指针,就像对 ptr1 的初始化所做的那样和ptr2 ,是罕见的。它通常用于用硬件做特殊的事情。当您故意将整数转换为指针时,应该使用强制转换以避免编译器警告。

关于c - 如何在c中打印0x0000000而不是(nil)和0x08ffffff而不是0x8ffffff,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66014239/

相关文章:

c++ - 不能将指针作为参数传递给另一个函数

c - 为什么此代码在 msdev 上运行时会出现访问冲突?

C 打印通用类型 vector

c++ - 我将如何使用 C/C++ 等语言创建类似于 ZIP 存档的文件压缩器?

c - NTRIPClient 更新 nmea

c++ - 如何正确删除C++中的指针?

c - "Freezing"控制台中的输入行并打印在上面的行上?

c - 费米架构上的 int2 与 int4 负载

c++ - 当 memcpy() 比 memmove() 快时,什么是真正重要的情况?

matlab - 在matlab中从结构创建表 - 对齐