指针详解 第二讲
数组名的理解
使用指针访问数组的内容时,有这样的代码
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = &arr[0];
使用数组名和数组首元素写一个代码做一个测试
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("&arr[0] = %p\n", &arr[0]);
printf("arr = %p\n", arr);
return 0;
}

通过观看运行结果可以看出来数组名和数组首元素地址打印出来的结果一模一样,数组名就是数组首元素(第一个元素)的地址。
但是如果说数组名就是数组首元素的地址,那下面的代码应该怎么理解呢?
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("%zd", sizeof(arr));
return 0;
}

输出的结果是40,如果数组名是数组首元素的的地址,那么应该输出4/8才对。
是因为对于数组名就是数组首元素的地址有两个例外。
- sizeof(数组名),sizeof中单独存放数组名,这里表示的是整个数组,计算的是整个数组的大小,单位是字节。
- &数组名,这里的数组名表示整个数组,取得是整个数组的地址(整个数组的地址和首元素的地址是有区别的)。整个数组的地址是一个数组指针 然后数组首元素地址一个一级指针 整个数组的地址+1跳过一整个数组组首元素地址+1 跳过数组中的一个元素
- 除此之外,任何地方使用数组名都表示首元素的地址。
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("&arr[0] = %p\n", &arr[0]);
printf("&arr[0]+1 = %p\n", &arr[0]+1);
printf("arr = %p\n", arr);
printf("arr+1 = %p\n", arr+1);
printf("&arr = %p\n", &arr);
printf("&arr+1 = %p\n", &arr+1);
return 0;
}

这⾥我们发现&arr[0]和&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,是因为&arr[0] 和 arr 都是⾸元素的地址,+1就是跳过⼀个元素。但是&arr 和 &arr+1相差40个字节,这就是因为&arr是数组的地址,+1 操作是跳过整个数组的。到这⾥⼤家应该搞清楚数组名的意义了吧。
数组名是数组⾸元素的地址,但是有2个例外。
使用指针访问数组
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
//输⼊
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
//输⼊
int* p = arr;
for (i = 0; i < sz; i++)
{
scanf("%d", p + i);
//scanf("%d", arr+i);//也可以这样写
}
//输出
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
一维数组传参本质:一维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。
二级指针
指针变量也是变量,是变量就要有地址,那指针变量的地址存放在哪里呢?就是我们搜说的二级指针了。
#include <stdio.h>
int main()
{
int a = 10;
int* pa = &a;
int** ppa = &pa;//二级指针
return 0;
}

int b = 20;
*ppa = &b;//等价于 pa = &b;
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;
*ppa 通过对ppa中的地址进⾏解引⽤,这样找到的是 pa , *ppa 其实访问的就是 pa 。
**ppa 先通过 *ppa 找到 pa ,然后对 pa 进⾏解引⽤操作: *pa ,那找到的是 a 。
指针数组

指针数组的每个元素都是⽤来存放地址(指针)的。

指针数组的每个元素是地址,⼜可以指向⼀块区域。
指针数组模拟⼆维数组
#include <stdio.h>
int main()
{
int arr1[] = {1,2,3,4,5};
int arr2[] = {2,3,4,5,6};
int arr3[] = {3,4,5,6,7};
//数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中
int* parr[3] = {arr1, arr2, arr3};
int i = 0;
int j = 0;
for(i=0; i<3; i++)
{
for(j=0; j<5; j++)
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
return 0;
}

- parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型⼀维数组,parr[i][j]就是整型⼀维数组中的元素。
- 上述的代码模拟出⼆维数组的效果,实际上并非完全是⼆维数组,因为每⼀行并非是连续的。
有问题评论区留言谢谢

被折叠的 条评论
为什么被折叠?



