当前位置:网站首页>【C语言】指针函数与函数指针、数组函数
【C语言】指针函数与函数指针、数组函数
2022-06-10 13:31:00 【创客协会的阿蛋°】
指针函数和函数指针是开发中经常混淆的一个概念。
指针函数
格式: 类型 *函数名()
return 和函数类型相同的值;
指针函数主体是一个函数,返回的类型为指针。
就是将指针指向这个函数返回的值。
int* f(int x,int y);
//因为括号的优先级大
//所以它首先是一个拥有x,y两个变量的函数,然后再来一个int型的指针指向它。
主体:f(int x,int y)
函数是可以返回数值的,对于正常函数来说应该是这样的:
int f(int x,int y)
{
x=1;
return x;
}
//此时f()返回的是x,数据类型为int型
用指针函数是这样的(错误用法):
int* f(int x,int y)
{
x=1;
return x;
}
//此时f()返回的是x的值的地址的值,相当于(int *)x;
这一定是个错误的数据了,因为指针指过去1(x的值)的地址里面去了
正确用法应该是用指针指向x所在的地址才能对x进行操作:
int* f(int x,int y)
{
x=1;
return &x;
}
//此时f()返回的是x的值,相当于(int *)&x
(int *)&x == x;
小甲鱼指针函数解析
以下是小甲鱼指针函数的代码:
其中就是利用了指针函数的特性:相当于char *(return “xxx”),字符串可以当作指针,如果不加 * 就相当于 char (return “xxx”),仅返回一个字符类型,加了 * 则相当于取"xxx"的首地址,返回的是从xxx的地址里面的值。
不要返回函数的局部变量:
注意局部变量的作用域,局部变量可以返回地址,但是数据可能已经不存在了
函数指针
格式: 类型 (* 指针名) (要指向的函数的参数)
函数指针主体是一个指针,是用来指向一个函数的。
就是用这个指针指向一大片的这个函数所在的区域。(函数名即为函数的首地址)
int (*f) (int x,int y);
//因为括号的优先级大。
// 所以它首先是一个int (*f)的指针,然后再指向带有参数(x,y)的函数。
主体:int (*f)
将函数指针作为参数来使用

