【问题标题】:Is dereferencing a pointer to a pointer to an int the same thing as dereferencing a pointer to a pointer to a char, in the C language?在 C 语言中,取消引用指向 int 的指针与取消引用指向 char 的指针的指针相同吗?
【发布时间】:2011-12-10 13:49:38
【问题描述】:

假设在这种情况下,您希望在取消引用指向指针的指针后存储地址。将其取消引用为:

    *(int **)(/* some void ptr */) = // some other address;

对

    *(char **)(/* same void ptr */) = // some other address;

因为我知道当你取消引用一个指向 int 的指针和一个指向 char 的指针时,它们是完全不同的东西!但是在处理指向指针的指针时,中间有一层,由于所有指针(在同一台机器上)的大小相同,我想知道这两种方法是否有任何区别

->edit:你甚至可以用 unsigned ptr ptr、long ptr ptr 和 void ptr ptr 替换它,得到同样的东西吗?

【问题讨论】:

  • 您唯一知道的是所有指针都可以转换为 void 指针。此外,您所做的是未定义的行为,除非您可以对“some void ptr”做出一些保证。

标签: c pointers


【解决方案1】:

您“所有指针(在同一台机器上)的大小相同”的假设是不正确的。对于您的特定机器来说,这很可能是正确的,并且在您可能使用的任何机器上也很可能是正确的,但是 C 标准没有做出这样的保证,并且在现实世界的机器中它不是真的。例如,在字寻址的机器上,int* 可能表示为字指针,但char* 或void* 可能需要额外的信息来指定它所指的字中的哪个字节。在某些架构上,函数指针与数据指针完全不同。

如果您发现自己在转换指针类型,则很可能是您的设计有问题,而指针一开始就应该是正确的类型。

当然,这并不总是正确的;在某些情况下,这种低级访问是适当且必要的,而 C 的一大优势是它允许您做这种事情。

但是如果没有更具体的例子,很难判断它是否合适。

拥有不同类型的意义不仅仅在于它们具有不同的大小或表示形式;关键是它们用于不同的目的。一个int* 指向一个int; char* 指向 char。

您的示例之间的区别在于一个引用int* 对象,另一个引用char* 对象。它们是不同的类型,并且它们不可互换,即使它们碰巧具有相同的大小和表示形式。您在作业右侧被注释掉的some other address 必须是某种实际表达,并且必须是某种类型。

你想完成什么?

【讨论】:

    【解决方案2】:

    您可以将指针转换为您想要的任何其他类型。在大多数现代实现中,指针类型与任何其他指针类型的大小相同,无论数据指向什么。

    但是,在类型正确性方面,C++ 比 C 更严格,因此如果您盲目地将一种类型的指针分配给另一种类型,您可能会看到“无效转换”错误。

    【讨论】:

    • 正如我在另一条评论和我的回答中所说,语言不能保证所有指针的大小都相同。
    • @KeithThompson:您能参考 C 标准中的某个部分吗?我找了,没找到。
    • 关键是标准中没有说指针是相同的大小。在没有这样的声明的情况下,没有要求符合实现以使它们具有相同的大小。并且 6.2.6.1p1 说“所有类型的表示都是未指定的,除非本子条款中另有说明。”。对于一个似是而非的场景,请参阅我的回答中对字寻址机器的讨论。
    【解决方案3】:

    是的,所有相同的大小 - 指针的大小,有趣的内存模型除外。是的,你会得到同样的东西。

    【讨论】:

    • 你怎么知道它们的大小一样?
    • 标准不能保证这一点——尽管通常情况下是这样,并且会放弃在一个不支持的平台上工作的想法。该标准仅保证 void* 能够表示除指向函数的指针之外的任何其他指针类型。
    • @dmckee:“消除这种想法”——为什么?只要您不编写假定所有指针大小相同的代码(并且很少需要这样做),这应该不是问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多