当前位置: 首页 > 知识库问答 >
问题:

printf("%p")和铸造到(空*)

靳富
2023-03-14

在最近的一个问题中,有人提到,当使用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个答案

贲高寒
2023-03-14

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

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

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

具有未定义的行为。

这是因为调用框架的布局可能取决于每个参数的具体类型。为指针和非指针类型指定不同参数区域的ABI在现实生活中已经出现(例如,Motorola 68000希望您尽可能将指针保留在地址寄存器中,将非指针保留在数据寄存器中)。我不知道现实世界中有哪种ABI可以分离不同的指针类型,但这是允许的,听到这种情况我也不会感到惊讶。

刘英彦
2023-03-14

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

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

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

连俊智
2023-03-14

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

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

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

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

具有不同指针类型表示的实现的一个示例是Cray PVP,其中指针类型的表示为64位,用于space*char*,但用于其他指针类型的表示为32位。

见“克雷C/C参考手册”,表3。在“9.1.2.2”中http://docs.cray.com/books/004-2179-003/004-2179-003-manual.pdf

 类似资料:
  • 我目前在辅导一个高中生AP Java,她问了我一个关于“双选”的问题。我以前从未听说过这个术语,但显然她的老师希望她在即将到来的期末考试中知道这个术语。 她的老师提供的例子是,如果你想将一个整数转换成一个字符串,你必须执行以下操作才能避免编译器错误: 问题是:你想在现实生活中什么时候这样做? 老师只提供了导致运行时错误的示例。此外,我从来不知道有一个术语,但这样做似乎是个坏主意,因为只有当两种类型

  • 我正在使用Java Mysql连接器,并且在提取结果时遇到问题: 这是需要执行的查询和准备好的语句: 现在我尝试在数组中获取结果,所以我使用: (1) 返回mysql。数组,该数组包含一个定位器,它是指向服务器上的SQL array的逻辑指针,并且(2)应该对temp进行类型转换并返回一个String[],但是我收到了这个错误 有什么想法吗?

  • TL;DR:为什么乘法/转换数据的速度很慢,为什么这因平台而异? 我遇到了一些不完全理解的性能问题。上下文是一个相机图像采集卡,其中以100 Hz的速率读取和后处理128x128 uint16_t图像。 在后处理中,我生成一个直方图 ) 令人惊讶的是,比? 更新4: 我在一台机器上用不同的数据类型和不同的编译器又做了一些测试。结果如下。 对于testd 0 - 2,相关代码为 和平方为双精度, ,

  • 问题内容: 在Objective-C中,我经常绕过块。我经常使用它们来实现有助于避免将内容存储到实例变量中的模式,从而避免线程/定时问题。 例如,我将它们分配给过孔,以便在动画结束时执行该块。(Objective-C可以将块视为对象;您也可以这样做和。) 但是,尝试在Swift和Objective-C中同时使用这些模式似乎很困难。( 编辑: 我们可以看到该语言仍在不断变化:已经对代码进行了修改,因

  • 在抽象工厂模式中,我使用泛型。我有一个扩展Serializable的BaseEntity接口,Employee类实现了BaseEntity。在抽象类中,我有一个getJavaObj方法 是一种方法,它接受并返回

  • 嗨,我最近看到了一个类似这样的问题 在我回答了这个问题后,事实证明我弄错了,我回答了整数。MIN_VALUE但正确的答案是整数。MAX_VALUE。经过进一步的测试,我意识到我对大于整数的int施加的任何双精度。MAX_VALUE只是使int等于整数。MAX_VALUE。例如 经过进一步的测试,我意识到如果你试图将long转换为int,似乎会将int分配给一个看似随机的数字。 所以我的问题是。到底