【问题标题】:pointer comparisons "<" with one past the last element of an array object指针将“<”与数组对象的最后一个元素进行比较
【发布时间】:2013-04-26 10:07:19
【问题描述】:

我知道只有当指针指向相同的内存空间(如数组)时,C 标准才允许与 &lt; 进行指针比较。

如果我们取一个数组:

int array[10];
int *ptr = &array[0];

是否允许将 ptrarray+10 进行比较? array+10指针是否考虑在数组内存之外,所以不允许比较?

例子

for(ptr=&array[0]; ptr<(array+10); ptr++) {...}

【问题讨论】:

    标签: c++ c pointers comparison


    【解决方案1】:

    是的,允许指针指向刚刚超过数组末尾的位置。但是,您不能尊重这样的指针。

    C99 6.5.6/8 加法运算符(已添加重点)

    如果表达式 P 指向数组对象的最后一个元素,则 表达式 (P)+1 指向数组对象的最后一个元素, 如果表达式 Q 指向数组的最后一个元素 对象,表达式 (Q)-1 指向数组的最后一个元素 目的。如果指针操作数和结果都指向元素 相同的数组对象,或数组的最后一个元素 对象,评估不会产生溢出;否则, 行为未定义。如果结果指向最后一个元素 数组对象的,它不应用作一元的操作数 * 被评估的运算符。

    而且,专门针对指针的比较操作:

    C99 6.5.8/5 关系运算符

    如果表达式 P 指向一个数组对象的元素并且 表达式 Q 指向同一个数组对象的最后一个元素, 指针表达式 Q+1 比较大于 P。在所有其他情况下, 行为未定义。

    【讨论】:

    • one post the first element的情况是否相同?
    • @MOHAMED 你的意思是 before 第一个元素?不,这是严格禁止的:)
    • @jalf 是的,我的意思是在第一个元素之前。谢谢你的回答。有一些标准证明吗?一些 SO 链接?
    • @MOHAMED 阅读这个答案。上面来自 6.5.6/8 的引用说明了你需要知道的一切。如果操作数和结果未指向数组或最后一个元素之后,则评估未定义。换句话说,一个before元素的开始是未定义的。
    【解决方案2】:

    是的,这是允许的,并且 C++ 严重依赖它(C 并没有那么多使用它,但在 C++ 中,表示范围的一种非常常见的方式是使用指针(或更一般地,迭代器)指向第一个元素,另一个指向过去范围的末尾。

    这样一个指针的存在是合法的,并将它与数组的其余部分进行比较。

    但是取消引用指针是不合法的。

    【讨论】:

    • 你知道为什么只有当指针指向同一个数组时才允许比较指针......对我来说似乎很奇怪......如果我有一堆对象,我想把它们放在 std: :map where key 是他们的地址?(我希望他们订购,但我不在乎如何,所以我使用他们的地址)
    • std::map 通过使用std::less 作为默认比较器来解决这个问题。它与&lt; 基本相同,除了它保证适用于指向不同数组/对象的指针。 :)
    • 至于为什么存在这个限制,我相信是为了支持非线性内存系统,比如(但不限于)有分段内存的老系统,以及在哪里任意指针之间的“小于”比较可能没有意义,或者计算成本更高。所以你有std::less 用于“我想要订购,我不在乎哪个,或者它有多贵”的情况,而&lt; 做简单的事情,但只能保证在一个单一的范围内工作分配。
    • 哇,真的很棒的洞察力,关于std少,我从来没有想过它......我认为它只是一个很好的通用名称
    • @NoSenseEtAl 在实践中,它通常只是 &lt; 的愚蠢包装。但关键是 如果 您正在为一些奇怪的架构进行编译,其中需要更复杂的计算来保证一致的顺序,那么std::less 提供了一个放置它的地方。但是是的,通常它只是直接调用&lt;。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 2018-08-04
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    相关资源
    最近更新 更多