数组小结
一维数组
- 创建及初始化
int arr[10];
char arr[5];
int main()
{
int arr[10];
printf("%d\n",sizeof(arr));//输出40
printf("%d\n",sizeof(int [10]));//输出40
}
int i=10;
int arr[i];//非法表达式,[]中必须是常量或常量表达式,不能为变量
int arr[3]={0,1,2};
char arr[]={'a','b','c'};//strlen(arr)==3
char arr[]="abc";//strlen(arr)==4
int main()
{
char arr[]="abcdef";
char *p="abcdef";
printf("%d\n",sizeof(arr));//7
printf("%d\n",strlen(arr));//6
printf("%d\n",sizeof(p));//4
printf("%d\n",strlen(p));//6
return 0;
}
int main()
{
char arr1[]="abcdef";
char arr2[]="abcdef";
//数组1和数组2分别开辟了内存空间,所存内容相同都为abcdef
char *p1="abcdef";
char *p2="abcdef";
//p1和P2都存a的地址,只存了一份
if(p1==p2)
{
printf("hehe\n");//可以输出hehe
}
if(arr1==arr2)
{
printf("hehe\n");//不能输出hehe
}
return 0;
}
int *p ="abcd";//p中存放的是字符'a'的地址
- 使用
[ ] 下标引用操作符
数组是通过下标来访问的,下标从0开始
#include <stdio.h>
int main()
{
int arr[10]={0};//不完全初始化
int i=0;//做下标
for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
arr[i]=i;//将数组初始化为0-9
}
for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);//输出数组内容
}
return 0;
}
注:数组大小可通过计算得到
int arr[5];
int sz = sizeof(arr)/sizeof(arr[0]);
- 在内存中的存储
int main()
{
int arr[10];
for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("&arr[%d]==%p\n",i,&arr[i]);
printf("&arr[%d]==%p\n",i,arr+i);
//输出完全相同,都为下标为i的地址
}
return 0;
}
注:随数组下标的增长,元素的地址也在有规律的递增
由此得,数组在内存中是连续存放的
- 一维数组的指针访问
int main()
{
int arr[]={0,2,3,4,5,6,7,8,9};
printf("%p\n",arr);
printf("%d\n",*arr);//1
}
注:数组的数组名其实是首元素的地址
通过 * (解引用操作符)来访问变量
int main()
{
int arr[10]={0};
int i=0;
//int *p=&arr[0];
int *p=arr;
for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
*(p+i)=i;//通过指针向数组赋值
}
for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
printf("%d\n",arr[i]);
printf("%d\n",*(p+i));
//输出相同,都为数组内容0-9
}
return 0;
}
注: arr[i] == *(p+i) //都表示第 i 个元素
&arr[i] == p+i //都表示第 i 个元素的地址
二维数组
- 创建和初始化
//创建
int arr[3][4];
char arr[2][3];
double arr[4][5];
//初始化
int arr[3][4]={1,2,3,4};
char arr[2][3]={{1,2},{4,5}};
int arr[][4]={{1,2},{4,5}};
注:数组的行可以省略,列不可省,因为二维数组在内存中是连续存放的,若省掉列数就不能确定每行有几个元素,程序执行时会发生错误。
- 二维数组的使用
int main()
{
char arr[3][4]={0};
printf("%d\n",sizeof(arr));//输出12
return 0;
}
int main()
{
int arr[3][4]={0};
int i=0;
int j=0;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
arr[i][j]=4*i+j+1;//将数组赋初值 1-12
}
}
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
printf("%d\n",arr[i][j]);//输出数组内容 1-12
printf("&arr[%d][%d]==%p\n",i,j,&arr[i][j]);
//打印每个元素的地址
}
}
return 0;
}
- 二维数组的指针访问
int main()
{
int arr[3][4];
//int *p=arr; 指针取出的是数组第一行的地址
int *p=arr[0][0];
for(int i=0;i<12;i++)
{
*(p+i)=i+1;//通过指针向数组赋值 1-12
}
return 0;
}
注:int *p=arr 和int *p=&arr[0][0]是不相同的
前者取出的是首行的地址,后者取出的才是首元素的地址
前者在程序执行时会发生错误,因为等号两边的类型不一致
左边为 int * ——指针类型
右边为 int (*) [4] ——数组指针类型
二维数组的首元素是指第一行,即数组名表示第一行的地址
- 数组作为函数参数
我们知道,数组名在两种情况外都是指向数组首元素的指针,所以,当数组名作为参数传递给函数时,此时,传递的应该是该指针的一份临时拷贝,函数如果执行了下标引用,实际上是对这个指针执行间接访问操作,通过这种间接访问,函数可以访问和修改调用程序的数组元素。
//二者相同
int strlen(char *arr)
int strlen(char arr[])
数组传参一般还需传递数组大小 sz
int sz = sizeof(arr) / sizeof(arr[0]);