C++ 代码在 for 循环的条件下给出 运行-time 错误,而如果它被具有相同意义的代码替换,则编译正确
C++ code is giving a run-time error in the condition of for loop Whereas it is compiling correctly if it is replaced by code which makes same sense
#include<bits/stdc++.h>
using namespace std;
int main() {
vector<int> luck;
int k = 10;
int sum = 0;
for(int i = 0; i<5; i++) luck.push_back(i);
for(int i = 0; i<luck.size() - k; i++) sum+=luck[i]; //RUNTIME ERROR
cout<<endl<<sum;
return 0;
}
wheareas 如果我添加
它会给出正确的输出
int boundary = luck.size() - k;
并将第二个'for'循环的条件替换为
i<boundary;
这里是完整无误的代码,再次:
#include<bits/stdc++.h>
using namespace std;
int main() {
vector<int> luck;
int k = 10;
int sum = 0;
for(int i = 0; i<5; i++) luck.push_back(i);
int boundary = luck.size() - k; // HERE
for(int i = 0; i<boundary; i++) sum+=luck[i]; //CONDITION CHANGE
cout<<endl<<sum;
return 0;
}
您在 for 循环中混用了无符号和有符号。使代码工作的另一种方法是更改:
for(int i = 0; i<luck.size() - k; i++) sum+=luck[i]; //RUNTIME ERROR
至:
for(int i = 0; i < int(luck.size() - k); i++) sum+=luck[i];
解释:
luck.size() returns 无符号整数值 (std::vector::size_type)。当您从中减去 k 时,它仍被视为无符号整数。因为在你的情况下 k > luck.size(),结果是否定的。当你给无符号整数赋负值时,你会得到一个巨大的正数,所以循环不会正确停止。
在第二种情况下,赋值(对有符号整数)将 rhs 表达式视为有符号且代码按预期工作。
正如 DeiDei 所说,这是有符号和无符号整数不幸混合的结果。
请注意,std::vector::size()
returns size_t
。
取决于平台,这通常是 32 位或 64 位 unsigned
。 (size_t
的位数与 void*
相同。)
在第一个示例中:
for(int i = 0; i<luck.size() - k; i++) sum+=luck[i]; //RUNTIME ERROR
出现以下值:
luck.size()
: (size_t)5
k
: (int)10
luck.size() - k
: (size_t)0xFFFFFFFFFFFFFFFFB(假设 64 位大小)
i < luck.size() - k
的比较也将i
提升为size_t
。因此,迭代不会在 5 处停止。因此,在第一个示例代码中,您在循环中获得了越界访问。
在第二个样本中:
int boundary = luck.size() - k; // HERE
for(int i = 0; i<boundary; i++) sum+=luck[i]; //CONDITION CHANGE
该值再次转换为 int
。
int boundary = luck.size() - k;
: (int)-5
这导致没有循环迭代。
演示:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> luck;
int k = 10;
int sum = 0;
for(int i = 0; i<5; i++) luck.push_back(i);
// trying 2nd version:
std::cout << "2nd version:\n";
int boundary = luck.size() - k; // HERE
for(int i = 0; i<boundary; i++) {
std::cout << "i: " << i << '\n';
sum+=luck[i]; //CONDITION CHANGE
}
std::cout << "sum: " << sum << std::endl;
// trying 1st version
std::cout << "1st version:\n";
sum = 0;
for(int i = 0; i<luck.size() - k; i++) {
std::cout << "i: " << i << '\n';
sum+=luck[i]; //RUNTIME ERROR
}
std::cout << "sum: " << sum << std::endl;
// done
return 0;
}
输出:
2nd version:
sum: 0
1st version:
i: 0
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9
i:
注:
sum
的输出没有发生。该应用程序会在没有进一步通知的情况下直接终止。这是一种未定义的行为可能表现出来的方式。分段错误是另一个。
#include<bits/stdc++.h>
using namespace std;
int main() {
vector<int> luck;
int k = 10;
int sum = 0;
for(int i = 0; i<5; i++) luck.push_back(i);
for(int i = 0; i<luck.size() - k; i++) sum+=luck[i]; //RUNTIME ERROR
cout<<endl<<sum;
return 0;
}
wheareas 如果我添加
它会给出正确的输出int boundary = luck.size() - k;
并将第二个'for'循环的条件替换为
i<boundary;
这里是完整无误的代码,再次:
#include<bits/stdc++.h>
using namespace std;
int main() {
vector<int> luck;
int k = 10;
int sum = 0;
for(int i = 0; i<5; i++) luck.push_back(i);
int boundary = luck.size() - k; // HERE
for(int i = 0; i<boundary; i++) sum+=luck[i]; //CONDITION CHANGE
cout<<endl<<sum;
return 0;
}
您在 for 循环中混用了无符号和有符号。使代码工作的另一种方法是更改:
for(int i = 0; i<luck.size() - k; i++) sum+=luck[i]; //RUNTIME ERROR
至:
for(int i = 0; i < int(luck.size() - k); i++) sum+=luck[i];
解释:
luck.size() returns 无符号整数值 (std::vector::size_type)。当您从中减去 k 时,它仍被视为无符号整数。因为在你的情况下 k > luck.size(),结果是否定的。当你给无符号整数赋负值时,你会得到一个巨大的正数,所以循环不会正确停止。
在第二种情况下,赋值(对有符号整数)将 rhs 表达式视为有符号且代码按预期工作。
正如 DeiDei 所说,这是有符号和无符号整数不幸混合的结果。
请注意,std::vector::size()
returns size_t
。
取决于平台,这通常是 32 位或 64 位 unsigned
。 (size_t
的位数与 void*
相同。)
在第一个示例中:
for(int i = 0; i<luck.size() - k; i++) sum+=luck[i]; //RUNTIME ERROR
出现以下值:
luck.size()
: (size_t)5
k
: (int)10
luck.size() - k
: (size_t)0xFFFFFFFFFFFFFFFFB(假设 64 位大小)
i < luck.size() - k
的比较也将i
提升为size_t
。因此,迭代不会在 5 处停止。因此,在第一个示例代码中,您在循环中获得了越界访问。
在第二个样本中:
int boundary = luck.size() - k; // HERE
for(int i = 0; i<boundary; i++) sum+=luck[i]; //CONDITION CHANGE
该值再次转换为 int
。
int boundary = luck.size() - k;
: (int)-5
这导致没有循环迭代。
演示:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> luck;
int k = 10;
int sum = 0;
for(int i = 0; i<5; i++) luck.push_back(i);
// trying 2nd version:
std::cout << "2nd version:\n";
int boundary = luck.size() - k; // HERE
for(int i = 0; i<boundary; i++) {
std::cout << "i: " << i << '\n';
sum+=luck[i]; //CONDITION CHANGE
}
std::cout << "sum: " << sum << std::endl;
// trying 1st version
std::cout << "1st version:\n";
sum = 0;
for(int i = 0; i<luck.size() - k; i++) {
std::cout << "i: " << i << '\n';
sum+=luck[i]; //RUNTIME ERROR
}
std::cout << "sum: " << sum << std::endl;
// done
return 0;
}
输出:
2nd version:
sum: 0
1st version:
i: 0
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9
i:
注:
sum
的输出没有发生。该应用程序会在没有进一步通知的情况下直接终止。这是一种未定义的行为可能表现出来的方式。分段错误是另一个。