我认为这是一个非常基本的问题,但我无法弄清楚。
我习惯于在C ++中使用数组,但我现在开始学习矢量。 我正在制作测试代码,我遇到了一个问题。
首先,这是我制作的代码:
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int main(){
vector<double> score(10);
for(vector<double>::size_type i=0;i<20;i++) {
cout<<"Enter marks for student #"<<i+1<<":"<<flush;
cin>>score[i];
}
double total = accumulate(score.begin(), score.end(),0);
cout<<"Total score:"<<total<<endl<<"Average score:"<<total/score.size()<<flush;
return 0;
}
在第9行的for
句中,我将i
声明为 vector<double>::size_type
类型(因为我被告知要这样做)。
我用上面描述的类型替换为 int
来测试代码,它运行得非常好。
为什么 vector<double>::size_type
与 int
相比更受欢迎?
答案 0 :(得分:25)
size_type
保证足够大,以支持最大的矢量大小vector::max_size()
。 int
不是:在许多常见平台上,int
有32位,而max_size()
远大于2 31 。
如果你知道大小是(并且将永远是)一个像20这样的小数字,那么你就可以使用int
或任何其他整数类型而不是size_type
。如果您要更改程序,例如从输入中读取大小,那么如果该值大于INT_MAX
则会出现严重错误;在使用size_type
时,它会继续适用于max_size()
之前的任何值,您可以轻松地对其进行测试。
答案 1 :(得分:7)
嵌入类型vector<double>::size_type
与各种vector
方法的返回值相关,例如.size()
,因此在这种情况下首选使用匹配类型(int = 0
通常会导致标志不匹配警告)。 E.g。
for (vector<double>::size_type i = 0; i < score.size(); ++i) { // types match
// ...
}
for (int i = 0; i < score.size(); ++i) { // types mismatch
// ...
}
std::vector::size_type
必须足够大,以表示容器中可包含的最大元素数,在本例中为vector<double>::max_size()
。通常,它会映射到size_t
。
在您的情况下,没有明确的理由使用vector<double>::size_type
(尽管从技术角度来说,使用size_type
会更好)因为循环从0到20运行且两者都是{{1} }。因此,以下情况可以。
int
附加说明:
支持基于索引的基于迭代器的循环:
for (int i = 0; i < 20; ++i) { // loops 20 times
// ...
}
它没有被标记为C ++ 11,但是如果可以的话,基于for循环的范围会处理很多这个。
for (vector<double>::iterator i = score.begin(); i != score.end(); ++i) {
// ...
}
甚至使用带有lambda的for (double& i : score) {
// ...
}
。
答案 2 :(得分:4)
vector
size_type
是矢量用于进行大小比较的内容。如果你有一个循环使用int
作为计数器并与向量的实际大小进行比较,那么你将从编译器收到关于有符号与无符号整数比较的警告:
for( int i=0; i<score.size(); i++ ){ // <-- signed vs. unsigned comparisons
// do something...
}
答案 3 :(得分:4)
你的问题有两个。
首先,你写的是std::vector
的结尾 - std::vector
有10个元素,你写的是20。
为了解决这个问题,并遵循“不要重复自己”的原则,您需要按如下方式更改代码:
int main(){
std::vector<double> score(20);
for(std::vector<double>::size_type i=0;i<score.size();i++) {
我将vector
放大并使用其大小来确定要写多少。
现在,当我们尝试用int
:
int main(){
std::vector<double> score(20);
for(int i=0;i<score.size();i++) {
我们得到一个烧焦/无符号的比较(可能):
i<score.size()
其中score.size()
是std::vector<double>::size_type
类型的无符号值,i
是int
。
编译器通常会在这些情况下发出警告,因为很容易获得无意义的结果(如果i
&lt; 0
,比较通常会导致负数比较大于正数!)此外,如果vector
的大小大于int
的最大值(在某些系统上,小到32767
,通常至少为2147483647
,有时甚至更大 - 这是编译器可以自由选择的值,C ++标准没有完全指定它,循环将会非常失败。
现在,虽然std::vector<double>::size()
的类型是std::vector<double>::size_type
,但这是(在我所经历的每个实现中)只是std::size_t
。所以这是一个较短的说法:
for(std::size_t i=0;i<score.size();i++) {
(std::size_t
在<cstddef>
中定义为旁边)。
如果您使用C ++ 11编程,可以做得更好:
int i=0;
for(double& student:score) {
std::cout<<"Enter marks for student #"<<++i<<":"<<std::flush;
std::cin>>student;
}
这是一个基于范围的for
循环,可以完全避免索引问题。