C 中有效指针操作的问题

Problems with valid pointers operations in C

在K&R中说有效的指针运算是同类型指针的赋值,同一个数组的加减运算......所有其他的指针运算都是非法的。

但是,当我在维基百科上阅读双向链表的代码时,它比较两个指向链表不同节点的指针。这让我很困惑。 这是代码

    unsigned int DetectCycleinList(void)
    {
        DoublLinkedList* pCurrent = pHead;
        DoublLinkedList* pFast = pCurrent;
        unsigned int cycle = FALSE;
        while ((cycle == false) && pCurrent->pNext != NULL)
        {
            if (!(pFast = pFast->pNext))
            {
                cycle = false;
                break;
            }
            else if (pFast == pCurrent)
            {
                cycle = true;
                break;
            }
            else if (!(pFast = pFast->pNext))
            {
                cycle = false;
                break;
            }
            else if (pFast == pCurrent)
            {
                cycle = true;
                break;
            }
            pCurrent = pCurrent->pNext;
        }
    }

比较pFast和pCurrent,是不是违法了

根据N1570,没有限制要比较的两个指针必须指向同一数组中的元素。 pFastpCurrent指向的是同一类型的对象,所以比较是合法的。

引自 N1570 6.5.9 等式运算符:

Constraints

2 One of the following shall hold:
— both operands have arithmetic type;
— both operands are pointers to qualified or unqualified versions of compatible types;
— one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void; or
— one operand is a pointer and the other is a null pointer constant.

[...]

6 Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.

两个指针之间可能会发生比较。例如,如果要检查指针 p 是否指向数组的第一个元素 a:

if (p == a)
    /* a points to the start of a */

但是,指针运算受到更多限制。