在 for 循环定义中递增与在 for 循环内部递增时 C++ 指针行为的差异

Difference in a C++ pointer behavior when incremented in the for loop definition vs inside for loop

我正在研究 leetcode problem(用于链表的 Floyd 循环检测算法),其中我注意到指针状态的奇怪行为。 当我在 for 循环内更改指针状态时,程序正确执行(指针状态移动到正确的状态):

ListNode *detectCycle(ListNode *head) {
        
        if(!head or !head->next)
            return nullptr;
        
        ListNode *slow, *fast;
        
        for(slow = head, fast = head; fast && fast->next;)
        {
            slow = slow->next, fast = fast->next->next; // This hops the pointers correctly

            if(slow == fast)
            {
                slow = head;
                while(slow != fast)
                {
                    slow = slow->next;
                    fast = fast->next;
                }
                return slow;
            }
        }
        return nullptr;
    }

但是当我在 for 循环定义中声明更改 slow & fast 时,状态更改是错误的,程序没有给出正确的输出。

ListNode *detectCycle(ListNode *head) {
        
        if(!head or !head->next)
            return nullptr;
        
        ListNode* slow, *fast;
        
        for(slow = head, fast = head; fast && fast->next; slow = slow->next, fast=fast->next->next) // Pointers dont hop correctly
        {
            if(slow == fast)
            {
                slow = head;
                while(slow != fast)
                {
                    slow = slow->next;
                    fast = fast->next;
                }
                return slow;
            }
        }
        return nullptr;
    }

我不知道是什么原因造成的。在我看来,递增 for 循环定义中的指针与立即递增 for 循环中的指针应该是一回事。有人可以深入了解为什么在循环内递增指针与在 for 循环签名中递增指针会导致不同的行为吗?

一个

for (init-statement; condition; iteration-expression)
{
    dostuff();
}

映射到

{
    init-statement
    while ( condition ) 
    {
        dostuff();
        iteration-expression ;
    }
}

所以我们得到

{
    slow = head, fast = head;
    while (fast && fast->next)
    {
        slow = slow->next, fast = fast->next->next; 
        dostuff(); // for example purposes only. Not really replacible with a function 
    }
}

{
    slow = head, fast = head;
    while (fast && fast->next)
    {
        dostuff();
        slow = slow->next, fast=fast->next->next;
     }
}

首先,slowfast 总是在 dostuff() 之前更新。

第二个,dostuff发生在slowfast更新之前,所以slowfast的值在[=17中使用=] 在第一次循环迭代时会有所不同。