int calc(int (*fp)(int,int),int num1,int num2);
calc(sub,3,5)的第一个参数:即用函数指针指向sub函数的地址。
从调用开始, (*fp)这个指针已经是sub函数了。
即 (*fp)(int,int) == sub(int,int)
数据是从 return (*fp)(num1,num2) 出来的,相当于sub(num1,num2)
函数指针进阶
#include<stdio.h>
int add(int, int);
int sub(int, int);
int cal(int (*)(int, int), int, int);
int (*select(char a))(int, int);
int add(int num1, int num2)
{
return num1 + num2;
}
int sub(int num1, int num2)
{
return num1 - num2;
}
int cal(int (*fp)(int, int), int num1, int num2)
{
return (*fp)(num1,num2);
}
int (*select(char op))(int num1, int num2)
{
switch(op)
{
case '+':return add;
case '-':return sub;
}
}
int main()
{
int num1, num2;
char op;
//int (*fp)(int, int);
printf("please enter a formular\n");
scanf("%d %c %d", &num1, &op, &num2);
printf("%d\n", cal(select(op), num1, num2));
return 0;
}
在这里注意cal函数是一个有三个参数的函数,其中第一个参数是一个函数指针。
select函数是一个指针函数,其返回值为一个函数指针。
当输入“1+2”时这个程序运行的流程是这样的。首先“+”这个符号被读入到op这个参数中,然后op这个参数被传入select函数,select函数中的switch语句发现op是一个加号,所以返回一个指向add函数的函数指针,这个函数指针作为cal函数的参数被传入后解引用,再把num1和num2传入add函数即可得到返回值3。
int (*select(char op))(int num1, int num2)
//可以理解为:类型 (* 函数指针)(参数1, 参数2)
调用printf("%d\n", cal(select(op), num1, num2));的时候,
cal会用函数指针调用select,select会根据传递的参数op,
来选择返回的是函数add还是函数sub的首地址。
首地址最终传到int cal(int (*fp)(int, int), int num1, int num2)中,
被cat的函数指针(int (*fp)来解引用。
相当于(int (*fp)(return add)=运行 add(num1,num2);
“数组函数”(题外话)
在c语言中摸鱼数组函数这种概念,但是我们可以人为的写出数组函数(不是define)
格式: int (* 数组)(函数的参数);
int (* arr[8])(int a);
数组函数案例:
#include <stdio.h>
#include <stdlib.h>
#define EPSINON 0.000001 // 定义允许的误差
double add(double x, double y);
double sub(double x, double y);
double mul(double x, double y);
double divi(double x, double y);
double add(double x, double y)
{
return x + y;
}
double sub(double x, double y)
{
return x - y;
}
double mul(double x, double y)
{
return x * y;
}
double divi(double x, double y)
{
// 不要对浮点数进行==或!=比较,因为IEEE浮点数是一个近似值
if (y >= -EPSINON && y <= EPSINON)
{
printf("除数不能为0\n");
// 如果除数为0,调用exit()函数直接退出程序
exit(1);
}
else
{
return x / y;
}
}
int main(void)
{
int i;
double x, y, result;
double (*func_table[4])(double, double) = {
add, sub, mul, divi};//在数组里面存放的是函数的首地址,用函数指针来指向这个地址来引用这个函数 以此形成函数数组
printf("请输入两个数:");
scanf("%lf %lf", &x, &y);
printf("对这两个数进行加减乘除后的结果是:");
for (i = 0; i < 4; i++)
{
result = (*func_table[i])(x, y);
printf("%.2f ", result);
}
putchar('\n');
return 0;
}
double (*func_table[4])(double, double) = {add, sub, mul, divi};
是一个数组函数,里面存有四个函数名(即首地址)。
调用(*func_table[i])(x, y)即为调用[i]对应名字的函数。
相当于:
(*func_table[1])(x, y)==(add(x, y));
(*func_table[2])(x, y)==(sub(x, y));
(*func_table[3])(x, y)==(mul(x, y));
(*func_table[4])(x, y)==(divi(x, y));
一般高级语言才有这些,C语言比较少用(但不是不用)。
略,有空再写,相对复杂。
边栏推荐
- [deep learning 05] cross entropy loss function
- [FAQ] summary of common problems and solutions during the use of rest API interface of sports health service
- 解决VMware Workstation安装VMware Tools显示灰色的办法
- How to locate the hot problem of the game
- 工作中记录MySQL中的常用函数
- Google Earth engine (GEE) - real time global 10 meter land use / land cover (LULC) data set based on S2 images
- Solve the problem that win10 virtual machine and host cannot paste and copy each other
- Let resources flow freely in the cloud and locally
- High performance practical Alibaba sentinel notes, in-depth restoration of Alibaba micro service high concurrency scheme
- Google Earth engine (GEE) -- batch download of DEM using MODIS leaf area index image mask
猜你喜欢

Multithreading killer ---countdownlatch & cyclicbarrier

【Multisim仿真】差分放大电路2

Im instant messaging development: the underlying principle of process killed and app skills to deal with killed

解决跨海高并发崩溃难题?so easy

【无标题】
![[untitled]](/img/40/8ce6b9fc0050c9ed5b8b1d05dc3c51.png)
[untitled]

In depth analysis of "circle group" relationship system design | series of articles on "circle group" technology

Google Earth Engine(GEE)——基于s2影像的实时全球10米土地利用/土地覆盖(LULC)数据集

格力手机叫板苹果手机?除了嘴硬之外,恐怕再无其他
![[technical analysis] discuss the production process and technology of big world games - preliminary process](/img/8d/52cb98a617f690df310d6de5512ebc.png)
[technical analysis] discuss the production process and technology of big world games - preliminary process
随机推荐
What is the p value of a gene?
[Multisim Simulation] differential amplifier circuit 2
多云管理平台cmp是什么意思?谁能清楚解释一下
In depth analysis of "circle group" relationship system design | series of articles on "circle group" technology
buuctf [PHP]inclusion
苹果生产线迁离,说明5G工业互联、智能制造对中国制造帮助有限
3. 网页开发工具 VS Code
[FAQ] résumé des problèmes courants et des solutions lors de l'utilisation de l'interface API rest du Service de santé sportive
Tablayout usage details (modify text size, underline style, etc.)
Google Earth engine (GEE) - real time global 10 meter land use / land cover (LULC) data set based on S2 images
Mmdetection adds precision to the evaluation index
新功能|Mail GPU Counter模块新增GPU图元处理和GPU Shader Cycles
eKuiper Newsletter 2022-05|protobuf 编解码支持、可视化拖拽编写规则
Comprehensive training of large projects
The essence of linear algebra 6 inverse matrix, column space and zero space
buuctf [Jupyter]notebook-rce
Google Earth Engine(GEE)——基于s2影像的实时全球10米土地利用/土地覆盖(LULC)数据集
解决win10虚拟机和主机不能互相粘贴复制的问题
【FAQ】运动健康服务REST API接口使用过程中常见问题和解决方法总结
Google Earth Engine(GEE)——利用MODIS 的叶面积指数影像掩膜dem批量下载