单片机,c语言,函数指针篇之基础介绍和运用

本人新人入坑,高3在读,可能讲的不是很好,我把我说理解的讲了,就当作我自己的笔记

指针是什么?

看下面试列,p最后存放的就是a的地址,指针就是一个存储内存地址的变量

int a = 10;       // 普通变量
int *p = &a;      // 指针变量,指向变量 a 的地址
printf("Value of a: %d\n", a);          // 输出 a 的值
printf("Address of a: %p\n", (void*)&a); // 输出 a 的地址
printf("Pointer p: %p\n", (void*)p);    // 输出 p 指向的地址
printf("Value pointed by p: %d\n", *p); // 输出 p 指向的地址中的值,即 a 的值

//输出
Value of a: 10
Address of a: 0x7ffeefbff4c4  // 示例地址,实际运行时可能不同
Pointer p: 0x7ffeefbff4c4    // 与 a 的地址相同
Value pointed by p: 10       // 与 a 的值相同

根据

上面的结论,下面代码p等于a的地址。x又等于p的地址,y又等于x的地址,最后打印y的地址和值,无非是和a的值一样

int a=10;
int*p=&a;
int*x=p;
int*y=x;
printf("Value of a: %d\n", a);        
printf("Address of a: %p\n", (void*)&a);
printf("Pointer p: %p\n", (void*)x);   
printf("Value pointed by p: %d\n", *x); 

那函数指针是什么呢?

下面这最基本的函数指针,怎么看,怎么理解

你可以理解为函数指针 a 是一个“容器”,它存放了函数 b 的地址。当你用 a 调用函数时,实际上是在调用函数 b。所以 a(1,2) 和 b(1, 2) 在效果上是一样的,因为它们都调用了函数 b

int b(int x,int y)
{
    return x+y;
}


void main()
{
    int (*a)(int,int)
    a = b;
    c = a(1,2);
    printf("%d",c);
}

还有一种函数指针,typedef 函数指针

typedef void (*a)(void);

这又是什么意思呢

typedef是定义的一个新的类型,如下图,这里将inte定义成一个继承int的新类型,并将其用作变量的类型

typedef int inte;

inte a = 10;

printf("%d",a);

//输出10

知道了这个我们在看下面,inte就是定义成一个函数指针的新类型,inte a,a就定义成了一个函数指针类型的"盒子"

typedef void(*inte)(void);


void b()
{
    printf("ok")
}

void main()
{
    inte a;
    a = b;
    a();
}

//输出结果ok

 到这里,可以就有人要问啦,我直接调用b不久好啦,搞这么麻烦,函数指针就这?还不如不用嘞。

在这种简单的情况下,直接调用函数 b 当然是可行的,并且在这种情况下使用函数指针 a 似乎增加了复杂性。不过,使用函数指针有其独特的用途和优势。我只能说,在某些情况下,使用函数指针比直接调用函数更有利,下面看这个试列

这里枚举了3个任务命令,最终使我们只需要向我们的执行任务函数传命令或者值就可以执行我们需要运行的函数,拿出去给别人用别人之需要看我的命令传参给执行函数就可以运行了,不用这种方法也可以,用switch,这里就要case3下,但是当我们的命令变多,代码复杂了,或者我要对不同的对象实现命令操作,就需要一堆switch和case,代码最后就变成了一坨


typedef void(*Task)(void);

enum
{
   START,
   OPERATION,
   FINISH
   
}state;

void Execute_The_Task(state a)
{
    Task task[] = {start,operation,finish}
    if(a<3)
    {
        tsak[a]();
    }
}

void main()
{
    Execute_The_Task(START);
    Execute_The_Task(OPERATION);
    Execute_The_Task(FINISH);
    或者是
    Execute_The_Task(0);
    Execute_The_Task(1);
    Execute_The_Task(2);
}

 还有一种就是写在结构体里面的指针变量,当我们理解上面两种了,这种也就不难理解了,他就是定义的一个结构体,结构体里面a,b的类型就是"盒子",和上面typedef函数指针一个样子

typedef struct{
    void (*a)(void)
    void (*b)(void)
}

他有什么用呢,从上面的试列看,这种情况我们对一个对象执行任务命令,现在每个任务就一条命令,当我们的每个任务出现了更多的分支,如洗衣机,每个模式不同的方法去洗衣服,我们就可以用到下面的方法,分别运行喝水任务,吃饭任务,和打游戏任务

#include <stdio.h>

// 定义三个函数指针的结构体
typedef struct {
    void (*Start)(void);
    void (*Operation)(void);
    void (*Finish)(void);
} Tick;

// 定义状态枚举
typedef enum {
    state1,
    state2,
    state3
} State;

// 函数声明
void start(void);
void operation1(void);
void operation2(void);
void operation3(void);
void finish(void);

// 初始化 Tick 数组
Tick TICK[] = {
    {start, operation1, finish},
    {start, operation2, finish},
    {start, operation3, finish}
};

// 执行任务函数
void Execute_The_Task(State a) {
    if (a < 3) {
        Tick tick = TICK[a];
        tick.Start();
        tick.Operation();
        tick.Finish();
    }
}

// 定义具体的操作函数
void start(void) {
    printf("开始\n");
}

void operation1(void) {
    printf("吃饭1\n");
}

void operation2(void) {
    printf("喝水2\n");
}

void operation3(void) {
    printf("打游戏3\n");
}

void finish(void) {
    printf("结束...\n");
}

// 主函数
int main() {
    Execute_The_Task(state1);
    Execute_The_Task(state2);
    Execute_The_Task(state3);
    // 或者是
    Execute_The_Task(0);
    Execute_The_Task(1);
    Execute_The_Task(2);
    return 0;
}

函数指针的运用不止这些,已我现在的能力介绍到这里已经尽力了,可以自己想想去创造 

 本篇就到这里,了,我要去学习了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值