gpt4 book ai didi

c - 一个数组对象的最后一个元素的基本原理是什么?

转载 作者:太空狗 更新时间:2023-10-29 14:54:53 25 4
gpt4 key购买 nike

根据 N1570(C11 草案)6.5.6/8 加法运算符:

Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object

子条款 6.5.6/9 还包含:

Moreover, if the expression P points either to an element of an array object or one past the last element of an array object, and the expression Q points to the last element of the same array object, the expression ((Q)+1)-(P) has the same value as ((Q)-(P))+1 and as -((P)-((Q)+1)), and has the value zero if the expression P points one past the last element of the array object, even though the expression (Q)+1 does not point to an element of the array object.106)

这证明了这样的指针算法是有效的:

#include <stdio.h>

int main(void)
{
int a[3] = {0, 1, 2};
int *P, *Q;

P = a + 3; // one past the last element
Q = a + 2; // last element

printf("%td\n", ((Q)+1)-(P));
printf("%td\n", ((Q)-(P))+1);
printf("%td\n", -((P)-((Q)+1)));

return 0;
}

我希望禁止指向越界的数组元素,对于这种情况,取消引用充当未定义的行为(数组溢出),因此它具有潜在的危险。这有什么道理吗?

最佳答案

将要循环的范围指定为 half-closed interval [start, end),特别是对于数组索引,具有某些令人愉悦的特性,正如 Dijkstra 在 one of his notes 中观察到的那样.

1) 您可以将范围的大小计算为 end - start 的简单函数。特别是,如果根据数组索引指定范围,则循环执行的迭代次数将由 end - start 给出。如果范围是 [start, end],那么迭代次数将是 end - start + 1 - 很烦人,不是吗? :)

2) Dijsktra 的第二个观察仅适用于(非负)整数索引的情况 - 将范围指定为 [start, end)(start, end] 两者都具有 1) 中提到的属性。但是,将其指定为 (start, end] 需要您允许 -1 的索引来表示包括索引 0 的循环范围 -您允许 -1 的“不自然”值只是为了表示范围。[start, end) 约定没有这个问题,因为 end 是一个非负整数,因此是处理数组索引时的自然选择。

Dijsktra 反对允许 -1 确实与允许超过容器的最后一个有效地址有相似之处。然而,由于上述约定已经使用了很长时间,它很可能说服了标准委员会做出这一异常(exception)。

关于c - 一个数组对象的最后一个元素的基本原理是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27472531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com