一维数组 数组的创建
数组是在内存中连续存储的具有相同类型的一组数据的集合
数组创建如下:
1 2 3 4 type arrayName [arraySize]; // type 数组中元素类型 // arrayName 数组名 // arraySize 数组的大小(数组可容纳元素最大个数)。必须是一个大于零的整数常量(常量表达式)
注意:数组大小为 常量表达式 ,不可为变量。
(其实数组大小可以是变量(可变长数组),C99标准支持,不重要 )
实例
1 2 3 4 5 6 // 代码1 int arr[10]; // arr可以容纳 10 个类型为 int 的数字。 // 代码2 int count = 10; int arr2[count]; // error,数组大小不可为变量。
数组初始化
数组的初始化:在创建数组的同时给数组的内容一些合理初始值(初始化)。
数组元素的值由{ }
包围,各个值之间以,
分隔。
1)给 部分 元素赋值。
当{ }
中值的个数少于元素个数时,只给前面部分元素赋值,后面的元素自动初始化为 0。
对于short、int、long,就是整数0;
对于char,就是字符 ‘\0’;
对于float、double,就是小数0.0。
只给部分元素赋初值,当{ }中值的个数少于元素个数时, 只给前面部分元素赋值,后面的元素默认为0值
赋值的元素少于数组总体元素的时候,剩余的元素自动初始化为 0
1 2 3 4 5 6 7 8 int arr[10 ] = { 1 ,2 ,3 ,4 ,5 }; 等价: int arr[10 ] = { 1 ,2 ,3 ,4 ,5 ,0 ,0 ,0 ,0 ,0 };int a[10 ]={0 };等价: int a[10 ]={0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
2)给 全部 元素赋值时,在定义数组时可以不给出数组长度
1 2 3 4 5 int arr[] = { 1 ,2 ,3 ,4 ,5 };int a[10 ]={1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 };
3)给全部元素赋值,那么在数组定义时可以不给出数组的长度
注意:数组在创建的时候如果想 不指定数组的确定的大小就得初始化
1 2 3 int a[]={0 ,2 ,4 ,6 ,8 };等价: int a[5 ]={0 ,2 ,4 ,6 ,8 };
注意:
1 2 3 4 5 char arr1[] = "abc" ; char arr2[3 ] = { 'a' ,'b' ,'c' };printf ("%s\n" , arr1); printf ("%s\n" , arr2);
一维数组的使用
访问数组元素:使用 []
,下标引用操作符。
1 2 数组名[下标] 这里的下标与定义数组的形式相同,但含义不同。定义数组是指定的是大小;而这里的下标指的是数组元素的编号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main () { int arr[10 ]; int sz = sizeof (arr) / sizeof (arr[0 ]); int i = 0 ; for (i = 0 ; i < sz; i++) { arr[i] = i; } for (i = 0 ; i < sz; i++) { printf ("Element[%d] = %d\n" , i, arr[i]); } return 0 ; }
1 2 3 int arr[10 ];int sz = sizeof (arr) / sizeof (arr[0 ]);
注意:数组可以使用下标访问,数组的下标是 从 0 开始
1 2 3 4 5 6 int a[5 ] = { 1 ,2 ,3 ,4 ,5 }; a[5 ] = 6 ; int a[5 ]; a[5 ] = {1 , 2 , 3 , 4 , 5 };
数组越界 数组的下标是有范围限制的。
数组的下标规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就 是正确的。
以下程序错误写法:
1 2 3 4 5 6 7 8 9 10 int main () { int arr[10 ] = {1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 }; int i = 0 ; for (i=0 ; i<=10 ; i++) { printf ("%d\n" , arr[i]); } return 0 ; }
一维数组在内存中的存储
数组在内存中是连续存放的。随着数组下标的增长,元素的地址在有规律的递增。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int main () { int arr[10 ] = {0 }; int i = 0 ; int sz = sizeof (arr)/sizeof (arr[0 ]); for (i=0 ; i<sz; ++i) { printf ("&arr[%d] = %p\n" , i, &arr[i]); } return 0 ; }
二维数组 二维数组可以看成是由多个长度相同的一维数组构成的。
二维数组的创建 二维数组创建如下:
1 2 3 4 5 type arrayName [length1][length2]; // type 数组中元素类型 // arrayName 数组名 // length1 第一维下标的长度(行数) // length2 第二维下标的长度(列数)
实例
1 2 int arr[3 ][4 ];char arr[5 ][5 ];
二维数组的初始化 1)二维数组的初始化可以按行分段赋值,也可按行连续赋值。
1 2 3 int arr[3 ][4 ] = {1 ,2 ,3 ,4 };等价: int arr[3 ][4 ] = {{1 ,2 },{4 ,5 }};
2)二维数组初始化,行可以省略,列不能省略
1 2 3 int arr[][4 ] = {{2 ,3 },{4 ,5 }};等价: int arr[2 ][4 ] = {{2 ,3 },{4 ,5 }};
3)可以只对部分元素赋值,未赋值的元素自动取0
1 2 3 4 5 6 7 8 9 int a[3 ][3 ] = {{1 }, {2 }, {3 }};1 0 0 2 0 0 3 0 0 int a[3 ][3 ] = {{0 ,1 }, {0 ,0 ,2 }, {3 }};0 1 0 0 0 2 3 0 0
二维数组的使用 二维数组的使用也是通过下标的方式。下标引用 都是从 0 开始
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 int main () { int arr[3 ][4 ] = { 0 }; int i, j; for (i = 0 ; i < 3 ; i++) { for (j = 0 ; j < 4 ; j++) { arr[i][j] = i * 4 + j; } } for (i = 0 ; i < 3 ; i++) { for (j = 0 ; j < 4 ; j++) { printf ("arr[%d][%d} = %d\n" , i, j, arr[i][j]); } } return 0 ; } 输出:
二维数组在内存中的存储
二维数组在概念上是二维的,但在内存中是 连续存放 的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 int main () { int arr[3 ][4 ] = { 0 }; int i, j; for (i = 0 ; i < 3 ; i++) { for (j = 0 ; j < 4 ; j++) { printf ("arr[%d][%d} = %p\n" , i, j, &arr[i][j]); } } return 0 ; } 输出:
数组名是什么? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 int main () { int arr[10 ] = { 1 ,2 ,3 ,4 ,5 }; printf ("%p\n" , arr); printf ("%p\n" , &arr[0 ]); printf ("%d\n" , *arr); return 0 ; } 输出:
重要【★★★★★】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int main () { int arr[10 ] = { 1 ,2 ,3 ,4 ,5 }; printf ("arr = %p\n" , arr); printf ("&arr[0] = %p\n" , &arr[0 ]); printf ("&arr = %p\n" , &arr); return 0 ; } 输出:
看到这里,有人就问这不一样的吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int main () { int arr[10 ] = { 1 ,2 ,3 ,4 ,5 }; printf ("arr = %p\n" , arr); printf ("arr+1 = %p\n" , arr+1 ); printf ("&arr[0]+1 = % p\n" , &arr[0 ]+1 ); printf ("&arr = %p\n" , &arr); printf ("&arr+1 = %p\n" , &arr+1 ); return 0 ; } 输出: 分析: 第一组:在原本地址上加了 4 ,增加了一个元素的大小 第二组:在原本地址上加了 4 ,增加了一个元素的大小 第三组:在原本地址上加了 40 ,也就是增加了整个数组的大小
总结:
数组名是数组首元素地址 。但是有 两个例外 (除下面两个例外以外,数组名都表示数组首元素地址)
sizeof(数组名) :计算整个数组的大小 ,sizeof内部单独放一个数组名,数组名表示整个数组 。
&数组名 :取出的是整个数组的地址 。&数组名,数组名表示整个数组 。
字符数组 注意:
字符数组可以在定义的时候进行初始化赋值,也可以在之后的程序中对其进行赋值操作。例如:
1 2 char str[6 ] = "hello" ; strcpy (str, "world" );
但是在对字符数组进行赋值时需要注意,使用赋值运算符(=)对字符数组进行赋值会出现错误,需要使用字符串函数如strcpy()等进行操作。例如:
1 2 3 char str[6 ] = "hello" ;str = "world" ; strcpy (str, "world" );