我引用了Kernighan&amp ;;的“C编程语言”。里奇:
任何指针都可以有意义地比较等于或不等于零。但是对于算术或与不指向同一数组成员的指针进行比较的行为是未定义的。 (有一个例外:超过数组末尾的第一个元素的地址可用于指针算法。)
这是否意味着我不能依赖==
来检查不同指针的相等性?这种比较会导致错误结果的情况是什么?
答案 0 :(得分:33)
我想到的一个例子是哈佛架构,它为代码和数据提供了单独的地址空间。在该体系结构的计算机中,编译器可以将常量数据存储在代码存储器中。由于两个地址空间是分开的,因此指向代码存储器中地址的指针可以在数字上等于数据存储器中的指针,而不指向相同的地址。
答案 1 :(得分:8)
为所有有效指针定义了相等运算符,并且它唯一可以给出“误报”的是当一个指针指向一个元素超过数组末尾时,另一个指针恰好指向(或指向结构定义的优点)另一个对象存储在内存中的数组之后。
我认为你的错误是将K& R视为规范性的。请参阅相等运算符的C99标准(此处的html版本:http://port70.net/~nsz/c/c99/n1256.html),6.5.9。关于比较未定义的问题仅适用于关系运算符(见6.5.8):
当比较两个指针时,结果取决于指向的对象的地址空间中的相对位置。如果指向对象或不完整类型的两个指针都指向同一个对象,或者两个指针都指向同一个数组对象的最后一个元素,则它们相等。如果指向的对象是同一聚合对象的成员,则指向稍后声明的结构成员的指针比指向结构中先前声明的成员的指针大,指向具有较大下标值的数组元素的指针比指向同一数组的元素的指针大。具有较低的下标值。指向同一个union对象的成员的所有指针都比较相等。如果表达式P指向数组对象的元素,并且表达式Q指向同一数组对象的最后一个元素,则指针表达式Q + 1比较大于P.在所有其他情况下,行为未定义。
答案 2 :(得分:2)
我将此解释如下:
short a[9];
int b[12];
short * c = a + 9;
这里说
是有效的c > a
因为c
来自a
通过指针算法
但不一定
b == c
或
c <= b
或类似的东西,因为它们来自不同的数组,其内存中的顺序和对齐未定义。
答案 3 :(得分:0)
您无法使用指针比较来比较指向不同数组的指针。
所以:
int arr[5] = {1, 2, 3, 4, 5};
int * p = &arr[0];
int anotherarr[] = {1, 2};
int * pf = &anotherarr[0];
由于if (p == pf)
和p
未指向相同的数组,因此您无法执行pf
。这将导致未定义的行为。
如果它们指向同一个数组,你可以依赖指针比较。
我自己不确定算术案例。
答案 4 :(得分:-2)
您可以使用来自不同阵列的指针执行==
和!=
。
&lt;,&lt; =,&gt;,&gt; =未定义。