数组是一个复合类型。
不存在引用数组;
可以使用列表初始化,但必须指定数组类型,不允许使用auto。
要声明数组的大小,如果使用常量,最好使用constexpr来修饰,表示数组的大小,如果是const,只限制只读,并不要求在编译时就确定,可以在运行时确定。
constexpr unsigned sz = 3;
int ial[sz] = { 0,1,2};
int a2[] = { 0,1,2 }; //自动推断出元素个数为3
int a3[5] = { 0,1,2 }; //等价于a3[]={0,1,2,0,0}
int a5[2] = { 0,1,2 }; //错误,初始值过多
字符数组的特殊性:
字符串字面值的结尾处还有一个空字符。
char a1[] = { 'c','+','+' }; //列表初始化,没有空字符
char a2[] = { 'c','+','+' ,'\0' }; //列表初始化,含有显示的空字符串
char a3[] = "c++"; //含有空字符串
const char a4[6] = "danial"; //错误,没有空间存空字符
即a1的长度为3,a2的长度为4,当用字符串给字符数组赋值时,尾部有一个默认的空字符’\0’,所以a3的长度为4,a4的错误在于没有考虑空字符,导致空间溢出。
不允许拷贝和赋值:
int a[] = { 0,1,2 };
int a2[] = a; //初始化时拷贝错误
a2 = a; //赋值错误
理解复杂的数组声明:
int* ptrs[10]; //ptrs是含有10个元素(整型指针)的数组
int& refs[10]; //错误,不存在引用的数组
int(*Parray)[10]=&arr; //Parray指向一个含有十个整数的数组
int(&arrRef)[10] = arr; //arrRef引用一个含有十个整数的数组
int *(&arry)[10]=ptrs //arry是数组的引用,数组包含10个int类型的指针
指针和数组:
使用数组的时候,编译器一般会把它转换为指针
string nums[] = { "one","two","three" };
string* p = &nums[0]; //指针p指向nums的第一个元素
string* p2 = nums; //等价于p2=&nums[0]
后两行的代码作用是一样的,指针默认指向数组的第一个元素。
int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
auto ia1(arr); //让编译器自动识别,ia2是一个整型指针,指向ia的第一个元素,等价于ia2(&ia[0])
int* ia2 = ia1 + 4; //ia2指向ia的第5个元素.即0+4=4,即第五个元素
int* ia3 = arr + 4; //正确,是上面两行的结合,ia3和ia2都指向的同一个地址
//指针的移动
int * p = &arr[2];
int j = p[1]; //即p指针指向下一个地址,即指向3
int k = p[-2]; //即p指针指向前两个地址,即指向0
指针也是迭代器:
对于迭代器的尾指针的模拟:
尽管能计算到尾后指针,但是尽量少这样用,很容易出错。
int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
int * p = arr; //p指向arr的第一个元素
++p; //p指向arr[1];
int* e = &arr[10]; //指向arr尾元素的下一个位置的指针
for (int* b = arr; b != e; ++b) {
cout << *b << endl;
}
运用迭代器:
int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
int* begin = std::begin(arr); //迭代器的运用
int* end = std::end(arr);
//寻找第一个负数
while (begin != end && *begin >= 0) {
++begin;
}
if (begin != end) {
cout << *begin << endl;
}
else
{
cout << "没找到负数!" << endl;
}
多维数组:
严格来说,c++没有多维数组,都是拼装起来的
int arrs[3][4]; //大小为3的数组,每个元素是含有4个整数的数组
int arr[10][20][30] = { 0 }; //三维数组,将所有元素初始化为0
//初始化
int arrs1[3][4] = {
{0,1,2,3},
{4,5,6,7},
{8,9,10,11}
};
int arrs1[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 }; //与上面等价
int arrs2[3][4] = { {0},{4},{8} }; //0,0,0,0,4,0,0,0,8,0,0,0
int arrs3[3][4] = { 0,3,6,9 };//0,3,6,9,0,0,0,0,0,0,0,0
多维数组与指针:
int ia[3][4]={ 0,1,2,3,4,5,6,7,8,9,10,11 };; //声明了一个二维数组
int(*p)[4] = ia; //ia的这种写法就代表了指针,指向二维数组的第一行;
//左边是一个p指针指向一个长度为4的一维数组,正好两边相等
p = &ia[2]; //p指向ia的尾元素,即ia本来代表第一行,+2代表指向第三行
//利用指针循环输出每个元素
for (auto m = ia; m != ia + 3; ++m) { //这里m推导出来的是和上面p一样的指针
for (auto n = *m; n != *m + 4; ++n) { //这里n是推导出来的一个int *n的指针
cout << *n << " ";
}
cout << endl;
}
//安全点的写法
for (auto k = std::begin(ia); k != std::end(ia); ++k) { //这里m推导出来的是和上面p一样的指针
for (auto l = std::begin(*k);l != std::end(*k); ++l) { //这里n是推导出来的一个int *n的指针
cout << *l << " ";
}
cout << endl;
}
版权声明:本文为qq_41903673原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。