【发布时间】:2020-06-11 02:51:39
【问题描述】:
我在 edabit.com 上玩 C++ 挑战以刷新自己,我遇到了一个挑战,我需要编写一个函数,如果给定一个向量,如果所有偶数索引都是偶数并且所有奇数索引都是奇怪的。否则返回假。该功能的逻辑和一切都很好。我知道有几种方法可以做到这一点,但提出了一个(我认为)创造性的解决方案,而不是通过一个 for 循环来检查索引是奇数还是偶数,而是编写了两个递增的后续 for 循环每个。一个从 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 ?
【问题讨论】:
-
没有垃圾回收。有范围。无论您在
for中声明什么,都将保留在for中。就像拉斯维加斯 :) C 主要具有所谓的词法范围,而不是动态范围。这意味着您可以静态地确定变量的范围。也就是说:看源码就知道作用域,不需要运行程序就知道,而且作用域在运行时不会改变。重要区别:variables 的范围是词法的。由于动态内存分配,对象的范围可以是动态的。 -
规则在 C 标准中,但除非您花大量时间了解它的结构和用于描述 C 是什么的概念框架,否则该文档大多难以理解。词法作用域使事情变得简单:你看向外和向上。进入当前块直到它的开头,然后退出块,然后向上看封闭块,依此类推,直到你到达翻译单元的开头。在此搜索期间在匹配的命名空间中找到的第一个名称就是您的符号解析为的名称。
-
顺便说一句:
std::vector<int> arr ...arr[i] % 2 == 1在arr[i] < 0时永远不会为真。代码应该是arr[i] % 2 != 0.for 偶数/奇数测试。 -
@chux-ReinstateMonica 感谢关于
< 0的观点,我想我没有考虑过这一点,但挑战的规定是所有测试的输入都是>= 0