函 数 指 针 和 回 调 函 数 函数指针和回调函数 函数指针和回调函数
1.引例
请写一个函数,同时返回两个正整型数据的和、差、商。但是我们知道函数只有一个返回值的,该如何实现呢?(通过传地址
)
int fun(int*Isum ,int*diff, int *quo, int a,int b);
2.正解
当我们既需要通过函数返回值来判断函数调用是否成功,又需要把数据传递出来。
此时,我们就要用到多参返回,多参返回,都是通过传递调用空间中的空间地址
来实现的。
比如前面我们讲到的,通过参数,返回堆上的一维空间,二维空间和初始化指针就是如此。
上面和下面没有太大关系
3.函数指针
函数的本质:函数的本质是一段可执行性代码段。函数名,则是指向这段代码段的首地址
。
函数首地址可以打印出来
printf("%p\n",print)
void print{
printf("abc\n");
printf("abc\n");
printf("abc\n");
printf("abc\n");
return;
}
((void (*)(void))exe0401630)(); // 这就是函数 == print()
看到这个小朋友惊呆了!
第一个(void),指的是:返回类型
(*)表示指针
第二个(void),指的是:传参
(void (*)(void)) 强转函数类型
4.什么是函数类型?
void (*p)(void) = print; // 函数类型的基本格式,三元素:类型、传参、指针*
p();
5.函数指针数组
void func0(int i){
printf( "your enter %d so func%d is called",i,i);
void func1(int i){
printf( "your enter %d so func%d is called",i,i);
void func2(int i){
printf( "your enter %d so func%d is called",i,i);
void func3(int i){
printf( "your enter %d so func%d is called",i,i);
void (*fpa[4])(void) = {func0,func1,func2,func3};
这是一个输入参数为void,返回类型为void,地址为0 的函数调用
6.什么是回调函数(CallBackFunction)
一个函数a没有执行完,又回来执行的函数b,函数b就是回调函数
提出思考:
当我们要实现某功能,都是写死在程序中的,如果要改只能改动原代码。
但是那么如果程序是以库的形式给出的呢?
那又怎么办呢?
main.c
#include cstdio.h>
#include "mysort.h”
int mycompare(int a,int b) // 回调函数,实现函数的升序和降序
{
return a>b?1:0;
}
int main(void)
{
int arr[10] - {6,5,4,3,2,1,7,8,9,0};
selectsort(arr,10,mycompare); //mycompare回调函数,实现函数的升序和降序
for(int i=0; i<10; i++)
{
printf(""%d\n" ,arr[i]);
}
return 0;
}
什么是回调函数(CallBackFunction)
就是函数selectsort
没有执行完,又回来执行的函数mycompare
,函数mycompare
就是回调函数
mysort.h
#ifndef MYSORT_H
#define MYSORT_H
void selectsort(int *p, int n,int (*pf)(int,int));
#endif / / MYSORT_H
mysort.c(实际中相当于封装的dll,对用户不可见)
#include "mysort.h”
// int(*pf)(int a, int b) :函数指针
void selectsort(int *p, int n,int(*pf)(int a, int b))
{
for(int i=o; i<n-1 ;i++){
for(int j=i+1; j<n; j++){
if(pf(p[i],p[j])) // pi > pj 1 0
{
p[i] = p[i]^p[j];
p[j] = p[i]^p[j];
p[i] = p[i]^p[j];
}
}
}
}