C 指针和函数
其实C真的是基础
今天在看iOS中关于Block的一些东西的时候,看到关于Block底层实现的一些东西的时候,涉及到C的函数和指针方面的东西,C真的是基础,关于C的内容也全都在复习和加深理解当中,这理先把指针和函数部分的理解自己再总结一下,看了下面的内容,相信你一定能懂指针型函数和函数指针是什么。
一: 指针型函数
在C语言中,一个函数可以返回一个整形、字符型或者是实型值等等,当然也可以返回一个空值,也可以返回指针型的数据,即地址,所谓的指针型函数就是指函数的返回值是指针型数据的函数!
真的这个"指针型函数"和“函数指针”很容易混淆掉,这些细节可能平时接触的C代码多了也就没什么问题,但要是接触的C代码不多的话,很容易出现混淆,得多注意。
1、指针型函数的定义形式:
函数数据类型 * 函数名 (形式参数列表)
解释: 函数名前面的 * 表示函数的返回值就是一个指针类型, “函数的数据类型”是指针所指向的目标变量的类型,在指针型函数中,使用return语句返回的可以是变量的地址,数据的首地址或者指针变量,还可以是结构体,共用体,等构造数据类型的首地址。
比如: int * function (int a, int b);
函数的返回值是 int 型指针或者地址,
下面一个简单的例子,找到两个数的最大值:
2、 指针型函数定义是应该注意的问题:
(1): 指针函数中return的返回值必须是与函数类型一致的指针
(2): 返回值必须是函数外部或者静态存储类别的变量地址或数组地址,以保证主调函数能正常的使用数据。因为在函数调用结束时,自动存储类型的变量或者数组所占有的村塾单元已经被释放掉,操作系统可能会重新分配这些存储单元。
二:函数指针
<1>定义以及注意事项
在C语言中,可以让指针指向函数,一个函数包括一些列的指令,在内存中占据一篇存储单元,它必然有一个指向函数第一条指令的地址,就是函数的入口地址。如同数组名可以表示数据的首地址一样,C语言同样用函数名表示函数的入口地址,而且是地址常量,通过这个地址可以找到函数,这个地址就是我们要说的函数的指针。
要让指针指向函数,只要把函数名复制给指针变量,则该指针变量的内容就是函数的入口地址。
定义形式如下: 数据类型 (* 函数指针变量名)();
说说上面内容中的一些注意点:
(1): * 函数指针变量名这部分必须写成(* 函数指针变量名),由于优先级的关系,不然这里就成我们前面写的指针型函数了,
(2): 和数据型指针一样,程序中不能使用指向不明的函数指针,使用前必须赋值!
(3): 赋值是可以只给出函数名不必给出参数
<2>函数指针的使用
这部分的内容也比较重要,不然知道什么是函数指针不会用也尴尬,函数指针与一般的指针之间的共同之处是都可以间接的访问,但是变量指针指向内存中的数据存储区域,通过间接存储运算访问的是目标变量,而函数指针指向内存的程序代码存储区域,通过间接存储运算时程序流程转移到指针所指向的函数入口。
用函数指针变量调用函数的一般形式是: (* 函数指针变量名)(实参);
注意点就是:必须用()包含* 函数指针变量名,表示间接调用指针变量所指向的函数,这里其实就是间接取地址运算。
比如下面这个例子:利用函数指针调用求一个数组的和
三:用指向函数的指针做函数的参数
下面这个例子,把我们前面说的两者结合起来看看。
比如:我们输入1,就求已知数组元素的最小值,输入2就求已知数组元素的最大值,输入3就求数组元素之和,代码如下,能帮助我们理解上面说的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #include <stdio.h> void process( int *x, int n, int (*fun)()){ int result; result = (*fun)(x,n); printf ( "%d\n" ,result); } /*求数组的和*/ int arr_sum( int x[], int n){ int sum = 0; for ( int i=0;i<n;i++){ sum += x[i]; } return sum; } /*求数组最大的元素*/ int arr_max( int x[], int n){ int max = x[0]; for ( int i=0;i<n;i++){ if (max < x[i]) max = x[i]; } return max; } /*求数组最小元素*/ int arr_min( int x[], int n){ int min = x[0]; for ( int i=0;i<n;i++){ if (min > x[i]) min = x[i]; } return min; } int main(){ int a[]={1,2,3,4,5,6,7,8}, choice; printf ( "请输入你的选择:" ); scanf ( "%d" ,&choice); switch (choice){ case 1: process(a,8,arr_min); break ; case 2: process(a,8,arr_max); break ; case 3: process(a,8,arr_sum); break ; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话