目录
介绍
数组,一组相同类型的元素集合。
一、数组的创建方式
type_t arr_name [const_n];
//type_t 是数组类型
//arr_name 是数组名
//const_n 是常量表达式,用来表示数组的大小
二、数组的初始化
int arr[10]={1,2,3};
//不完全的数组初始化
//相当于在一个可以放置十个鸡蛋的篮子内只放置了三枚鸡蛋
//而其余的七枚鸡蛋由0代替
//进而可以理解为,只初始化了三个元素
//而其余的七个未被初始化的元素用0代替
int arr2[] = {1,2,3}
int arr3[5] = {1,2,3,4,5}
char ch1[5] = {'98','a','z'}
char ch2[] = "abc"
//ch2 和 ch3 表面上看似只有 a,b,c 三个字符
//但实际上,ch2是放置了一个字符串在其中
//而字符串的效果则是自带一个结束标志,也就是\0
char ch3[] = {'a','b','c'}
//ch2 内的元素:a,b,c,\0
//ch3 内的元素:a,b,c
//且不仅元素数量并不相同,就连占据的字节数量也不同
三、数组的下标
int arr [10] = {1,2,3,4,5,6,7,8,9,10}
//将数组的元素全部铺开:
// 1 2 3 4 5 6 7 8 9 10
//在数组中,不论是一维数组还是二维数组,数组的下标由0开始
// 0 1 2 3 4 5 6 7 8 9
//所以,数组的下标 就是数组的大小减去1
//int arr[10] 中的10 表示的是数组的大小,亦或者说数组中元素的个数
//记住 在 int arr [10] 中是绝对不能出现arr[10]
//int arr[10] 中的10 表示的是数组的元素个数或者数组大小
//arr[10] 表示的是在一个名为arr的数组中 的一个下标为10的元素 10表示下标
//[] ——是下标操作符,括号内放置的是常量,而不是变量
//或者说,[]内是否可以放置变量,由编译器的标准决定
//在c99标准之前,[]内放置的必须是常量或者是常量表达式
//列如 arr[3+5] arr[3*5]
//但是在c99标准之后,[]内可以放置变量,以此来支持变长数组
//列如:
int main()
{
int n = 10;
int arr[n] ={1,2,3,4,5,6}
return 0;
}
数组的大小——函数sizeof的使用
//求数组的大小或者说求数组内元素的个数,我们可以使用函数sizeof
//sizeof 是一种计算内存大小的函数
//列如:
int arr[] = {1,2,3,4,5,6,7,8,9,10,100,99,5,522,66,11,6};
int sz = sizeof(arr)/sizeof(arr[0]);
//由数据的类型,我们可以知道,int类型占据的是四个字节,char占据的是1个字节
//float 占据的是四个字节,double占据的是八个字节·······
//而arr是数组名,在sizeof中相当于整个数组
//所以 sizeof (arr) 表示的是整个数组的字节
//而 arr[0] 所代表的是在arr数组中 下标为0 的元素
//所以 sizeof (arr[0]) 是在代表数组中一个元素所占据的字节数
//通过数学的计算和逻辑,我们因此可以得到数组的大小
四、数组的每个元素地址
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int sz = sizeof(arr)/sizeof(arr[0]);
for(int i = 0;i<sz;i++) //i表示下标
{
printf("&arr[i] = %d",arr[i]);//取数组的每一个元素的地址
}
return 0;
}
通过取地址,以及每个元素的地址与地址之间的差异我们得知了,整个数组是一个连续的数组!且数组的地址是使用十六进制的序列进行表达的。
列如 arr[0]的地址和arr[1]的地址之间,相差了四个字节,而arr[1]和arr[2]之间也像相差了四个字节 ,且十六进制的序列越往后越大,以此类推。
五、数组名与地址
//数组名
//在C语言中,数组名能够表达数组中首个元素的地址
//列如:
printf("%d",arr);
printf("%d",&arr[0]);
printf("%d",&arr)
arr——数组名 ——可表示数组首个元素地址
&arr[0] ——数组首个元素地址
&arr ——&数组名 ——表示整个数组,取的是整个数组的地址
但是三者的值一样!因为数组的地址也是从数组的首个元素开始。
以此我们得知,数组名确实能够代表数组的首个元素地址。
但是,有两个例外,第一是 &数组名 表示的是整个数组的地址!
printf("%p",&arr);
printf("%p",&arr+1);
&arr和&arr+1之间相差了40
(十六进制计算,68-40=28 ,因为是16进制,所以相差0x28,进行十进制转化,相差40,注意0x不用计算)
而整个数组的大小(int类型)也就是40个字节!因此它两相差了一个数组的大小!
所以&arr表达的是数组的地址,但是数组的地址是从数组首个元素地址开始的!
而第二是 sizeof(数组名) 这里的数组名代表的是整个数组,计算的是整个数组的大小,单位是字节。
printf("%d",sizeof(arr));
而关于 arr 和arr+1 、&arr[0]和&arr[0]+1 、&arr 和 &arr+1 三者区别如下图所示:
如图得知 arr 和arr+1 、&arr[0]和&arr[0]+1 表达的结果是一样的,都是表达首元素地址以及首元素地址的后一位元素的地址。
六、数组名与指针
通过数组名与地址,我们明白了arr和arr[0]可以代表数组首元素的地址。
而地址可以寄存在指针变量中,我们通过指针变量的调动从而使用数组。
例如:
前提,我们要先知道,arr是表示首元素地址,而 * (arr)表示arr首元素的地址所指向的元素,通俗说,就是表示首元素。
也因此 *(arr+i)中的 arr 表示首元素的地址,也可以表示为arr[0] ,而arr+i则可以表示arr[0]+i或者是arr[ i ] 。
同理下图的表达式也是一个意思
而我们将arr授予一个全新的指针变量,代表数组首元素地址。
p++ 将地址不断地向后移动的同时,*p指向的元素也在不断地朝后移动,直到循环的结束。
同理,根据*(arr+i)的原理,我们还可以写出如下图所示
也根据arr[ i ] 的原理写出 p[ i ]
还可以根据 arr[0] +i 写出p[0]+i