开发环境:
- 网页版:跳转
- 本地开发(Vscode):跳转
文章目录
- 一、简介
- 二、普通函数
- (1)定义函数
- (2)调用函数
- 1. 传值调用
- 2. 传地址调用
- 三、递归函数(套娃)
- (1) 示例代码
- 四、函数指针
- (1)示例代码
- (2) 回调函数
- 1. 示例代码
- 五、弱函数(weak)
- (1) 示例代码
一、简介
- 函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main().
- 函数还有很多称呼,比如方法、子例程或程序等等。
- 函数从用户使用的角度可以分为:标准函数和用户自定义函数。
二、普通函数
(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. 传值调用
#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;
}
四、函数指针
- 指向函数的指针变量
- 函数指针可以像一般函数一样,用于调用函数、传递参数
- 一般形式: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)
- weak 不是c语言的关键字,而是一些编译器的扩展属性。
- 如果用户没有定义这个函数,那么编译器就会执行__weak声明的函数。
- 一般形式:__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;
}