数组
数组对我们来说是很方便的,它可以很好的帮我们存储一组类型相同的元素,让我们可以很方便的去调用它们,不过数组的“规矩”也不少。
数组的创建和初始化
一维数组的创建和初始化
(数组数据类型)int arr[]={0};
这样既完成了数组的创建也完成了数组的初始化。
初始化就是在创建数组时同时给它的内容一些合理的初值。
如果你在创建,初始化的时候不指定数组的长度,它就会根据你初始化的大小默认你的数组长度。像我创建的arr[]就是只有一个元素,长度为一。
⚠️指定的数组的长度必须是常量
int arr1[]={0,1,2,0,0};
int arr2[]={0,1,2,3,4,5,6,7,0,0};
int arr3[5]={0,1,2};
int arr4[10]={0,1,2,3,4,5,6,7};
这前两个初始化的结果和后两个其实分别是一样的,前两个是数组的完全初始化,后两个则是部分初始化,给定数组的长度并给定一部分元素的值,未给出的元素的值就自动用0来填补。
⚠️和字符,字符串有关的数组在内存中的存储方式很特别,要特别注意
char arr1[]="abc";
char arr2[3][1]={"a","b","c"};
char*p="abc";
二维数组的创建和初始化
创建
int arr1[3][4]
int arr2[5][5]
int arr3[9][10]
初始化
int arr1[3][4]={1,2,3,4,5,6};
int arr1[3][4]={(1,2),(3,4)};
int arr[][5]={(1,2),(3,4)};
和一维数组一样可以部分初始化
数组的使用
有一个操作符”[ ]”(下标引用操作符),就是进行数组访问的操作符
#include <stdio.h>
int main()
{
int arr[5]={0};
int i=0;
int sz = sizeof(arr)/sizeof(arr[0]);
for(i=0;i < sz;i++)
{
arr[i]=i;
}
for(i=0;i < sz;i++)
{
printf("arr = %d",arr[i]);
}
return 0;
}
数组的访问总是通过下标来实现的,并且下标总是从0开始的。数组的大小是可以计算的得知的,循环体的循环次数应该用计算得来的元素来表示而不是一个常量。
int main()
{
int arr[][5]={(1,2),(3,4)};
int i=0;
for(i=0;i <2 ;i++)
{
int j = 0;
for(j = 0;j < 5;j++)
{
a[I][j]=i+j;
}
}
for(i=0;i <2 ;i++)
{
int j = 0;
for(j = 0;j < 5;j++)
{
printf("arr[%d][%d]=%d",i,j,arr[i][j]);
}
printf("\n");
}
return 0;
}
在内存中的存储
一维数组
#include<stdio.h>
int main()
{
int arr[]={1,2,3,4,5};
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;
}
运行结果如下
二维数组
int main()
{
int arr[][5]={(1,2),(3,4)};
int i=0;
for(i=0;i <2 ;i++)
{
int j = 0;
for(j = 0;j < 5;j++)
{
printf("&arr[%d][%d]=%p\n",i,j,&arr[i][j]);
}
}
return 0;
}
运行结果如下
由此我们可以看出二维数组在内存中也是连续存放的,它将第一行(arr[0])看作是第一个元素,以每一行为元素连续排列在内存中。
指针访问
一维数组的指针访问
数组名就相当于数组首元素的地址,我们知道了一个首元素的地址并且它是连续存放的,那我们就可以很方便的找出其中的每一个元素,这时候我们可以应用指针变量来很好的解决这个问题,数组名+整数就可以获取到整个数组的元素。
int main()
{
int i=0;
int arr[5]={1,2,3,4,5};
int sz = sizeof(arr)/sizeof(arr[0]);
for(i=0;i < sz;i++)
{
printf("&arr[%d] = %p\n",i,&arr[i]);
printf("%p\n",arr+i);
}
return 0;
}
运行结果如下
二维数组的指针访问
有关数组的运算
只有两种情况下数组名代表整个数组
sizeof(数组名),计算这个数组的大小
&数组名,取出整个数组的地址
其余情况下都位数组首元素的地址
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a+0));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(a[1]));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1));
printf("%d\n",sizeof(&a[0]));
printf("%d\n",sizeof(&a[0]+1));
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));
数组作为函数参数
数组作为函数参数时,传参数并不是将整个数组传过去而是传递数组首元素的地址,所以在传参的时候必须将数组的大小一并传过去,函数内部无法计算数组大小。