数组(Array)是有序的元素序列,是用于储存多个相同类型数据的集合。
1. 一维数组
1.1 一维数组的创建
创建方式:
type_t arr_name [const_n];
type_t 是指数组的元素类型。
const_n 是一个常量表达式,用来指定数组的大小。
例:int arr[10];
类型为整型、大小为十、名字为arr的数组。
注:数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数组的概念。
例:int count = 10;int arr[count];
该句代码先定义一个变量count,再将count作为数组的大小,但它在C99之前都不支持!并且它的长度不是想变就变的,只是你可以给count赋值,然后创建count大小的数组,大小不再是常量了。
变长数组是指用整型变量或表达式声明或定义的数组,而不是说数组的长度会随时变化,变长数组在其生存期内的长度同样是固定的。
1.2 一维数组的初始化
数组初始化:在创建数组的同时给数组赋一些初始值。
完整的初始化方式:
- 整型数组:
int arr1[5] = {1,2,3,4,5};
字符数组:char ch[3] = {'a','b','c'};
字符串:char str[3] = "abc";
不完整的初始化方式:
-
整型数组:
int arr2[10] = {1,2,3,4,5};
字符数组:char ch1[10] = {'a','b','c'};
字符串:char str1[10] = "abc";
若花括号内元素的个数少于方括号,那么花括号中剩余元素就会默认初始化为零。 -
整型数组:
int arr3[] = {1,2,3,4,5};
字符数组:char ch2[] = {'a','b','c'};
字符串:char str2[] = "abc";
若方括号中没有初值,那么它的初值就是花括号中元素的个数。
字符串与字符的初始化相似但有所不同,字符串初始化时会在结尾加’\0’表示结束,而字符不会,当然如果是开的空间大于字符或字符串,那么它们其实是一样的,因为反正会将剩余的空间初始化为零。
1.3 一维数组的使用
方括号 ’ [ ] ’ :下标引用操作符,用于数组元素的访问。
数组访问用下标,且下标从零开始
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
像这句代码,想取出元素1,由于数组下标是从零开始的,可以用arr[0]表示第一个元素。
下举个打印数组内所有元素的例子(附注释):
1.4 一维数组在内存中的存储
创建一个固定数组,它的空间开辟在栈中,并且是连续存储的。
&:取址符,取出元素地址;这样就能知道储存的位置。
我们来打印地址来观察:
此时发现一维数组的数据在内存中的确是按顺序连续存储。
2. 二维数组
2.1 二位数组的创建
创建方式:
type_t arr_name [const_n1][const_n2];
type_t 是指数组的元素类型。
const_n1是一个常量表达式,用来指定数组的行。
const_n2是一个常量表达式,用来指定数组的列。
例:int arr[3][4];
三行四列,12个元素的二维数组
2.2 二维数组的初始化
完整的初始化方式
int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
不完整的初始化方式
-
花括号内无分组
1.int arr[3][4] = {1,2};
只初始化第一行的前两个元素,剩余元素默认为零。
2.int arr[3][4] = {1,2,3,4,5,6};
只初始化第一行的元素和第二行的前两个元素,剩余元素默认为零。 -
花括号内有分组
int arr[3][4] = {{1,2},{3,4}};
只初始化第一行和第二行的前两个元素,剩余元素默认为零。 -
当有初始化,那么方括号中行数可省略
int arr[][4] = {{1,2},{3,4}};
但若没有初始化,像int arr[][4];
,那么就是错的。
2.3 二维数组的使用
二维数组也是用‘ [ ] ’来访问,不过是分行下标和列下标。
例如:int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
想访问元素7,可以用arr[1][2]来访问。
例题:打印数组所有元素
int main()
{
int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };//完整初始化
int i = 0;//定义行下标
for (i = 0; i < 3;i++)
{
int j = 0;//定义列下标
for (j = 0; j < 4; j++)
{
printf("%d ", arr[i][j]);
}
}
return 0;
}
2.4 二维数组在内存中的存储
我们同样来打印地址来观察:
此时发现二维数组和一维数组的数据在内存中存储是一样的,也是按顺序连续存储。
3. 数组越界
数组的下标是有范围限制的。
数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
例如:
一维:int arr1[5] = {1,2,3,4,5};
该数组有五个元素,下标从零开始,那么下标:0 1 2 3 4,下标>4,或<0,数组越界访问。
二维:int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
该数组有12个元素,下标从零开始,那么下标有:00、 01、 02、 03、 10、 11、 12、 13、 20、 21、 22、 23,如果行>2,列>3或下标<0,数组越界访问。
注意:
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就
是正确的,所以写代码时,最好自己做越界的检查。
4. 数组可以做函数参数
当函数需要一个数组时,可以将函数名作为参数传过去。
但是需要注意的是这里传的数组并不是将整个数组传过去,而是首元素的地址。因此sz只能在main函数中计算,然后作为参数传过去。由于数组名arr是一个地址,而地址在32位下是四个字节,arr[0]的值是1,整型也是四个字节,相比为结果为1。
数组名的解释在这篇中http://t.csdn.cn/efcOg
求三连支持,若有错误,敬请各位读者斧正!