簡體   English   中英

C ++中的For循環函數參數奇數

[英]For loop over function parameters oddity in C++

在我當前的項目中,我偶然發現了一個奇怪的現象:嵌套的for循環只會執行一次內部循環,然后停止。 即使仔細檢查了所有涉及的變量,外部for循環仍會無故終止。 使此構造與程序中包含的其他for循環不同的唯一原因是,計數器變量作為參數傳遞給包含循環的函數,並且從未復制到任何地方。

因此,我決定測試該問題是否可以重現:

#include <stdio.h>

void someFunction(int x, int y, int width, int length)
{
    int endX = x+width;
    int endY = y+length;

    printf("x will not exceed: %i\n", endX);
    printf("y will not exceed: %i\n", endY);

    for(; x < endX; x++)
    {
        for(; y < endY; y++)
        {
            printf("(%i, %i)\n", x, y);
        }
    }
}

int main(int argc, const char *argv[])
{
    someFunction(1, 1, 5, 5);
    return 0;
}

但是,在執行時,應用程序的輸出與直觀期望有所不同:

x will not exceed: 6
y will not exceed: 6
(1, 1)
(1, 2)
(1, 3)
(1, 4)
(1, 5)

切換x和y時,其行為類似,但是y變量從不增加。 通過簡單地將一個新變量聲明為每個循環的計數器來解決該問題。

但是為什么會這樣呢? 是否出於特定原因而不允許使用? 編譯器是否禁用某些參數的修改,如果是,為什么它只能使用一個變量而不使用另一個變量?

提供的源代碼是使用GCC / G ++ 4.5.3編譯的,沒有任何特殊的優化標志。

y永遠不會在x循環中重置,因此,一旦它在第一次通過時超出范圍,便永遠不會超出范圍。

由於xy也存在於循環外部,並且由於循環未設置其初始值,因此即使重新使用它們也保留最后一個值。 特別是,這與您的y ,在y循環退出后不會回退到初始值。

為避免此類問題,請避免將循環外部的變量用作索引。

void someFunction(const int x, const int y, const int width, const int length)
{
    int endX = x+width;
    int endY = y+length;

    printf("x will not exceed: %i\n", endX);
    printf("y will not exceed: %i\n", endY);

    for(int ix=x; ix < endX; ++ix)
    {
        for(int iy=0; iy < endY; ++iy)
        {
            printf("(%i, %i)\n", ix, iy);
        }
    }
}

在這里,通過使參數為const,我們確保即使出現錯誤也無法觸摸它們。 然后,我們在循環中使用局部的ix和iy來處理迭代。

另外,除非由於某些其他原因必須避免,否則請避免使用后綴增量,而應使用前綴。 在使用整數之前,這並不是什么大改變,但是使用更復雜的變量可以有所作為。

如果您避免像C程序員那樣編寫代碼,那么這也是一個好主意(因為您將問題標記為C++而不是C )。

慣用的C ++等效項是這樣的:

#include <iostream>

void someFunction(const int& x, const int& y, const int& width, const int& length)
{
    const int endX = x+width;
    const int endY = y+length;

    std::cout << "x will not exceed: " << endX << std::endl;
    std::cout << "y will not exceed: " << endY << std::endl;

    for(int ix=x; ix < endX; ++ix)
    {
        for(int iy=y; iy < endY; ++iy)
        {
            std::cout << '('<<ix<<", "<<iy<<')'<< std::endl;    
        }
    }
}

int main()
{
    someFunction(1, 1, 5, 5);
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM