C printf(";%p";)和铸造到(void*)

C printf(";%p";)和铸造到(void*),c,pointers,casting,printf,void,C,Pointers,Casting,Printf,Void,在最近的一个问题中,有人提到,当使用printf打印指针值时,调用方必须将指针强制转换为void*,如下所示: int *my_ptr = .... printf("My pointer is: %p", (void *)my_ptr); 为了我的生命,我不知道为什么。我发现,这几乎是一样的。这个问题的答案是正确的——它解释了整数和指针的长度不一定相同 当然,这是正确的,但是当我已经有了指针,就像上面的例子一样,为什么我要从int*转换到void*?什么时候int*与void*不同?事实上,

在最近的一个问题中,有人提到,当使用printf打印指针值时,调用方必须将指针强制转换为void*,如下所示:

int *my_ptr = ....

printf("My pointer is: %p", (void *)my_ptr);
为了我的生命,我不知道为什么。我发现,这几乎是一样的。这个问题的答案是正确的——它解释了整数和指针的长度不一定相同

当然,这是正确的,但是当我已经有了指针,就像上面的例子一样,为什么我要从
int*
转换到
void*
?什么时候int*与void*不同?事实上,
(void*)my_ptr
什么时候生成的机器代码不同于简单的
my_ptr

更新:
多个知识渊博的响应者引用了该标准,称传递错误的类型可能导致未定义的行为。怎么用?我希望
printf(“%p”,(int*)ptr)
printf(“%p”,(void*)ptr)
生成完全相同的堆栈帧。这两个调用何时生成不同的堆栈帧?

转换说明符需要类型为
void*
的参数。如果未传递类型为
void*
的参数,函数调用将调用未定义的行为

根据C标准(C11,7.21.6.1p8格式的输入/输出函数):

“p-参数应为指向void的指针。”

C中的指针类型不需要具有相同的大小或相同的表示形式

具有不同指针类型表示的实现示例是Cray PVP,其中对于
void*
char*
,指针类型的表示为64位,而对于其他指针类型,指针类型的表示为32位


参见“克雷C/C++参考手册”,表3。在“9.1.2.2”中,转换说明符需要类型为
void*
的参数。如果未传递类型为
void*
的参数,函数调用将调用未定义的行为

根据C标准(C11,7.21.6.1p8格式的输入/输出函数):

“p-参数应为指向void的指针。”

C中的指针类型不需要具有相同的大小或相同的表示形式

具有不同指针类型表示的实现示例是Cray PVP,其中对于
void*
char*
,指针类型的表示为64位,而对于其他指针类型,指针类型的表示为32位


参见“克雷C/C++参考手册”,表3。在“9.1.2.2”中

实际上,除了在古老的大型机/小型机上,不同的指针类型不太可能有不同的大小。但是,它们有不同的类型,并且根据
printf
的规范,使用格式说明符的错误类型参数调用它会导致未定义的行为。这意味着不要这样做。

实际上,除了在古代的大型机/小型机上,不同的指针类型不太可能有不同的大小。但是,它们有不同的类型,并且根据
printf
的规范,使用格式说明符的错误类型参数调用它会导致未定义的行为。这意味着不要这样做。

c11:7.21.6格式化输入/输出函数(第8页):
p
参数应是指向
void
指针。指针的值为 在定义的实现中转换为打印字符序列 态度

c11:7.21.6格式化输入/输出函数(第8页):
p
参数应是指向
void
指针。指针的值为 在定义的实现中转换为打印字符序列 态度


在C语言中,所有指针类型的表示形式都可能不同。因此,是的,
int*
不同于
void*
。可能很难(或不可能)找到能够说明这种差异的现实平台,但在概念层面上,差异仍然存在

换句话说,在一般情况下,不同的指针类型具有不同的表示形式
int*
不同于
void*
,也不同于
double*
。就C语言而言,您的平台对
void*
int*
使用相同的表示形式这一事实只不过是巧合


该语言规定,某些指针类型必须具有相同的表示形式,其中包括
void*
char*
的比较,指向不同结构类型的指针,或者说,
int*
const int*
。但这些只是一般规则的例外。

在C语言中,所有指针类型的表示形式都可能不同。因此,是的,
int*
不同于
void*
。可能很难(或不可能)找到能够说明这种差异的现实平台,但在概念层面上,差异仍然存在

换句话说,在一般情况下,不同的指针类型具有不同的表示形式
int*
不同于
void*
,也不同于
double*
。就C语言而言,您的平台对
void*
int*
使用相同的表示形式这一事实只不过是巧合


该语言规定,某些指针类型必须具有相同的表示形式,其中包括
void*
char*
的比较,指向不同结构类型的指针,或者说,
int*
const int*
。但是这些只是一般规则的例外。

其他人已经充分说明了将
int*
传递给原型函数的情况,该原型函数具有固定数量的参数,并且需要不同的指针类型

printf
不是这样的函数。它是一个变量函数,因此默认参数用于其匿名参数
int a;
printf("%p\n", &a);
printf("My pointer is: %p", (void *)my_ptr); // OK when my_ptr points to an object
printf("My function pointer is: %ju", (uintmax_t) my_function_ptr); // Selectively OK