**
一、指针函数
**
1、指针函数定义的语法格式:
返回数值类型 *函数名(形参表)
{
函数体语句
}
原来b只能在return_test内部使用,现在一旦返回了b的地址给别的函数,那么别的函数也可以访问b了,无形扩大了b的使用范围
打开注释return &g_a或者return &g_b打印结果是一样的
2、完善:
3、函数,指针,数组
void A(int a[],int length)
等价于
Void A(int *a,int length)
利用两种函数方式打印数组的元素内容,其是一样的
结果如下:
使其元素内容+1操作
可复制代码如下:
#include<stdio.h>
static void print1(int a[],int length)//方式 1
{
for(int i=0;i<length;i++)
printf("a[%d]=%d\n",i,a[i]);
}
static void print2(int *p,int length)//方式2
{
for(int i=0;i<length;i++)
printf("p[%d]=%d\n",i,p[i]);
}
static void add(int *p,int length)//实现数组元素加1
{
for(int i=0;i<length;i++){
p[i]+=1;
printf("add_p[%d]=%d\n",i,p[i]);}
}
int main()
{
int a[]={1,2,3,4,5};
int length=sizeof(a)/sizeof(a[0]);
print1(a,length);
print2(a,length);
add(a,length);
}
**
二、函数指针
**
1、上面的指针函数:
就是一个函数,只是函数的返回值是一个地址而已
例如 int *add(int a ,int b)
2、明确:函数名就是整个函数的首地址
例如:int add(int a,int b)
{
Printf(“……….”);
Printf(“……….”);
Printf(“……….”);
}
结论:add就是函数的首地址,等于add函数中第一条语句printf这条语句的首地址,看到add就是看到了一个地址(32位,4字节)
4、函数指针数据类型声明的语法格式,不会分配内存,大型程序中写头文件中
返回值数据类型 (*函数指针名)(形参表)
例如:int (*pfunc)(int ,int);//pfunc就是一种数据类型,函数指针数据类型
或者
Typedef int (*pfunc)(int ,int);//给函数指着数据类型取别名为pfunc
5、函数指针变量定义的语法格式:函数指针名 函数指针变量
例如:
Pfunc_t pfunc;//定义一个函数指针变量,
//将来保存函数的首地址(pfunc_t是别名)
6、函数指针变量的初始化
pfunc_t pfunc = add; //定义一个函数指针变量并且保存add函数
的首地址,也就是pfunc指向add函数
或者:
pfunc_t pfunc;
pfunc = add;
7、通过函数指针变量来间接调用指向的函数的语法:
函数指针变量名(实参表)
pfunc(100, 200); //本质就是调用add函数,类似add(100, 200)
指针函数就是一个指针,特殊的地方在于保存的东西比较特殊,是保存的一个地址,以后很多函数只要定义一个指针 函数,然后挨个调用就好了
**
举例如下:
**
(1)定义加减函数
(2)清0和置1函数
可复制代码如下:
/*函数指针演示*/
#include<stdio.h>
//声明一个函数指针类型并且取别名
typedef void (*pfunc_t)(int *,int);
void clear_bit(int *data,int n){//清零函数
*data&=~(1<<n);
}
void set_bit(int *data,int n){//置1函数
*data|=(1<<n);
}
int main(){
int data=0x55;
//定义函数指针变量,并且初始化为NULL
pfunc_t pfunc=NULL;
pfunc=clear_bit;
pfunc(&data,2);//0101 0101--0101 0001(0x51)
printf("data=%#x\n",data);
pfunc=set_bit;
pfunc(&data,3);//0101 0001--0101 1001(0x59)
printf("data=%#x\n",data);
}
三、函数指针经典用法
需求:目前有一堆函数,要求程序启动时,把这一堆函数挨个调用一遍
笨办法
vim pfunction3.c
#include <stdio.h>
一堆函数的定义
void add(int a, int b)
{
return a + b;
}
...
int main(void)
{
//挨个调用
add(1,2);
sub(1,2);
mul(2,2);
div(3,2);
...
return 0;
}
优秀代码:
可复制代码如下:
#include<stdio.h>
//声明函数指针数据类型并且取别名
typedef int (*pfunc_t)(int,int);
//定义一堆函数
int add(int a,int b){return a+b;}
int sub(int a,int b){return a-b;}
int mul(int a,int b){return a*b;}
int div(int a,int b){return a/b;}
int main()
{
//1、定义一个函数指针数组,每个元素是一个函数的地址
pfunc_t pfun_array[]={add,sub,mul,div,NULL};
//2、挨个调用
for(pfunc_t *pfunc=pfun_array;*pfunc;pfunc++)
{ //*pfunc是取出内容
int ret=(*pfunc)(200,100);//取出每个函数调用
printf("ret=%d\n",ret);
}
return 0;
}
**
四、回调函数
**
回调函数可复制代码如下
/*回调函数演示*/
#include<stdio.h>
//声明一个函数指针类型(以后数据类型的别名就是pfuc_t)
typedef int (*pfunc_t)(int ,int);
int add(int a ,int b){//定义加法函数:回调函数
return a+b;
}
int sub(int a,int b){//定义减法函数:回调函数
return a-b;
}
int cal(int a,int b,pfunc_t pfunc){
int ret=pfunc(a,b);//调用pfunc指向的函数并且给指定的
函数传递a,b
return ret;
}
int main()
{
int ret=0;
ret=cal(100,200,add);//让pfunc指向add函数,add称为回> 调函数
printf("ret=%d\n",ret);
ret=cal(100,200,sub);//让pfunc指向sub函数,sub称为回> 调函数
printf("ret=%d\n",ret);
}