C++中的向量:为什么我在这个简单的复制和打印程序中会遇到这么多错误?

3

我正在尝试使用算法库和向量库将一组数字从数组复制到向量中,然后使用迭代打印它们。但是我的代码存在问题,您能帮我看看吗?

另外,我尝试了两种迭代方法:一种是使用vec.begin()和vec.end()方法,另一种是使用for (i = 0; i < vec.capacity(); i++),但都出现了错误。

请问我该怎么做呢?

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    int intArray[] = {5,6,8,3,40,36,98,29,75};

    vector<int> vecList(9);
    //vector<int>::iterator it;
    copy (intArray, intArray+9,vecList);
    //for(it  = vecList.begin() ; it != vecList.end() ; it++)
    for (int it = 0 ; it < vecList.capacity() ; it++)
    {
        cout<<*it<<endl;
     }

    system("pause");
    return 0;

}

提示:当it的类型为int时,*it是什么?这两种方法是访问元素的不同方式。 - amit
我已经把它移除了,你是对的。但还是有许多模糊混乱的错误,这些对我来说毫无意义... - T0M XeOn LuCiFeR
std::copy 的第三个参数也需要一个迭代器。 - Some programmer dude
这个 std::copy 的文档有一个非常接近您自己的例子。 - juanchopanza
5个回答

7
有几个改进可以实现。
您将迭代器与索引混淆了。 迭代器 it 是指向向量的指针,您需要通过键入 *it 来解除引用。 索引 i 是从向量开头的偏移量,并且说 vecList[i] 将给出该元素。
最好使用初始化列表(C++11)来初始化向量,而不是从数组中读取。
您需要循环到 vecList.size()。 向量的容量是向量容器元素的分配存储空间的大小。 最好使用范围 for 循环进行循环,如 Kerrek SB 所示,或使用 std::for_each + lambda 表达式,或使用常规 for 循环,就像您所做的那样。 在这种情况下,最好养成习惯,使用 it != vecList.end()(而不是使用 <)并执行 ++it 而不是 it++
请注意,我还使用了 auto 避免编写显式的迭代器类型。 在您可以使用 auto 的任何地方都养成使用 auto 的好习惯。
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    // initialize vector with a list of elements
    vector<int> vecList {5,6,8,3,40,36,98,29,75}; 

    // loop from begin() to end() of vector, doing ++it instead of it++ 
    for (auto it = vecList.begin(); it != vecList.end(); ++it) 
    {
        cout<<*it<<endl;
    }

    // the pause command is better done by setting a breakpoint in a debugger

    return 0;

}

Ideone上的输出结果(此处使用g++ 4.5.1编译器,最好升级到至少这个版本以利用C++11功能)。


代码存在很多问题。他试图对“int”进行取消引用,他没有初始化索引... - Luchian Grigore
1
我不同意在任何地方都使用auto。只有当它能够消除不必要的混乱时,我才会使用它。 - fredoverflow
当我编译它时,这些是我得到的错误,还有一个问题,我正在使用两天前发布的Backtrack 5 r3,应该有最新版本,不要紧,这个项目是使用Qt C++纯文本项目,它是最新版本,那又怎样? - T0M XeOn LuCiFeR
@FredOverflow,Herb Sutter和Scott Meyers不同意你的观点。 - TemplateRex
是的,请阅读错误信息的第一行:您需要使用“-std=c++0x”进行编译。 - TemplateRex
显示剩余4条评论

6
问题在于您混淆了索引和迭代器。

使用索引:

 for (int i = 0  ; i < vecList.size() ; it++)
 {
    cout<<vecList[i]<<endl;
 }

使用迭代器

 for (std::vector<int>::const_iterator it = vecList.begin()  ; i != vecList.end() ; it++)
 {
    cout<<*it<<endl;
 }

1

这不是一个答案,但我想展示现代C++如何让你摆脱很多对细节脆弱的依赖:

int intArray[] = {5,6,8,3,40,36,98,29,75};

std::vector<int> vecList(std::begin(intArray), std::end(intArray));

for (int i : vecList) { std::cout << i << std::endl; }

通过迭代器和算法的惯用法,您通常可以消除任何显式提及数组长度等细节,从而使您的代码更加健壮。


2
你已经在使用C++11了,为什么不把前两行合并呢?std::vector<int> vec {1, 2, 3}; 在这种情况下,甚至可以使用 for (int i : {1, 2, 3}) std::cout << i << '\n'; - chris
@chris 你觉得 for (int i : {1, 2, 3}) std::cout << i << '\n'; 怎么样? ;) - fredoverflow

1
A. 你需要迭代 vecList.size() 而不是 vecList.capacity(),因为它表示向量保留了多少内存(而不是使用了多少内存)。 B. 你试图使用整数索引 it 作为迭代器,并调用 *it,你应该查看 Luchian Grigore 的答案以找到正确的方法。

1

笔误使用:copy(intArray, intArray+9, vecList.begin());

因此,

#include<iostream>
#include<vector>
#include <algorithm>

using namespace std;


int main()

{

int intArray[] = {5,6,8,3,40,36,98,29,75};

vector<int> vecList(9);
vector<int>:: iterator it;
copy (intArray, intArray+9,vecList.begin());
for (it=vecList.begin();it!=vecList.end(); it++)
{
    cout<<*it<<endl;
 }

system("pause");
return 0;

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接