模板类vector:
模板类vector相似string类,是一种动态数组。
例如说,string类可以将一个string的字符串插入到另外一个string类字符串后面。vector也可以有相似的功能。
而对于vector类来说,他是一个数组,例如我们数组中有第一个A和第二个元素B,然后我们可以把C插入在A和B之间,这个时候,数组第一个成员为A,第二个为C,第三个为B。
我们还可以把其中一个成员删掉,这样,后面两个成员自动向前进一位,例如删掉第一个成员A,于是第一个成员变成了C,第二个成员变成了B。
头文件:
#include<vector> //使用vector类需要引用头文件vector
创建vector类数组:
vector<类型名>数组名(成员个数);
例如:
vector<double>vd(n);
注意:成员个数可以为变量,这样在使用的时候更自由。
给vector数组成员赋值:
可以像使用普通数组一样,使用 变量名[编号] 来进行赋值,注意:第一个成员的编号为0,和数组是一样的。例如:
vd[1] = 22;
数组vd的第二个成员的值为22。
注意:vector类不能在声明的时候,同时进行初始化为数组成员赋值。
在vector类的数组中插入一个成员:
使用命令 数组名.insert(数组名.begin()+插入位置,插入的成员);
例如,给vd数组的第二个位置插入一个成员,成员的值为a(a可以是变量名,也可以是常量,但需要已经初始化)。如代码:
vd.insert(vd.begin()+1, a);
注意:插入到第二个位置,是+1,而原来数组第二个位置的成员,将依次向后退一位,例如原来第二个位置的成员,在插入后就在第三个位置了。
删除vector类数组中的一个成员:
使用命令 数组名.erase(数组名.begin()+删除位置):
例如,删除vd数组第一个成员,那么删除位置就应该写0。注意,数组第一个位置的编号是0。如代码:
vd.erase(vd.begin() + 0);
在vector类数组的尾部插入一个成员:
即在数组的最后插入一个成员,这个成员的插入,增加了数组成员的个数。代码为: 数组名.push_back(数组成员);
例如在数组最后加入成员10,代码:
vd.push_back(10);
vector类数组的成员数:
数组成员数是可以变的,用 数组名.size() 可以显示成员的数量。——按照某个帖子的说法是 向量大小 。
①在创建并声明时,成员数为声明时的成员数,即使某个成员并没有被赋值,也会被算入在内。
②在插入成员,无论是在中间插入或是在尾部插入,都会增加成员数。
③在删除成员时,也会相应减少成员数。
代码是:
cout << "vd数组的宽度为:" << vd.size() << endl << endl; //显示数组的成员数
将一个vector数组赋值给另外一个vector数组:
当两个数组类型相同,(元素数无需相同),可以进行赋值。
格式为:
目标数组名=源数组名;
上代码:
#include<iostream> #include<vector> //使用vector类需要引用头文件vector int main() { using namespace std; int n; //声明变量n cout << "输入vector类的数组元素个数(请大于等于3):" << endl; cin >> n; //要求用户输入变量n vector<double>vd(n); //创建一个double类型的vector动态数组,数组元素为n个,数组名为vd //即 vector<类型名>数组名(成员数量),注意,成员数量可以为变量 cout << "输入vd[0]:"; cin >> vd[0]; //调用的时候,用vector类的数组名加元素编号,第一个元素编号为0,同数组。要求用户输入vd[0]的值 cout << "将vd[1]赋值22。" << endl; vd[1] = 22; //给vd[1],即数组中第2个成员,赋值22 cout << "vd[0]为" << vd[0] << "。vd[1]为" << vd[1] << endl; cout << "vd数组的宽度为:" << vd.size() << endl << endl; //显示数组的成员数 int a = 1; vd.insert(vd.begin() + 1, a); //在数组中第二个位置插入变量a cout << "现在,创建常量a=1,然后将a插入在vd[1]之前,即把a插入到vd[1]的位置,原来的vd[1]依次顺延到下一位。" << endl; cout << "vd[0]为" << vd[0] << "。vd[1]为" << vd[1]; cout << "vd[2]为:" << vd[2] << endl; //原本第二个位置的成员被顺延到第三个位置了 cout << "vd数组的宽度为:" << vd.size() << endl << endl; //显示数组的成员数 vd.erase(vd.begin() + 0); //删除数组中第一个成员,其他成员依次向前进一位 cout << "现在,删除vd[0]当前成员,原来的vd[1]就变成vd[0]了。" << endl; cout << "vd[0]为" << vd[0] << "。vd[1]为" << vd[1] << endl; cout << "vd数组的宽度为:" << vd.size() << endl << endl; //显示数组的成员数 //n = 5; //虽然上面vd[n]声明了数组的成员数,但单纯更改变量n,其实是不能改变vd数组的成员个数的。 int b = 2, c = 3, d = 4; //声明新的变量bcd并初始化 vd.insert(vd.begin() + 2, b); //在第三个位置插入成员b vd.insert(vd.begin() + 3, c); //在第四个位置插入成员c vd.insert(vd.begin() + 4, d); //在第五个位置插入成员d cout << "从第三个位置依次插入b=2,c=3,d=4" << endl; cout << "目前,vd[0]为" << vd[0] << "。vd[1]为" << vd[1] << "。vd[2]为" << vd[2] << "。vd[3]为" << vd[3] << "。vd[4]为" << vd[4] << endl; cout << "vd数组的宽度为:" << vd.size() << endl << endl; //显示数组的成员数 //vd.erase(vd.begin() + 1, vd.end() + 2); //按照说法,这行代码可以删除多个数组成员,但实际测试中却出错了。 vd.push_back(10); //在数组的最后插入成员,值为10 cout << "在vd数组的尾部插入常量10。" << endl; cout << "第" << n + 4 << "个元素是数组的最后一个元素,vd[" << n + 3 << "]的值为:" << vd[n + 3] << endl; //注意,这行是可以通过变量来显示相应的数组的成员的,例如vd[n+3]是数组第n+4个成员 cout << "vd数组的宽度为:" << vd.size() << endl << endl; //显示数组的成员数 vector<double>bb(20); //创建vector类数组bb,原因是要将vd数组赋值给bb数组,因此成员数不重要 bb = vd; //将vd数组赋值给bb数组,二者将完全等同 cout << "将vd数组赋值给bb数组\n"; cout << "bb数组第四个成员bb[3]=" << bb[3] << endl; cout << "bb数组的成员数为:" << bb.size() << endl; system("pause"); return 0; }
输出:
输入vector类的数组元素个数(请大于等于3): 33 输入vd[0]:55 将vd[1]赋值22。 vd[0]为55。vd[1]为22 vd数组的宽度为:33 现在,创建常量a=1,然后将a插入在vd[1]之前,即把a插入到vd[1]的位置,原来的vd[1]依 次顺延到下一位。 vd[0]为55。vd[1]为1vd[2]为:22 vd数组的宽度为:34 现在,删除vd[0]当前成员,原来的vd[1]就变成vd[0]了。 vd[0]为1。vd[1]为22 vd数组的宽度为:33 从第三个位置依次插入b=2,c=3,d=4 目前,vd[0]为1。vd[1]为22。vd[2]为2。vd[3]为3。vd[4]为4 vd数组的宽度为:36 在vd数组的尾部插入常量10。 第37个元素是数组的最后一个元素,vd[36]的值为:10 vd数组的宽度为:37 将vd数组赋值给bb数组 bb数组第四个成员bb[3]=3 bb数组的成员数为:37 请按任意键继续. . .
模板类array(限C++11):
vector类比数组强大,但是代价是效率较低(不知道为什么,原因是使用的是动态存储区么?),假如是长度固定的数组(原因是vector是动态数组,可以增加成员或减少成员),使用数组更高,但代价是不那么安全和方便(不方便本人知道,但是不安全是为什么?)。
因此,c++11增加了模板类array,使用的是栈(静态存储区)(vector是堆,动态存储区),位于名称空间std之中。
因此array效率和数组相同,但是更安全和方便,要创建array对象,需要包含头文件array。array对象的创建和语法与vector稍有不同。
头文件:
#include <array> //使用模板array需要调用头文件array
声明和创建:
声明一个array类数组和vector数组方式不同,格式为: array<类型名,成员数常量>数组名;
例如创建一个int类型,成员数为3,数组名为a的array类的代码为:
array<int, 3> a;
注意:①vector的成员数是可变的,而array的成员数是固定的。
②vector和array都是<>括号,而不是小括号()。
初始化和赋值:
原因是和数组相似,所以初始化和赋值的方式相似数组。
初始化的格式为: array<类型名,成员数>数组名={成员1,成员2,……};
赋值格式为: 数组名[编号]=常量;
例如,初始化数组a的前2个成员的代码为:
array<int, 3> a = { 1,2 };
给a的第三个成员赋值的代码为:
a[2] = 4;
显示成员数:
与vector类相同,显示成员数的代码为: 数组名.size()
例如代码:
cout << a.size() << endl;
上代码:
#include<iostream> #include<array> //使用模板array需要调用头文件array int main() { using namespace std; array<int, 5> a = { 1,2 }; //创建array类数组a,成员数为5,类型为int类,并为前2个成员赋值 a[2] = 4; //为第三个成员赋值 cout << a[0] << endl; //显示第一个成员的值 cout << "请为数组第四个成员赋值:" << endl; cin >> a[3]; //读取用户输入,为第四个成员赋值 cout << "第四个成员的值为" << a[3] << endl; //显示第四个成员的值 cout << "数组的成员数为:" << a.size() << endl; //显示成员数 array<int, 5 >b; //创建数组b b = a; //由于数组和数组a的类型相同,成员数相同,故可以将数组a赋值给数组b cout << "array类数组b等于数组a,b的第二个元素为b[1]=" << b[1] << endl; //显示数组b第2个元素,和数组a第二个元素相同 system("pause"); return 0; }
输出:
1 请为数组第四个成员赋值: 55 第四个成员的值为55 数组的成员数为:5 array类数组b等于数组a,b的第二个元素为b[1]=2 请按任意键继续. . .
vector对象、array对象和普通数组之间的相同和差异:
std::vector<double> x(5, 2,45); // 5 个元素,全部初始化为 2.45.
std::vector<double> x = {1.0, 1.1, 1.2, 1.3};
std::vector<double> x{1.0, 1.1, 1.2, 1.3};
后两个需要 C++11.
一种是对象本身,占用的内存
一种是 持有handle (指针,有时候引用也可)的对象,handle 指向的内存区域
例如 string
sizeof(stirng)
是对象 string 占有的内存,是固定大小
string 的内容,需要占用动态区
string::size() 是内部各个字符占用的内存大小,
是必须保证的大小,通常会占用比这个大小多一点的内存。
这里 指针p可以在静态区,栈区 这两个数据区域的任何一个地方。
主要看怎么样定义指针 p,定义在何处
new 的这个string对象在堆区,大小为 sizeof(string) 这个对象通常并不包含它的数据 “1234567891011121314.。”
它的数据 “1234567891011121314.。” 一般存放在堆区的另一块内存中
你还可以 这么做
struct XXX {
string *p;
};
定义一个 XXX 对象 x,
XXX x;
或new 一个XXX对象
px=new XXX;
然后,再初始化他的指针成员 p;….
。
这个持有者例如px,p,是必须存在的,
原因是高级语言,是按照名字,安排变量的存储空间的,按照名字编译代码的。
甚至汇编语言,也需要名字处理变量。
而动态分配的对象,并没有名字。
至少从程序员的角度,看不到他的名字。