0
int a=40,b=34;
int *iptr1,*iptr2;                        
iptr1 = &a;
iptr2 = &b;        
printf("\n Equal condition of two pointers=%d", (ip1 == ip2));    //no error 

char name1[20], name2[20];
char *p1 = name1;
char *p2 = name2;
if(p1 > p2) /*Error*/ 

为什么关系操作有错误/警告但比较操作没有?

4

2 回答 2

3

您只能对来自同一数组或同一聚合对象的指针执行关系操作<><=、 )。>=否则,它会导致未定义的行为

引用C11,第 6.5.8 章,关系运算符,第 5 段

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

在您的代码中,

  if(p1>p2)

尝试比较两个指针,它们既不是同一个数组对象的一部分,也不是同一个聚合对象的成员。因此,它触发了警告。

然而,为了比较,没有这样的约束,所以像这样的表达式(ip1==ip2)是完全可以的。

于 2017-08-29T15:15:58.997 回答
1

您可以将指针与指向不同对象或不同数组元素的相等运算符(==或)进行比较。!=如果指针不指向同一个对象,那么它们被认为是不相等的。

更准确地说(C 标准,6.5.9 等式运算符)

6 两个指针比较相等当且仅当两者都是空指针,并且都是指向同一个对象(包括指向对象的指针和在其开头的子对象)或函数的指针,两者都是指向同一对象最后一个元素之后的指针数组对象,或者一个是指向一个数组对象末尾的指针,另一个是指向另一个数组对象的开头的指针,该数组对象恰好紧随地址空间中的第一个数组对象。

考虑以下示例。

#include <stdio.h>

int main(void) 
{
    struct A
    {
        int x;
        int y;
    } a;

    printf( "&a.x + 1 == &a.y is %d\n", &a.x + 1 == &a.y );

    return 0;
}

x如果数据成员和结构之间没有填充,y则输出将等于,1因为每个数据成员都可以被视为具有一个元素的数组,并且“数组”y紧跟在“数组”之后x

但是,您不能将指针与不指向同一数组的元素或不超过同一数组末尾的关系运算符 ( <, >, <=, ) 进行比较。>=

于 2017-08-29T15:56:03.650 回答