C语言指针做函数参数,指针做函数返回类型

有时候我们可以使用函数的返回值来回传数据,在简单的情况下是可以的,但是如果返回值有其它用途(例如返回函数的执行状态量),或者要回传的数据不止一个,返回值就解决不了了,所以要引用上指针来传递。
指针做函数参数:
在c语言中,函数的参数不仅可以是整数、小数、字符等具体的数据,还可以是指向它们的指针。用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以访问到函数外部的数据,并且这些数据不会随着函数的结束而被销毁。像数组、字符串、动态分配的内存等都是一系列数据的集合,没有办法通过一个参数全部传入函数内部,只能传递它们的指针,在函数内部通过指针来影响这些数据集合。有的时候,对于整数、小数、字符等基本类型数据的操作也必须要借助指针,一个典型的例子就是交换两个变量的值:
#include void swap(int a, int b){int temp; //临时变量 temp = a; a = b; b = temp;}int main(){int a = 66, b = 99; swap(a, b);printf(a = %d, b = %d, a, b);return 0;}/* 从结果可以看出,a、b 的值并没有发生改变,交换失败。这是因为 swap() 函数内部的 a、b 和 main() 函数内部的 a、b 是不同的变量,占用不同的内存,它们除了名字一样,没有其他任何关系,swap() 交换的是它内部 a、b 的值,不会影响它外部(main() 内部) a、b 的值。他们会随着函数段的结束而失去了作用域  
利用指针:
#include void swap(int *p1, int *p2){//这里接收到的是a和b的地址int temp; temp = *p1;//利用地址将值做修改 *p1 = *p2; *p2 = temp;}int main(){int a = 66, b = 99; swap(&a, &b);//这里将a和b的地址获取传入printf(a = %d, b = %d, a, b);return 0;}//函数运行结束后虽然会将 p1、p2 销毁,但它对外部 a、b 造成的影响是“持久化”的,不会随着函数的结束而“恢复原样”。因为我们对它做的是进入到地址的修改  
用数组做函数参数:
如果一个函数按值传递数组,则必须分配足够的空间来存储原数组的副本,然后把原数组的所有数组拷贝到新的数组中去,如果把数组的地址传递给函数,让函数来直接处理原来数组则效率要高。
但是 传递地址的时候,总会导致一些问题,c通常安值传递数据,因为这样做可以保证数据的完整性,如果函数使用的是原始的数组的副本,就不会发生修改原始数据,但是,处理数组的函数通常都需要使用原始数据,因此这样的函数可以修改原数组,有时,这正是我们需要的:void add(double a[ ],int n,int b);  调用此函数,将可以将原来数组的值进行修改,也可以说是函数通过指针,直接将原数组做修改了
数组是一系列数据的集合,无法通过参数将它们一次性传递到函数内部,如果希望在函数内部操作数组,必须传递数组指针。下面的例子定义了一个函数 max(),用来查找数组中值最大的元素:
#includeint max(int len, int a[]);//声明 注意这里的a[ ] 里边没有任何东西,其实也可以放东西也可以不放的/*实际上这种形式的数组定义都是假象,不管是int a[100]还是int a[]都不会创建一个数组出来,编译器也不会为它们分配内存,实际的数组是不存在的,它们最终还是会转换为int *intarr这样的指针。这就意味着,两种形式都不能将数组的所有元素“一股脑”传递进来,大家还得规规矩矩使用数组指针。*///真正传递的数组可以有少于或多于 100 个的元素。int main(void) {int n;int a[100];int i;scanf(%d, &n);for (i = 0; i < n; i++) {scanf(%d, a+i);//给数组里边的值初始化 } //这个a的原型是 int *a //所以这里可以使用 &a[i] 或者 a+iprintf(max=%d, max(n,&a));return 0;}int max(int len, int a[]) {//定义int t = a[0];int i;for (i = 1; i < len; i++) {//依次比较if (t strlen(strl2)) {//比较长度 谁长返回谁return strl1; }else {return strl2; }}  
       用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,c语言没有任何机制来保证这些数据会一直有效,它们在后续使用过程中可能会引发运行时错误 ,  但是,这里所谓的销毁并不是将局部数据所占用的内存全部抹掉,而是程序放弃对它的使用权限,弃之不理,后面的代码可以随意使用这块内存 , 如果使用及时也能够得到正确的数据,如果有其它函数被调用就会覆盖这块内存,得到的数据就失去了意义。而覆盖它的究竟是一份什么样的数据我们无从推断(一般是一个没有意义甚至有些怪异的值)。
#include int *func(){int n = 100;return &n;}int main(){int *p = func(), n; n = *p;printf(value = %d, n);//因为前面没有覆盖,所以还是能得到之前的值return 0;} ******与下面比较:******#include int *func(){int n = 100;return &n;}int main(){int *p = func(), n;printf(c.biancheng.net);//这里会覆盖掉 n = *p;printf(value = %d, n);//所以输出的值会无从得知return 0;}  
还应该注意函数指针变量的调用:
分析函数指针变量不能进行算术运算,这是与数组指针变量不同的。数组指针变量加减一个整数可使指针移动指向后面或数组元素,而函数指针的移动是毫无意义的。函数调用中“(* 指针变量名)”的两边的括号不可少,其中的“*”不应该理解为求值运算,在此处只是一种表示符号。要把“z= * pomax(x,y);”改成“z=(*pomax)(x,y);”。


NVIDIA 与 Ampere Computing 携手创建用于云游戏的Arm 架构云原生服务器平台
高度集成的MAX2830 RF收发器解决方案
AS-Interface总线技术的特点及残极洗涤堆垛机组ASI系统的设计
iPhone秀
激光技术在动力电池加工上的应用
C语言指针做函数参数,指针做函数返回类型
高通司宏国:5G+无界XR,产业发展新方向
特斯拉将收购通用汽车关闭的工厂
5G商用面临哪些拦路虎
太阳能控制电路
需要了解Linux的硬链接与软链接
数控机床机械手的主要组成部分
R型试验变压器有什么特点?
介绍信号完整性的另一个要素—芯片
什么是嵌入式操作系统,它由哪些组件构成
【Purple Pi OH RK3566 Harmony开发板】OpenHarmony音频播放应用
为什么锡膏使用前一定要搅拌回温?
电子分频前后级放大器后级部分(三)
现代高层正纠结是否为苹果代工汽车
作为一名程序员到底有多难