C ==用于指针比较

C ==用于指针比较,c,pointers,comparison,equality,C,Pointers,Comparison,Equality,我引用Kernighan&Ritchie的“C编程语言”: 任何指针都可以与零进行有意义的相等或不相等比较。但是,对于算术或与不指向同一数组成员的指针的比较,行为是未定义的。(有一个例外:超过数组末尾的第一个元素的地址可以用于指针算术。) 这是否意味着我不能依靠==检查不同指针的相等性?在什么情况下,这种比较会导致错误的结果?不能使用指针比较来比较指向不同数组的指针 因此: intarr[5]={1,2,3,4,5} int*p=&arr[0] int-anotherarr[]={1,2} in

我引用Kernighan&Ritchie的“C编程语言”:

任何指针都可以与零进行有意义的相等或不相等比较。但是,对于算术或与不指向同一数组成员的指针的比较,行为是未定义的。(有一个例外:超过数组末尾的第一个元素的地址可以用于指针算术。)


这是否意味着我不能依靠
==
检查不同指针的相等性?在什么情况下,这种比较会导致错误的结果?

不能使用指针比较来比较指向不同数组的指针

因此:

intarr[5]={1,2,3,4,5}

int*p=&arr[0]

int-anotherarr[]={1,2}

int*pf=&anotherarr[0]

如果(p==pf)
不能执行
,因为
p
pf
不指向同一数组。这将导致未定义的行为

如果指针指向同一数组,则可以使用指针比较


我自己也不确定这个算术案例。

我解释如下:

short a[9];
int b[12];
short * c = a + 9;
在这里,这样说是有道理的

c > a
因为
c
是通过指针算法从
a
得到的

但不一定如此

b == c


c等式运算符是为所有有效指针定义的,它唯一能给出“假阳性”的时间是当一个指针指向一个超过数组末尾的元素,而另一个指针恰好指向(或通过结构定义指向)存储在内存中刚好超过数组的另一个对象时

我认为你的错误是将K&R视为规范。请参阅equality操作符上的C99标准(此处为尼斯html版本:),6.5.9。未定义比较的问题仅适用于关系运算符(见6.5.8):

比较两个指针时,结果取决于指向的对象在地址空间中的相对位置。如果指向对象的两个指针或不完整类型都指向同一对象,或者都指向同一数组对象的最后一个元素,则它们的比较相等。如果指向的对象是同一聚合对象的成员,则指向稍后声明的结构成员的指针比指向结构中较早声明的成员的指针大,指向具有较大下标值的数组元素的指针比指向具有较低下标值的同一数组元素的指针大。指向同一联合对象成员的所有指针比较相等。如果表达式P指向数组对象的一个元素,而表达式Q指向同一数组对象的最后一个元素,则指针表达式Q+1比P大。在所有其他情况下,行为都未定义


我想到的一个例子是哈佛体系结构,它为代码和数据提供了单独的地址空间。在这种体系结构的计算机中,编译器可以在代码内存中存储常量数据。由于这两个地址空间是分开的,因此指向代码内存中地址的指针在数字上可以等于数据内存中的指针,而不必指向同一地址。

您可以执行
=
=使用来自不同数组的指针


=未定义。

如果您有不同类型的指针,并且它们具有相同的值,则它们指向相同的内存地址,您可能会遇到一些问题。但是无论如何,如果绝对肯定内存布局是完全线性的,那么比较指针通常是可以的。否则,没有。想想8086。请注意,ISO/IEC 9899:1990在比较函数指针和对象指针时没有指定结果。-1您声明“为所有有效指针定义了相等运算符”,然后引用标准中与此相反的部分(注意,如果它们都指向同一个对象,则等式计算结果为true;如果它们指向不同的对象,则等式计算结果不为false).1:引用规范的第一个答案。丹尼,我想你有点困惑了:引用的段落是关于关系比较,而不是相等比较。相等运算符的部分说:“两个指针比较相等,当且仅当……都是指向同一对象的指针……”。这应该是公认的答案。@BlueRaja DannyPflughoeft:我引用的文本是关于运算符而不是相等运算符的,我引用它作为误解的可能来源。相等运算符不承认误报,除非我已经介绍了一个案例。这个答案可以改为“在不符合ISO C标准的C编译器中。"这个答案与C无关,因为对象指针和函数指针不可直接比较,而且它们之间的转换也没有定义。如果没有特定于实现的技巧,就没有有意义的方法将函数指针与对象指针进行比较。正如chazomaticus指出的那样,对于哈佛建筑师来说,编译器是不可能的在代码段中存储数据的体系结构。@R..90年代初,我使用一个C编译器,可以将常量放入代码内存中。我不记得它是否需要编译器扩展或仅仅声明一个常量数组就可以了,但我记得我能够得到一个
char*
const char*
指向t的字符o不同类型的内存。还有一种特殊的指针,可以让您在运行时指向一种或另一种内存,但它需要三个字节,而不是通常的两个字节。这是很久以前的事了,标准最多是C89。那不是C编译器。C允许
const char*
指向非常量数据(这是正常用法,甚至有一个隐式转换),还允许
char*
指向常量数据,只要它不用于修改该数据。指针的类型为
c <= b