【问题标题】:Difference in a C++ pointer behavior when incremented in the for loop definition vs inside for loop在 for 循环定义与内部 for 循环中递增时 C++ 指针行为的差异
【发布时间】:2022-01-19 20:02:30
【问题描述】:

我正在使用leetcode problem(链表的弗洛伊德循环检测算法),其中我注意到指针状态的奇怪行为。 当我在 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 循环签名中增加指针会导致不同的行为吗?

【问题讨论】:

  • 看看这里:godbolt.org/z/PTYeTn1s8
  • slow = slow->next, fast=fast->next->next 放入for 循环中的iteration-expression 与放入循环体中的最后一行相同-因此与把它放在循环体的前面。
  • 在执行if (slow == fast) 语句之前,您的第一个样本总是“跳跃”fastslow。执行if (slow == fast) 语句之后的第二个“跳跃”。由于if (slow == fast) 语句的主体更改了slowfast,这会导致您的代码示例表现不同。
  • 为了清楚起见,使用括号!你的意思是(slow = slow->next), (fast = fast->next->next); 还是slow = (slow->next, fast = fast->next->next);?事实上,在循环体中,最好使用两个单独的语句,而不是逗号操作符。

标签: c++ for-loop pointers


【解决方案1】:

一个

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 更新之前,因此 dostuff 中使用的 slowfast 的值在第一次循环迭代中会有所不同。

【讨论】:

    猜你喜欢
    • 2019-01-17
    • 2015-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 2010-11-13
    • 1970-01-01
    相关资源
    最近更新 更多