数组是一组相同类型元素的集合。
数组名
数组名是首元素地址
只有两种情况数组名不是首元素地址
- sizeof(arr)----arr代表整个数组
- &arr------------arr代表整个数组,取出的是整个数组的地址
arr | 首元素的地址 | arr+1 | 第二个元素地址 |
---|---|---|---|
&arr | 取整个数组地址 | &arr+1 | 整个数组后的下一个地址 |
- | - | - | - |
&arr[0] | 取第一行数组的地址 | ||
&arr[0][0] | 取第一个数组的地址 |
弄清楚arr这个数组名在解引用和取地址情况下为什么代表了什么,才能对操作有更好的理解
初始化
int arr[10]={1,2,3,4,5,6,7,8,9,0};
不完全初始化
int arr[5]={1};
第一个元素是1,剩余默认为0
不指定个数
int arr[]={1,2,3}
大小为3
字符串数组
char ch[5]="hello";
放不下,字符串有\0
char ch[]={'a','b','c'}
大小为3
数组会根据初始化内容确定
strlen(字符串中是否有\0)计算字符串长度 和 字符串数组大小无关
sizeof是运算符,用来计算变量所占空间大小
存储方式
数组在内存中连续存储,首元素地址最低,末元素地址最高
[ ]是一个操作符,编译器识别后将 [ ]前的变量名当做数组处理
在release版本下,将i放在数组后,就不会产生死循环
指针和数组
数组名 是首元素地址
int a=1;
定义一个变量a;int arr[10]={0,1,2,3,4,5,6,7,8,9};
arr是变量,存储的是 首元素地址- 也就是说arr是一个指针变量,该指针变量存储的是首元素地址,指针指向一个数组;
- 对其解引用就拿到了该指针指向空间的值;
*arr为首个元素
- 对其取地址就拿到了该指针代表空间的地址;
&arr拿到整个数组地址,对指针+1,指针的值递增其指向类型大小
- 所以我们通常所说的:数组名是首地址并不准确,
这种说法将数组名与首地址等价起来,数组名arr实际只是一种变量,该变量内容是首元素地址
下图可以验证
(第四行和第六行用法并不正确,只是为了说明其代表的范围)
*(&arr[0]) | 对数组中第一个元素的地址解引用 |
---|---|
*arr | arr变量值是首元素地址,对其解引用拿到首元素 |
*(&arr) | 对整个数组解引用,循环打印出数组每个值 |
二维数组
二维数组必须初始化列数
int arr[3][4]
二维数组类似矩阵,但仍是线性存储;
主数组有3个元素,每个元素是有4个元素的数组,主数组中元素类型是数组类型;
二维数组是一维数组的数组
二维数组中,arr代表了第一行的元素(值是a[0][0]的地址)
解引用的值是a[0][0]
字符类型存储
数组中,按定义方法分为为字符数组与其它类型的数组,
c语言并没有字符型的数据类型,只能将字符或字符串按两者形式存储: