指针(二)

1.使用指针访问数组

有了前面的知识,我们就可以用指针来访问数组了。但在此之前,我们得知道数组名蕴含的意义。

首先,我们来分析如下代码

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%p\n", arr);//
	printf("%p\n", &arr[0]);//数组arr首元素的地址
	return 0;
}

上述代码,%p这个占位符是用来打印地址的,我们发现打印arr(数组名)&arr[0]的地址是一模一样的,我们就得出结论,数组名本身就是地址且是数组首元素的地址。

但是有两个例外:

1)sizeof(数组名) :sizeof里面直接放数组名,这里的数组名表示的是整个数组,计算的整个数组的大小

2)&数组名:这里的数组名表示的也是整个数组,取出的是整个数组的地址。

代码演示:

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", sizeof(arr[0]));//计算数组首元素的大小
	printf("%d\n", sizeof(arr));//计算整个数组的大小
	printf("%p\n", &arr[0]);//打印数组首元素的地址
	printf("%p\n", &arr);//打印整个数组的地址
	return 0;
}

 

 

上述代码的结果清晰地解释了第一个例外,但是我们可以看到&arr(整个数组地址)&arr[0](数组首元素地址)打印出的地址怎么都一样啊,这时我们又纳闷了:&arrarr有啥区别啊,不急我们做如下测试:

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%p\n", arr);
	printf("%p\n", arr + 1);
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr[0] + 1);
	printf("%p\n", &arr);
	printf("%p\n", &arr + 1);
	return 0;
}

 

从上述结果可以看出例外一是正确的,arr和&arr[0]都是首元素的地址,+1表示跳过1个元素,也就是跳过4个字节,而&arr取出的是整个数组的地址,+1表示跳过整个数组,也就是跳过40个字节。

总结:数组名表示首元素地址,但是有两个例外,一个是sizeof(arr),另一个是&arr

数组名了解完,我们就可以使用指针来访问数组了。

代码如下:

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = arr;
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		scanf("%d", p + i);
		/*scanf("%d",arr+i);*/
	}
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
		/*printf("%d ",p[i]);*/
	}
	printf("\n");
	return 0;
}

 

从上述结果看出,我们成功地使用指针访问了数组,我们再深入分析一下,arr代表 的是数组首元素的地址,它可以赋值给p,那是不是parr就等价呢?答案是对的,之前我们学数组的时候,可以通过下标来访问数组,也就是arr[i]来访问数组,那是否可以改成p[i]来访问数组呢?答案也是对的。

代码如下:

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = arr;
	int i = 0;
	for (i = 0; i < sz; i++)
	{
	/*	scanf("%d", p + i);*/
		scanf("%d",arr+i);
	}
	for (i = 0; i < sz; i++)
	{
		/*printf("%d ", *(p + i));*/
		printf("%d ",p[i]);
	}
	printf("\n");
	return 0;
}

 

2.指向指针的指针 (二级指针)

我们通过指针来访问变量叫做间接访问,由于指针变量直接指向要访问的变量,成为“单级间址”的间接访问,那如果通过指向指针的指针变量来访问要访问的变量,这就是“二级间址”的间接访问,也叫二级指针,也就是指针变量存放的地址。

例子

#include <stdio.h>
int main()
{
    int a = 10;
    int* p = &a;
    int** pp = &p;
    return 0;
}

 

 

p是指向变量a的指针变量,pp是指向指针p的指针变量。

二级指针里的一些运算:

1)*pp表示的是对pp地址的解引用,相当于指针变量p;

2)**pp表示的是先通过*pp来找到指针变量p,然后再通过解引用*p来找到a

3.指针数组 

我们可能一开始看到这个指针数组,不知道它是指针还是数组,我们可以通过类比来判断,之前我们学习了数组,数组里面有整型数组,它是存放整型变量的数组,字符数组是存放字符变量的数组,那么我们可以判断出指针数组是存放指针类型变量的数组。

 

4.指针数组模拟实现二维数组

 

上面我们已经知道指针数组的概念,那么我们可以用指针数组来模拟实现一个二维数组,将二维数组打印在屏幕上。

代码如下:

#include <stdio.h>
int main()
{
	int arr1[] = { 1,1,1,1 };
	int arr2[] = { 2,2,2,2 };
	int arr3[] = { 3,3,3,3 };
	int *arr[3] = { arr1,arr2,arr3 };//数组名表示首元素的地址,类型为int*,可以存放在指针数组arr中
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 

上述代码成功使用指针数组模拟出了二维数组 ,但由于每行未必连续,所以不一定是二维数组。

 

 

 

经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值