必须将int声明为第二个for循环

问题描述 投票:0回答:3

我在edabit.com C ++挑战中玩耍以刷新自我,我面临一个挑战,在这个挑战中,我需要编写一个函数,给定一个向量,如果所有偶数索引均为偶数且所有奇数索引均为奇数,则返回true 。否则返回false。逻辑和功能的一切都很好。我知道有几种方法可以做到这一点,但是想出了一个(我认为)创造性的解决方案,而不是通过检查索引是否为奇数或偶数来运行一个for循环,而是编写了两个后续的for循环,这些循环以2为增量每。一个从0开始,另一个从1开始。一旦发现不匹配,则返回false。否则最后它将返回true。我来自JavaScript,您无需重新声明索引变量(如果使用var而不是let),但是此代码无法编译:

bool isSpecialArray(std::vector<int> arr) {
    for(int i = 0; i < arr.size(); i = i + 2){
        if(arr[i] % 2 == 1){
            return false;
        }
    }

    for(i = 1; i < arr.size(); i = i + 2){
        if(arr[i] % 2 == 0){
            return false;
        }
    }

    return true;
}

状态:

error: use of undeclared identifier 'i'
        for(i = 1; i < arr.size(); i = i + 2){
            ^

当然,在第二个for循环中声明int可以清除错误,并按预期执行程序。我猜这是由于垃圾回收造成的,但是标准中是否有特定的规则来定义这一点?还是这可能是每个编译器的事情?我对垃圾回收的理解是,一旦声明的变量就不会从内存中清除,直到在定义它的当前函数中不再使用为止。由于for循环的范围,这是否有所不同,类似于JavaScript的let

c++ variable-declaration
3个回答
1
投票
C中没有垃圾回收,即使有,也无法解释您的错误。实际原因很简单:声明为for循环一部分的变量在循环后超出范围。

0
投票
首先,JS和C ++具有非常不同的范围模型,并且JS因其不良做法而闻名(对不起)。在C ++中,规则更加一致:只要程序退出作用域,该变量就会被销毁。这意味着在这段代码中:

for (int i = 0; ; ) { }

变量i仅为此作用域定义,不能在另一个(非嵌套)循环中重用,在其他地方看不到,并且名称可以在内部作用域中重用或重新定义。这给您带来的好处是,控制数据缺陷和减少副作用更加容易。因此,您的解决方案是在第二个循环中声明另一个变量i

for(int i = 1; i < arr.size(); i = i + 2){ if(arr[i] % 2 == 0){ return false; } }

只要您来自JS世界,我就会给您更多建议。首先,不要按值传递向量(除非您意识到自己在做什么)。通过引用传递它,或者通过const引用传递更好:

bool isSpecialArray(const std::vector<int> &arr) { // ... }

接下来,增加索引的一种可能更有效,更惯用的方法是i += 2

以及最后的观察:您的解决方案中没有“创造力”,但是有缺点。此代码对缓存的友好程度降低了,这可能被认为是不好的做法。


0
投票
c ++没有垃圾回收。相反,它确实对对象(例如i)进行确定性销毁。编译器执行此操作的方法是,一旦对象的作用域结束,便清理该对象,然后再不允许您使用该对象。

int main() { { int i; } // scope of i ends cout << i; // error, can't access i here }

for循环具有自己的范围,因此在您的示例中,第一个循环中的i在第二个循环中不可访问。    
© www.soinside.com 2019 - 2024. All rights reserved.