数组指针问题
一、一维数组、二维数组
- 数组
C语言标准规定 当数组名作为数组定义的标识符或者sizeof的操作数或者&的操作数的时候,数组名才会表示整个数组本身,在其他表达式中,数组名会被转换为指向第0个元素的指针
//定义一个一维数组
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d\n",arr);
printf("%d\n",&arr);
printf("%d\n",&arr[0]);
//输出为:
11532380
11532380
11532380
//结论:在数组中数组名就是数组中第一个元素的地址。数组名可以看作一个指针。
*************************************************************************************
//定义一个一维数组
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d\n",arr);
printf("%d\n",arr+1);
printf("%d\n",&arr+1);
printf("%d\n",&arr[0]+1);
//输出为:
5963088
5963092
5963128
5963092
//结论:我们可以看到第三个输出比第一个大了40,所以虽然&arr也是输出数组的首地址,但是&arr表示整个数组,我们给&arr+1会看到它的地址增大40,移动到了数组最后一个元素的后面。而arr+1和&arr[0]+1只是增大4,移动到了数组的第二个元素处。
- 二维数组
//定义一个二维数组
int arr[2][3]={1,2,3,4,5,6};
printf("%d\n",arr);
printf("%d\n",&arr);
printf("%d\n",arr[0]);
printf("%d\n",&arr[0]);
printf("%d\n",&arr[0][0]);
//输出为:
2227336
2227336
2227336
2227336
2227336
//结论:无论是一维数组还是二维数组还是几维数组,只要是数组,数组名就是数组的首地址。
*************************************************************************************
//定义一个二维数组
int arr[2][3]={
{1,2,3},
{4,5,6},
};
printf("%d\n",arr);
printf("%d\n",arr+1);
printf("%d\n",&arr+1);
printf("%d\n",arr[0]+1);
printf("%d\n",&arr[0]+1);
printf("%d\n",&arr[0][0]+1);
//输出为:
12123344
12123356
12123368
12123348
12123356
12123348
//结论:二维数组中虽然arr、&arr、&arr[0]都是二维数组的首地址,但是其中arr和&arr[0]都代表一整行,&arr代表整个二维数组,arr[0]代表一个int。
二、指向数组元素的指针、数组指针、指针数组
- 指向数组元素的指针:它指向的是数组中的元素
//定义一个一维数组
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int* p=arr;
int* p1=&arr;
printf("%d \n", p);
printf("%d \n", p1);
printf("%d \n", p+1);
printf("%d \n", p1+1);
//输出为:
19920880
19920880
19920884
19920884
//结论:指向数组的指针,是指向数组的第一个元素的地址,指针移位也是一次移动int的字节数4个。
*************************************************************************************
//定义一个二维数组
int arr[2][3]={
{1,2,3},
{4,5,6},
};
int* p=arr;
int* p1=&arr;
int* p2=arr[0];
int* p3=&arr[0];
int* p4=arr[0][0];
printf("%d\n",p);
printf("%d\n",p1);
printf("%d\n",p2);
printf("%d\n",p3);
printf("%d\n",p4);
//输出:
4126964
4126964
4126964
4126964
1
//结论:指针指向二维数组是输出的是二维数组的首地址。
*************************************************************************************
//定义一个二维数组
int arr[2][3]={
{1,2,3},
{4,5,6},
};
int* p=arr; //错误的操作,因为arr是一个二级指针,p是一级指针,虽然可以指向,但是会警告
int* p1=&arr; //错误的操作,因为arr是一个二级指针,p1是一级指针,虽然可以指向,但是会警告
int* p2=arr[0]; //正确,p2指向数组的第一行,p2+1也就是arr[0]+1也就是移位一个int大小的字节。
int* p3=&arr[0];//错误的操作,因为arr是一个二级指针,p是一级指针,虽然可以指向,但是会警告
int* p4=&arr[0][0];//正确,指向第一行第一列的元素的地址,p4+1就是移位一个int大小
printf("%d\n",p);
printf("%d\n",p+1);
printf("%d\n",p1+1);
printf("%d\n",p2+1);
printf("%d\n",p3+1);
printf("%d\n",p4+1);
- 数组指针:它指向的是一个数组。
//定义一个一维数组
int a[5]={1,2,3,4,5};
//定义一个数组指针
int (*p)[5]=a;//错误的赋值方法,p是一个二级指针,a是一个一级指针,所以我们要用一级指针的地址给p赋值
int (*p)[5]=&a;//正确的赋值方法
*************************************************************************************
//定义一个二维数组
int arr[2][3]={
{1,2,3},
{4,5,6},
}
int (*p)[3]=arr;//我们可以把arr这个数组看成两个一维数组,a[0]、a[1]这两行,而p就是指向的a[0]这一行,所以p+1,就指向了a[1]这一行。
printf("%d\n",p);
printf("%d\n",p+1);
//输出为:
14547600
14547612
三、数组作为函数的参数传递会被弱化为指针
//深入理解数组作为参数传递进入函数会被弱化为指针
void test(int* arr)
{
printf("%d\n",sizeof(arr));
}
void test1(int a[10])
{
printf("%d\n",sizeof(a));
}
int main()
{
int num[10]={1,2,3,4,5,6,7,8,9,10};
test(num);
test1(num);
printf("%d\n",sizeof(num));
return 0;
}
//输出结果:
4
4
40
//结论:数组传进函数中会被弱化为指针,我们可以看到无论形参是指针类型还是数组,我们sizeof他们都是4字节,这是因为指针类型的大小就是4字节。而我们直接sizeof(num)就是整个数组的大小。