[嵌入式C][入门篇] 快速掌握基础4 (普通函数,递归函数,函数指针,弱函数)

2024-01-07 20:55:09

开发环境:

  1. 网页版:跳转
  2. 本地开发(Vscode):跳转

一、简介

  1. 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main().
  2. 函数还有很多称呼,比如方法、子例程或程序等等。
  3. 函数从用户使用的角度可以分为:标准函数和用户自定义函数。

二、普通函数

(1)定义函数

// void -- 无返回类型, 函数体可以写return; 也可以不写
void func (void) { // 函数头 + 无参数
   ... 函数体
   return;
}

// void -- 无返回类型, 函数体可以写return; 也可以不写
void func (uint8_t para) { // 函数头 + 参数
   ... 函数体
   return;
}

// uint8_t -- 具有返回类型,必须写return x;
uint8_t func (uint8_t para) { // 函数头 + 参数
   ... 函数体
   return 0;
}

(2)调用函数

  1. 在函数内,使用别的函数
  2. 传值调用,形参值不影响实参,这是单向的数据传递方式。
  3. 传值调用,形参值影响实参,这双向的数据传递方式。

1. 传值调用

#include <stdio.h>
/* 函数声明 */
int max(int num1, int num2);
int main () {
   /* 局部变量定义 */
   int a = 100;
   int b = 200;
   int ret; // 接收返回值
   /* 调用函数来获取最大值 */
   ret = max(a, b); // 调用别的函数
   printf( "Max value is : %d\n", ret );
   return 0;
}
/* 函数返回两个数中较大的那个数 */
int max(int num1, int num2)  {
    return (num1 > num2) ? num1 : num2; 
}

在这里插入图片描述

2. 传地址调用

#include <stdio.h>
/* 函数声明 */
void max(int num1, int num2, int *val);
int main () {
   /* 局部变量定义 */
   int a = 100;
   int b = 200;
   int ret; // 接收返回值
   /* 调用函数来获取最大值 */
   max(a, b, &ret); // 调用别的函数
   printf( "Max value is : %d\n", ret);
   return 0;
}
/* 函数对比两个数,较大的那个数写入val */
void max(int num1, int num2, int *val)  {
    val = (num1 > num2) ? num1 : num2; 
}

在这里插入图片描述

三、递归函数(套娃)

递归指在函数中调用函数自身。(无限套娃或者有限套娃)
在这里插入图片描述

(1) 示例代码

#include <stdio.h>
#include <stdint.h>
uint64_t test(uint32_t i) {
   if(i <= 1) return 1; // 条件满足,退出套娃
   return i * test(i - 1);
}
int  main() {
    int i = 15;
    printf("%d 的阶乘为 %ld\n", i, test(i));
    return 0;
}

在这里插入图片描述

四、函数指针

  1. 指向函数的指针变量
  2. 函数指针可以像一般函数一样,用于调用函数、传递参数
  3. 一般形式:typedef void(*key_cb)(uint8_t event);

(1)示例代码

#include <stdio.h>
#include <stdint.h>

typedef void(*key_cb)(uint8_t event); // 定义一个函数指针类型
static key_cb g_key_event_cb = NULL; // 定义一个函数指针变量

void key_event(uint8_t event) { // 根据函数指针类型定义一个函数
	switch (event) {
		case 0:
			printf("按键释放\r\n");
			break;
		case 1:
			printf("按键按下\r\n");
			break;
		case 2:
			printf("单击\r\n");
			break;
		case 3:
			printf("双击\r\n");
			break;
		case 4:
			printf("长按\r\n");
			break;
		default:
			break;
	}	
}

int  main() {
	g_key_event_cb = &key_event; // 将函数地址赋值给函数指针
	g_key_event_cb(4);
	g_key_event_cb(0);
    return 0;
}

在这里插入图片描述

(2) 回调函数

函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。

1. 示例代码

#include <stdio.h>
#include <stdint.h>
typedef void(*key_cb)(uint8_t event); // 定义一个函数指针类型
void key_event(uint8_t event) { // 根据函数指针类型定义一个函数
	switch (event) {
		case 0:
			printf("按键释放\r\n");
			break;
		case 1:
			printf("按键按下\r\n");
			break;
		case 2:
			printf("单击\r\n");
			break;
		case 3:
			printf("双击\r\n");
			break;
		case 4:
			printf("长按\r\n");
			break;
		default:
			break;
	}	
}
void call(key_cb func) {
	func(1);
}
int  main() {
	call(&key_event);
    return 0;
}

在这里插入图片描述

五、弱函数(weak)

  1. weak 不是c语言的关键字,而是一些编译器的扩展属性。
  2. 如果用户没有定义这个函数,那么编译器就会执行__weak声明的函数。
  3. 一般形式:__weak void abc(void); 或 void __attribute__((weak)) abc(void);

(1) 示例代码

#include <stdio.h>
#include <stdint.h>

void __attribute__((weak)) abc(void) {
	printf("弱函数\r\n");
}

void abc(void) {
	printf("强函数\r\n");
}

int  main() {
	abc();
    return 0;
}

文章来源:https://blog.csdn.net/qq_29246181/article/details/135441581
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。