C++在循环中重新定义一个变量吗?

7
当在C++中的循环内声明一个变量时,C++会在每次迭代中重新创建该变量吗?我的意思是,它是否会为另一个num变量重新分配内存?所以如果循环迭代5次,你会得到5个具有自己独特值的单独的num变量吗?即使该变量仅在循环内部使用,声明变量在循环开始之前是否更好呢?例如,如果我想将变量用作计数器或占位符怎么办?
// is this better code?
// int num;
for (int i = 0; i < 5; i++) {
  int num;
  // do stuff with num
}
4个回答

9

是的,如果num在循环内部定义,那么它将在每次循环运行时表示不同的变量。每次控制流经过其定义时,它将被重新初始化(如果有必要),并且每次循环迭代结束时,它都会被销毁。

变量应该尽可能在最狭窄的范围内声明。因此,如果num不需要保留其值从一次迭代到下一次迭代,通常应在循环内部定义。如果需要保留其值从一次迭代到下一次迭代,必须在循环外部定义。

当初始化比较昂贵时,有一些例外情况,可以违反这个最佳实践。


6
编译器可能会优化内存使用,使得变量只会被物理分配一次并在每次循环迭代中重新使用。但是,通常情况下,作用域规则要求每个循环迭代操作一个不同的变量实例。对于类/结构等复杂类型,在每次循环迭代中都需要调用构造函数和析构函数来处理变量。

4

这是一个新变量。你可以通过它能够编译成功来自己验证。

for (int i = 0; i < 5; i++) {
  const int num = i;
  // do stuff with num
}

如果它确实是同一个变量,我们如何将新内容分配给常量变量呢?

至于是否更有效率,你应该记住C++有一个非常好的优化编译器。堆栈变量没有真正的“成本”。一个简单的整数赋值显然没有任何副作用,所以编译器可以轻松地重用同一空间。如果你在循环外不需要该变量,最好在循环内部声明它。

我建议使用https://gcc.godbolt.org/查看一些小函数的汇编代码生成情况,有无优化,这将让你了解编译器可以轻松优化掉哪些内容。


2
在你所描述的情况下,C++标准规定变量的新实例将在循环开始时构造,并在循环结束时销毁。
实际发生的事情与此无关。C++允许以任何方式实现这一点,只要可观察到的结果符合C++标准的规定即可。
在这里,你只是有一个普通的int。虽然它按照我所描述的那样被正式构造和销毁,但在变量被构造和销毁时实际上并没有发生任何实质性的事情。C++不要求在本地范围内新构建的int必须初始化为任何特定的值。因此,在这种情况下,典型的C++实现将简单地将这个int分配给某个内存空间,并在每个循环迭代中重复使用它。
但是,如果用一个更详细的对象替换这个int,该对象具有正式的构造函数,你将看到对象的构造函数将在每个循环迭代的开始处被调用,并且对象的析构函数将在循环迭代的结束处(或者执行线程离开循环范围时)被调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接