繁体   English   中英

C ++:“向量 <int> :: size_type变量“ - 以这种方式声明的重点是什么?

[英]C++: “vector<int>::size_type variable” - what is the point of declaring in this way?

我认为这是一个非常基本的问题,但我无法弄明白。

我习惯于在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_typeint vector<double>::size_type

size_type保证足够大,以支持最大的矢量大小vector::max_size() int不是:在许多常见平台上, int有32位,而max_size()远大于2 31

如果你知道大小是(并​​且将永远是)一个像20这样的小数,那么你可以使用int或任何其他整数类型而不是size_type 如果您要更改程序,例如从输入中读取大小,那么如果该值大于INT_MAX则会出现严重错误; 在使用size_type ,它将继续适用于max_size()任何值,您可以轻松地测试它。

嵌入式类型vector<double>::size_type与各种vector方法的返回值有关,例如.size() ,因此在这种情况下使用匹配类型的首选项( int = 0通常会导致符号不匹配警告)。 例如

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运行并且都是int 因此以下是可以的。

for (int i = 0; i < 20; ++i) { // loops 20 times
  // ...
}

补充说明:

支持基于索引的基于迭代器的循环:

for (vector<double>::iterator i = score.begin(); i != score.end(); ++i) {
  // ...
}

它没有被标记为C ++ 11,但如果可能的话,基于for循环的范围会处理很多这样的事情。

for (double& i : score) {
  // ...
}

甚至使用带有lambda的for_each

vector size_type是矢量用于进行大小比较的内容。 如果你有一个循环使用int作为计数器并与向量的实际大小进行比较,你会收到编译器关于有符号与无符号整数比较的警告:

for( int i=0; i<score.size(); i++ ){  // <-- signed vs. unsigned comparisons
    // do something...
}

你的问题有两个问题。

首先,你在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替换那个long子句时:

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类型的无符号值, iint

编译器经常在这些情况下发出警告,因为很容易得到无意义的结果(如果i < 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循环,完全避免了索引的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM