通过对上节课的学习,我们已经对指针有了初步的了解,现在让我们看看指针有哪些应用吧
1.传递参数
1.1使用指针传递大容量的参数
下面让我们用一个简单的例子对比一下,来说明一下问题吧,在这里我们先用变量赋值的方式:
#include "stdio.h"
void Tran(int para)
{
sprintf("para = %x\n",para);//把para指向的地址的数据打印出来,也就是a的值
}
int main(void)
{
int a = 0x55;
Tran(a);//把a的值传给para
return 0;
}
接下来,让我们使用指针的方式寻找数组a里面的最大数,并让指针指向我们要打印的内容:
#include "stdio.h"
int FindMAx(const int *para,int length) //const表示只读 防止子程序修改数据
{
int i = 0;
int max;
max = para[0];
for(i = 1;i<length;i++) //注意:数组的第i个数->数组的第i-1
{
if(para[i] > max)
max = para[i]; //刷新最大值
}
return max;
}
int main(void)
{
int a[] = {12,34,56,78,56,34,12};
int MAX;
MAX = FindMax(a,7);
printf("MAX = %d\n",MAX);
return 0;
}
通过这个例子,我们就可以看出来指针的优越之处,如果我们还是选择简单的变量之间的赋值,就会占用很多空间,并且现在仅仅只是一个数组,字节数也不是太多,那如果以后遇到一些更大的呢?几千几万个字节,那岂不是在白白浪费内存啦~并且在单片机的学习之中学会使用指针,会方便我们对函数封装,用的时候在主函数调用下就可以了,大大减轻cpu的负担
1.2使用指针传递输出函数
在C语言设计中有一个弊端,就是函数只能返回一个值,那么我们就可以利用主函数和子函数共用一套数据的特性,来实现返回多个值的设计:
#include "stdio.h"
void FindMaxAndCount(int *max,int *count,const int *para,int length) //寻找最大值和最大值出现的次数
{
int i = 0;
*max = para[0]; //改变主函数变量MAX的值
*count = 1;
for(i = 1;i<length;i++) //注意:数组的第i个数->数组的第i-1
{
if(para[i] > max)
{
*max = para[i]; //刷新最大值
*count = 1; //改变主函数变量Count的值
}
if(para[i] == max)
*count++;
}
}
int main(void)
{
int a[] = {12,34,56,78,56,34,12};
int MAX;
int Conut;
FindMaxAndCount(&MAX,&Count,a,7); //改变主函数变量的值
printf("MAX = %d\n",MAX);
printf("Count = %d\n",Count);
return 0;
}
2.传递返回值
在模块化编程中,为了方便对外设进行封装,也为了便于主函数调用,我们常常使用指针达到这个目的:
假设下面是外设的封装函数:
int Time[] = {23,59,55};
int *GetTime(void) //定义一个返回值为指针变量的函数(也可以当作是要传递的变量的首地址)
{
return Time; //返回需要传递函数的首地址
}
现在我们想在主函数中获取时间:
#include "stdio.h"
int main(void)
{
int *pt; //定义一个指向time的指针
pt = GetTime(); //获取Time的首地址
sprintf("pt[0] = %d\n",pt[0]);
sprintf("pt[1] = %d\n",pt[1]);
sprintf("pt[2] = %d\n",pt[2]);
return 0;
}
其中,需要注意的就是不要传递一个局部变量的地址,因为在函数运行之后局部变量的值会被擦除,导致我们读出来的数不正确;
总结
在学习的最后,我个人认为在接触相对简单的函数来说,定义的一个指针变量p就相当于是某个数据的首地址,*p或者p[]就是查看数据的内容,这样理解起来就是会简单很多。