为了账号安全,请及时绑定邮箱和手机立即绑定

printf(“%p”)并转换为(void *)

printf(“%p”)并转换为(void *)

C
米脂 2019-09-03 16:58:47
在最近的一个问题中,有人提到当使用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)生成完全相同的堆栈帧。两个调用何时生成不同的堆栈帧?
查看完整描述

3 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

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

换句话说,通常情况下,不同的指针类型具有不同的表示。int *不同于void *和不同double *。就C语言而言,您的平台使用相同的表示形式void *并且int *只不过是巧合。

一些指针类型都要求有相同的表述语言状态,其中包括void *主场迎战char *,指向不同的结构类型,或者说,int *const int *。但这些只是一般规则的例外。


查看完整回答
反对 回复 2019-09-03
?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

其他人已经充分解决了传递int *一个原型函数的情况,该函数具有固定数量的参数,这些参数需要不同的指针类型。


printf不是这样的功能。它是一个可变参数函数,因此默认参数升级用于其匿名参数(即格式字符串之后的所有内容),并且如果每个参数的提升类型与格式效应器所期望的类型不完全匹配,则行为未定义。特别是,即使 int *并且void *具有相同的表示,


int a;

printf("%p\n", &a);

有未定义的行为。


这是因为调用帧的布局可能取决于每个参数的确切具体类型。为指针和非指针类型指定不同参数区域的ABI已经在现实生活中发生(例如,Motorola 68000希望您尽可能地在地址寄存器和数据寄存器中的非指针中保持指针)。我不知道任何真实的ABI会分离不同的指针类型,但它是允许的,听到一个我也不会感到惊讶。


查看完整回答
反对 回复 2019-09-03
  • 3 回答
  • 0 关注
  • 1169 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信