C语言-通过指针引用数组的知识框架

本文详细介绍了如何使用指针操作数组元素,包括一维和多维数组。从指针的基本概念出发,逐步深入到指针的运算、通过指针引用数组元素的方法、用数组名作为函数参数的技巧,以及通过指针引用多维数组的技术细节。

目录


前言

指针变量本质上是变量,首先就是要定义指针变量,基本格式为: 类姓名 * 指针变量名(例如:int *p),定义指针变量的同时,要对指针变量进行赋值,否则,这个指针就有可能指向隔壁老王家的门,从而会犯错误(Error!)

关于指针变量(指针指向变量)在指针部分属于比较简单内容,可自行学习。以下是在指针变量的基础上,研究通过指针指向数组的问题。

1.数组元素的指针

int a[5] = { 1,5,8,9,10 };
int* p;//定义了一个指针
p = &a[0];//其实是给p进行了赋值,让他指向a[0]的地址,不让他指向隔壁老王家

//p的初始地址也可以表示成:
int* p;
p = a;
//也可以合并成一行

2.引用数组元素指针的运算

//地址的运算
p + 1;//指向同一数组的下一个元素的地址
p - 1;
p++; ++p;
p--; --p;

//表示以上地址里边的值,加个*就行了
//*号只有在定义的时候,代表把这个变量p定义成指针变量
//除此之外,*号就表示这个地址里边的值【在一维数组可以这样理解】

int a[5] = { 1,5,8,9,10 };
int* p;//定义了一个指针
p = &a[0];
*(p + 1);//p指向a[0]的地址,p+1指向a[1]的地址。那么*(p + 1)就是a[1]的值
int a[5] = { 1,5,8,9,10 };
int* p;//定义了一个指针
p = &a[0];
*(p++);//p++的运算结果是p,所以代表*(p++)对应的是a[0]的值,同时p变成了指向a[1]的地址

3.通过指针引用数组元素

不用指针:a[i];

用指针变量p:*(p+i);或者*(a+i);

4.用数组名作函数参数

数组名作为函数实参,传递到调用函数时,实际上传的是数组的首地址,那么没学指针以前,我们形参也用了一个数组接收,但是接收首地址,其实用指针比较方便,因此我们在形参的时候定义了一个指针变量用来接收数组的首地址,那么在调用函数的时候,对形参指针p的改变,也就实现了对数组的改变。

这个时候就不需要再对形参指针定义了,因为已经传过来了形参的首地址,实参和形参之间已经完成了定义,就不会指向隔壁老王家了。

归纳:如果有一个实参数组,要想在函数中改变此数组元素中的元素的值,实参与形参有四种可能:

 形参和实参都用数组名;实参用数组名,形参用指针;

实参形参都用指针变量;实参为指针变量,形参用数组名;

 5.通过指针引用多维数组

1-4是利用指针引用多维数组,以下开始用指针变量指向多维数组中的元素。

1)多维数组元素的地址

 //定义一个二维数组a[i][j]
a:首行地址;     a[i]:i行0列元素地址;     a+i:i行的首地址

&a[i]:i行首地址  相对于扩大了范围;

*(a+i):i行0列元素地址

//按照刚才的定义在地址的基础上再加一个*就表示这个地址对应的元素的值。例如*((a+i)+j)表示i行j列元素的地址;*(*((a+i)+j))就表示i行j列元素的值。

2)指向多维数组元素的指针变量

(1)指向数组元素的指针变量

p=a[0];//0行0列的元素地址

p+(i*m+j)//指向i行j列的元素的地址,前边再加上*表示具体的值

 (2)指向由m个元素组成的一维数组的指针变量

int(*p)[4]//数据类型是int (*)[4]型

p=a//初始化赋值,这里要求赋值,p的初始值应该是,二维数组首行的地址 ,所以是a,也可用&a[0];

3)用指向数组的指针作函数参数

前面我们形参用指针去接收实参传来的地址,当然,如果说是一个二维数组,实参传的是首行的地址,这时候形参就要用int(*p)[]去接收这一行的地址。

实例:班级内3名同学,四门工科,组成了一个二维数组,计算二维数组的平均数,也就是所有科目的平均成绩(尽管没有实际意义,但是是为了说明形参指针接收单个元素的地址),第二个问题就是要输出第i个学生的四门成绩(这里很明显就要用到行地址指针来接收。)

#include<stdio.h>

int main()
{
	void average(double* q, int num);
	void search(double(*q)[4], int n);

	double* p;
	double(*p1)[4];
	double score[][4] = { {65,67,90,60},{58,98,56,99},{96,89,87,99} };
	p = score[0];//初始化定义的是0行0列的元素的地址
	p1 = score;//初始化定义的是0行元素的地址
	average(p,12 );//传的实参是p,也就是score[0][0]的地址
	search(p1, 3);//传的p1,是0行的首地址
	return 0;
}

void average(double* q, int num)//形参用指向变量的指针变量
{
	double sum = 0,aver = 0;
	double* q_end;
	q_end = q + 11;

	for (; q <=q_end; q++)
	{
		sum += *q;
	}
	aver = sum / num;
	printf("平均分为:%.3f", aver);
}

void search(double(*q1)[4], int n)//形参用指向一维数组的指针变量
{
	int i;
	printf("请输入你想查询的同学序号:");
	scanf("%d", &i);
	for (int j = 0; j < 4; j++)
	{
		printf("%5.1f", *(*(q1 + i - 1) + j));
	}
}

欢迎交流!下一篇是“通过指针实现对字符串的引用”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值