1、初始化
int n[10] = {1} 当初始化值比数组元素少的时候,剩下的元素被初始化为0。
int n[2] = {1, 2, 3} 当初始值比数组元素多的时候,编译时会报错。
static int n[10] 不必进行初始化,static数组会自动初始化元素。
2、声明数组
只能使用常量来声明数组,否则会产生编译错误。如:
int a = 10;
int n[a];
这样就会产生编译错误。
int a = 10;
const int i = a;
int n[i];
这样虽然i是用const修饰,但是赋值给他的a依然是一个变量,所以一样会产生编译错误。
尤其注意函数的传参,用传参来声明数组会产生编译错误。
const int i = 10;
int n[i];
这样就不会产生编译错误。
3、数组越界
与Java不同,在c++中数组越界不会报错,编译通过也可以正常运行,会得到一个默认值。但是数组越界是很严重的。
双向越界都不会报错,也就是说下标为负值也不会报错。
4、数组赋值
数组是不能直接赋值的。如:
int n[1] = {0};
int m[1] = {0};
n = m;
这样就好编译错误
由于数组名是const指针,所以一个数组不能通过赋值运算赋给另一个数组。(常量指针不能用在赋值运算左侧)
5、数组/vector长度
(1)与java不同,数组不能知道自身的长度。所以把一个数组当函数传参时,也要把数组长度当函数传参才行。如:
void init(int nums[], int length)
(2)vector.size()是一个size_t类型的,不是int类型,一定要注意。在某些编译器上直接转int会报错。
6、vector初始化及赋值
(1)vector初始化可以传入另外一个vector2,这样会拷贝vector2的数据来初始化,称为拷贝构造函数。如:
vector a;
vector b(a);
(2)将一个vector赋值给另外一个vector时,也是拷贝。
a = b; //a是b的拷贝,依然是两个不同的vector。
注意当两个vector不同时进行赋值,左侧的vector无论之前什么长度,都会变成跟右侧vector长度相等,元素相等。
7、vector获取元素
可以用vector[i]或vector.at(i)两种形式来获取元素。其中第一种方式与数组一样不检查边界,而第二种方式会检查边界。
8、函数传参
数组作为函数传参时是引用参数,如void init(int a[])
vector作为函数传参时默认是传值的,所以如果想引用传参,必须加“&”,如void init(vector &a)。
所以使用vector函数传参时一定要注意,尽量使用引用传参,以免不必要的内存占用。
9、字符串数组
可以直接使用字符串初始化,如:
char a[] = "abcd";
数组长度会比字符串长度大1,因为数组末尾有一个‘\0’,来表示这个数组是一个字符串,如果没有这个结尾,那只是一个普通的数组。
比如上面的数组a应该是[‘a’, 'b', 'c', 'd', '\0']的一个长度为5的数组。
可以直接使用,如 cout<<a<<endl 可以直接打印字符串
所以一定要注意长度,如果保存超过声明长度的字符串,数组末尾就没有'\0'字符,而且会覆盖内存中数组后面的数据,造成溢出。
10、多维数组初始化
int a[2][3] = {1, 2, 3, 4, 5}
会按照顺序(先行后列)为多维数组初始化,不够的初始化为0。既a[0][0]=1, a[0][1]=2 ... a[1][2]=0
int a[2][3] = {{1}, {2, 3}}
会按每行进行初始化,不够的初始化为0。既a[0][0]=1, a[0][1]=0, a[0][2]=0, a[,1][0]=2, a[1][1]=3, a[1][2]=0
int a[2][1] = {{1}, {2, 3}}
这样会编译报错,因为每行只有一列,而{2, 3}超出了。同样int a[1][2] = {{1, 2}, {1}}也是
int a[][2] = {{1}, {2, 3}}
可以没有行数,这样会根据初始化的值自动判断出行数,但是一定要有列数。
11、vector排序
std::sort(vector.begin(), vector.end());