vector的初始化
vector可以用初始化列表完成对象的初始化,但有两处容易想当然,造成错误的理解!
vector<string> v1 {"hi"}; //ok
vector<string> v2 ("hi"); //error,无对应的构造函数
vector<string> v3(10,"hi"); //ok,v3有10个"hi"
vector<string> v4{10,"hi"}; //ok,与上一句一样
//!注意:如果初始化时使用了花括号的形式但是提供的值又不能用来列表初始化,就要考虑用这样的值来构造vector对象了!这里主要是因为int型无法隐式的转换成string类型;再看下面的例子:
vector<char> c1{10,'a'}; //ok,含两个字符
数组的初始化
当定义数组时,字符串数组和数值类数组的默认初始化不同,要特别注意:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int myint[10]; //函数体外,默认初始化为0
string s1[10]; //初始化为空串
int main(int argc, char *argv[])
{
int myint2[10]; //函数体内,未显式初始化,则其值是未知的
string s2[10]; //初始化为空串
for(auto i:myint2)
cout<<i<<"\t";
cout<<"\n======================================================\n\n";
for(auto i:myint)
cout<<i<<"\t";
return 0;
}
所以最好在使用的时候才定义,定义时最好初始化。
复杂的数组声明
int *ptrs[10]; //ptrs是含有10个整形指针的数组
int &refs[10] = /*?*/ //error!不存在引用的数组
int (*Parray)[10] = &arr; //Parray指向一个含有10个整数的数组
int (&arrRef)[10] = arr; //arrRef引用一个含10个整数的数组
Tips:
- 默认情况下,类型修饰符应从右往左依次绑定
- 对数组来说,由内向外的与阅读顺序更易让人理解:首先(*Parray)意味Parray着是一个指针,接下来观察右边,知道Parray指向一个大小为10的数组,最后观察左边,知道数组中的元素类型是int!
指针和数组
数组的名字其实是其首元素的指针,但在对数组名使用auto和decltype时,两者区别很大!
int ia[] = {0,1,2,3,4,5,6,7,8,9}; //ia是一个含10个整数的数组
auto ia2(ia); //ia2是一个整形指针,指向ia的第一个元素
decltype(ia) ia3 = {0,1,2,3,4,5,6,7,8,9}; //ia3是一个含10个整数的数组!
ia[3] = i; //为ia3的一个元素赋值
要特别注意上面auto和decltype的区别
多维数组
多维数组其实就是数组的数组,int arr[10][20][30]={0};
按照上文的方法由内向外读,首先array是个大小为10的数组,他的每个元素都是大小为20的数组,这些数组的元素又都是含有30个整数的数组。
多维数组可以用花括号初始化:
int ia[3][4] = { {0,1,2,3}, {4,5,6,7}, {8,9,10,11} };
int ia2[3][4] = { {0}, {1}, {2} }; //将行首元素分别初始化为0,1,2
练习:
编写三个不同版本的程序,使其输出ia的元素:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
int array[3][4]= {0,1,2,3,4,5,6,7,8,9,10,11};
// VERSON 1 : using range for
cout<<"\nVERSON 1 : using range for\n";
for(int (&p)[4] : array) //必须用& 引用
{
for(int i : p)
cout<<i<<"\t";
cout<<endl;
}
//VERSON 2: using traditional for & []
cout<<"\nVERSON 2 : using traditional for & []\n";
for (int i = 0; i<3;i++)
{
for(int j = 0; j<4; j++)
cout<<array[i][j]<<"\t";
cout<<endl;
//VERSON 3: using traditional for & pointors
cout<<"\nVERSON 3: using traditional for & pointors\n";
for (int (*p)[4]=array;p!=array+3;p++)
{
for(int *j = *p; j!=(*p)+4; j++)
cout<<*j<<"\t";
cout<<endl;
}
return 0;
}