打印一个结构体对象的地址

4
我有一个像这样的struct
typedef struct _somestruct {
    int a;
    int b;
}SOMESTRUCT,*LPSOMESTRUCT;

我正在创建一个struct对象,并试图像这样打印它的地址。

int main()
{
    LPSOMESTRUCT val = (LPSOMESTRUCT)malloc(sizeof(SOMESTRUCT));

    printf("0%x\n", val);

    return 0;
}

...然后我收到了这个警告

警告 C4313: 'printf' : 格式字符串中的 '%x' 与类型为 'LPSOMESTRUCT' 的第 1 个参数存在冲突

因此,我尝试将地址强制转换为 int,像这样

printf("0%x\n", static_cast<int>(val));

但我收到了这个错误:

错误 C2440:'static_cast':无法将“LPSOMESTRUCT”转换为“int”

我错过了什么?如何避免此警告?

谢谢。

4个回答

12

%x 期望一个无符号数,但你正在打印一个指针。为了正确地做到这一点,通常需要使用%p。严格来说,那个期望一个指向 void 的指针,所以你需要进行强制类型转换:

printf("%p\n", (void *)val);

实际上,大多数当前的实现都使用相同的指针格式,这种情况下强制转换将是无意义的。当然,考虑到 C++ 标签,你所包含的代码大部分都变得可疑(除了像 LPSOMESTRUCT 这样的部分,不管怎样都是可疑的)。在 C++ 中,通常需要类似以下的代码:

struct somestruct { 
   int a;
   int b;
};

somestruct *val = new somestruct; // even this is questionable.

std::cout << val;

2
使用%p格式说明符打印指针。
printf("%p\n", val);

1

由于这个标签是C++,我想指出在该语言中创建结构体时不需要使用typedef:

typedef struct _somestruct {
    int a;
    int b;
}SOMESTRUCT,*LPSOMESTRUCT;

应该是:

struct SOMESTRUCT {
    int a;
    int b;
};

此外,许多人认为创建像 LPSOMESTRUCT 这样的 typedef 是不好的实践,因为它隐藏了类型是指针的事实。


1
如果你想进行类型转换,使用reinterpret_cast而不是static_cast可能会在这里起作用。
使用printf时,尝试使用%zu而不是%x来打印指针,因为指针是无符号整数类型(即%zu)。
printf("%zu \n", val);

还有一件事,作为一个C++程序,你使用malloc而不是new的原因是什么?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接