【问题标题】:What are the restrictions in comparing two pointers?比较两个指针有什么限制?
【发布时间】:2018-02-07 02:48:08
【问题描述】:
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*/ 

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

【问题讨论】:

  • 错误信息是什么。什么编译器?
  • char name1[20],name2[20];`末尾有一个流浪的`
  • ..我以为那是显示器上的一粒灰尘:(
  • 是的..请发布您测试的代码。复制/粘贴,不要输入。很容易打错字,例如。会阻止编译的无关字符。
  • 另外,发布您测试的所有代码,即。一个MCVE。非 MCVE 加上拼写错误给人的印象是您只是输入了印刷作品中的代码,而根本没有实际尝试过。

标签: c pointers compiler-errors equals-operator relational-operators


【解决方案1】:

您只能对来自同一数组或同一聚合对象的指针执行关系运算<><=>=)。否则会导致undefined behavior

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

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

在您的代码中,

  if(p1>p2)

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

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

【讨论】:

    【解决方案2】:

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

    更准确地说(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;
    }
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-16
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      • 2013-07-05
      • 2017-01-19
      相关资源
      最近更新 更多