[英]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
循环中重置,因此,一旦它在第一次通过时超出范围,便永远不会超出范围。
由于x
和y
也存在于循环外部,并且由于循环未设置其初始值,因此即使重新使用它们也保留最后一个值。 特别是,这与您的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.