AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
[TOC] 每个C程序都至少有一个函数,即主函数 **main()** ,所有简单的程序都可以定义其他额外的函数,格式如下: ``` 返回类型 函数名称(参数1类型 参数1, 参数2类型 参数2, ...){} ``` 函数还有很多叫法,比如方法、子例程或程序,等等 ## 函数调用 [传值调用](https://www.runoob.com/cprogramming/c-function-call-by-value.html "C 中传值方式调用函数") 如:int func_name(int a) [引用调用](https://www.runoob.com/cprogramming/c-function-call-by-pointer.html "C 中引用方式调用函数") 如:int func_name(int &a) ## 函数指针 函数指针是指向函数的指针变量,通常我们说的指针变量是指向一个整型、字符型或数组等变量,而【函数指针】是指向函数。 ### **定义函数指针**:用(\*标识符)替换函数名,剩下照抄 ``` int max(int a , int b){ return a>b?a:b; } //定义函数指针:先复制int max(int a , int b),然后将函数名替换为(*标识符) int (*p)(int a , int b)=NULL;//任何指针都可以指向null,这时候还未执行max //可以不加NULL吗,可以的 int (*p)(int a , int b); ,如果不指向null,第一时间想用这段内存时它却可能指向不是期望的内存,所以一般用null初始化新定义的指针 //定义函数指针时可以省略形参 int (*p)(int , int)=NULL; ``` 用函数名给函数指针赋值 ``` int (*pp)(int , int)=NULL; pp=max; ``` ### **函数指针的调用函数** * 1、直接用函数指针替换函数名的方式调用 * 2、指针的基本操作去调用,取\*运算再调用 >[danger]不要和基本指针联系在一起,只需记得这两种方法就可以了 ``` //原来调用函数 max(1,2); //直接用函数指针替换函数名的方式调用函数 pp(1,2); //指针的基本操作去调用,取\*运算再调用 (*pp)(1,2) ``` ### **函数指针的用法(实现回调函数)** 回调函数(以函数指针为参数的函数) ``` int max(int a , int b){ return a>b?a:b; }// 指针是int (*p)(int , int) int min(int a , int b){ return a<b?a:b; }// 指针是int (*p)(int , int) //定义一个回调函数:(以函数指针为参数的函数就是回调函数) void printData(int (*p)(int , int), int a, int b){ print("%d\n",p(a,b)); } int main(){ //定义上面定义的回调函数的函数指针 void (*pp)(int (*p)(int , int), int a, int b)=printData; //省略掉形参 void (*pp)(int (*)(int , int), int , int )=printData; //调用上面定义的回调函数 pp(max,1,2);//求最大值 (*pp)(max,1,2) pp(min,1,2);//求最小值(*pp)(min,1,2) } ``` ## **typedef** ### **基本用法(给已存在的类型起别名)** ``` #include <stdio.h> typedef int INT;//INT是int的别名 int main(){ int a=1; INT a=1;//d等于int a=1 } // 步骤 将INT a=1中的INT替换为 typedef int INT; 得到typedef int a=1 然后去掉typedef 得到int a=1 ``` ### **再函数指针中的使用** ``` int max(int a , int b){ return a>b?a:b; }// 指针是int (*pf)(int , int) int main(){ typedef int(*pfunc)(int, int);//给指针定义别名叫pfunc pfunc pf=max; print("%d\n",pf(1,2)) } //ypedef int(*pfunc)(int, int);拿下来 去掉ypedef 得到int(*pfunc)(int, int); //然后将pfunc替换成pf得到int (*pf)(int , int) ``` typedef是为了简化回调函数的 ``` int max(int a , int b){ return a>b?a:b; }// 指针是int (*pf)(int , int) //定义一个回调函数:(以函数指针为参数的函数就是回调函数) void printData(int (*pf)(int , int), int a, int b){ print("%d\n",pf(a,b)); } //调用回调函数 void (*pf)(int (*)(int , int), int , int )=printData; pf(1,2); //简化后 int max(int a , int b){ return a>b?a:b; }// 指针是int (*pf)(int , int) typedef int (*pf)(int , int); void printData(pf P, int a, int b){ print("%d\n",P(a,b)); } ``` ### **再结构体中定义别名** ``` typedef struct Node{ int data; struct Node* next; }NODE,*LPNODE,ARRAY[3]; //怎么看呢?不要看中间{}里的的代码 //typedef struct Node NODE,*LPNODE,ARRAY[3]; //和 int a,b,c等效int a;int b; int c;一样,可以得出: //typedef struct Node NODE 结构体别名 //typedef struct Node* LPNODE结构体指针别名 //typedef struct Node ARRAY[3] 结构体数组别名 ``` ## **万能指针充当函数指针** [函数指针](https://www.bilibili.com/video/BV1tL411M77o?p=3) 万能指针:空类型的指针void* 万能指针在操作任何类型指针,在使用前必须做强制类型转换 万能指针操作基本数据类型 ``` void* p=NULL; int a=0;//定义a变量 p=&a;//p指向a(p指向a的内存地址) 它可以指向任何类型这里是指向int //使用前要先转换成想要的类型(int *)p 然后做*运算 *(int *)p printf("%d\n", *(int *)p); void* p=NULL; float b=0.0f;//定义b变量 p=&b;//p指向b(p指向b的内存地址) 它可以指向任何类型这里是指向float //使用前要先转换成想要的类型(float *)p 然后做*运算 *(float *)p printf("%f\n", *(float *)p);//等价于float* pp=(float*)p; printf("%f\n", *pp); ``` 万能函数当作函数指针 ``` void print(){ printf("万能函数当作函数指针"); } p=print; ```