本文通过对c++ primer的总结以及个人理解,总结成一篇博客帮助自己复习。
数组在赋值的时候,总会出现一些比较混乱的情况,直接上栗子:
我们在使用vector时,经常会因为括号问题出错。
// 注意我们在使用vector<string>时不要用()对其初始化和赋值。
vector<int> a(10); // 10个0
vertor<int> b{10}; // 1个10
vector<int> c(10, 1); // 10个1
vector<int> d{10, 1}; // 10和1
vector<string> e{10}; // 10个0
vector<string> e{10, 1}; // 10个1
在定义数组时,有一些表达很容易被我们忽略。
int n = 10;
constexpr int n1 = 10;
// 以下定义中,string arr2[n]是非法的,其他是合法的。因为n不是常量表达式。
int arr[10];
int *arr1[n1];
string arr2[n];
string arr3[n1];
而对于复杂的数组声明,我们也可能会陷入混乱。
int arr[10];
int *arr1[10];
int (*a)[10] = &arr; // a指向一个含有10个整数的数组arr
int (&b)[10] = arr; // b引用一个含有10个整数的数组arr
int *(&c)[10] = arr1; // c是含有10个整形指针的数组arr1的引用
对于auto和decltype,在数组定义时也有一些差异。
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto a(arr); // a是一个指向arr第一个元素的指针,与b等价
auto b(&arr[0]);
decltype(arr) c = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // c是一个由10个整数组成的数组
在很多时候,数组的名字其实是一个指向数组首元素的指针,所以既然是指针,便有一些比较稀奇的用法。
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *a = &arr[2];
int b = a[-2]; // 该表达合法,代表的是arr[0]的元素0。
// 这里的数组的索引值不是无符号类型,但vector和string的下标值是无符号。
而string和char的比较中,也有一些区别。
string s1 = "abcde";
string s2 = "abcdef";
char c1[] = "abcde";
char c2[] = "abcdef";
if (s1 < s2) {/.../} // 比较的是字符串大小
if (c1 < c2) {/.../} // 比较的是两个无关地址
而括号的存在,有时候会让声明变得不一样。
int *a[4]; // 整型指针的数组,数组里面含有4个指针
int (*b)[4]; // 整型指针,指向含有4个整数的数组
容易犯错的数组使用方法和注意事项基本都在上文呈现,如果有哪里错误的欢迎大家及时指正!!!参考书籍《c++ primer 5th》。