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

news2024/9/27 23:28:22

开发环境:

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

文章目录

  • 一、简介
  • 二、普通函数
    • (1)定义函数
    • (2)调用函数
      • 1. 传值调用
      • 2. 传地址调用
  • 三、递归函数(套娃)
    • (1) 示例代码
  • 四、函数指针
    • (1)示例代码
    • (2) 回调函数
      • 1. 示例代码
  • 五、弱函数(weak)
    • (1) 示例代码

一、简介

  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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1364020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记.backward()报错

最近我在模型训练损失里加入了LPIPS深度感知损失&#xff0c;训练的时候就出现了如上的报错&#xff0c;具体解释为&#xff1a;调用梯度反向传播loss.backward()时&#xff0c;我们计算梯度&#xff0c;需要一个标量的loss(即该loss张量的维度为1,只包含一个元素&#xff09;&…

计算机科学速成课【学习笔记】(2)——电子计算机

本集课程B站链接 2. 电子计算机-Electronic Computing_哔哩哔哩_bilibili2. 电子计算机-Electronic Computing是【计算机科学速成课】[40集全/精校] - Crash Course Computer Science的第2集视频&#xff0c;该合集共计40集&#xff0c;视频收藏或关注UP主&#xff0c;及时了…

lombok注解 @Data使用在继承类上时出现警告解决

一、警告问题 1、Data注解 Data 包含了 ToString、EqualsAndHashCode、Getter / Setter和RequiredArgsConstructor的功能。 当使用 Data注解时&#xff0c;则有了 EqualsAndHashCode注解&#xff08;即EqualsAndHashCode(callSuperfalse)&#xff09;&#xff0c;那么就会在此…

基于java,springboot的学生考勤系统

1.环境以及简介 基于java,springboot的学生考勤系统&#xff0c;Java项目&#xff0c;SpringBoot项目&#xff0c;vue项目&#xff0c;含开发文档&#xff0c;源码&#xff0c;数据库以及ppt。 源码下载 另有1000份项目源码&#xff0c;项目有java&#xff08;包含springboo…

【Java】设计模式之两阶段终止

两阶段终止 两阶段终止&#xff0c;即Two Phase Termination。是用来终止线程的套路。 它的思想是&#xff0c;如何在一个线程T1中优雅地终止线程T2&#xff1f;这里的【优雅】指的是给T2一个料理后事的机会。 错误思路&#xff1a; 使用stop方法。stop 方法会真正杀死线程…

CentOS 7 实战指南:文件或目录的权限操作命令详解

前言 这篇文章详细介绍了文件和目录的常用权限操作命令&#xff0c;并提供了全面的技术解析。通过本文&#xff0c;你将学习如何使用 chmod 和 chown 命令来管理文件和目录的权限&#xff0c;控制用户和用户组的访问权限。无论你是初学者还是有经验的系统管理员&#xff0c;这…

synchronized、volatile关键字

Java中的synchronized关键字 synchronized关键字介绍 synchronized块是Java提供的一种原子性内置锁&#xff0c;Java中的每个对象都可以把它当作一个同步锁来使用&#xff0c;这些Java内置的使用者看不到的锁被称为内部锁&#xff0c;也叫作监视器锁。 线程的执行代码在进入…

ssm基于JSP的明水县苹果网吧计费管理系统的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本明水县苹果网吧计费管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大…

Guava:Cache强大的本地缓存框架

Guava Cache是一款非常优秀的本地缓存框架。 一、 经典配置 Guava Cache 的数据结构跟 JDK1.7 的 ConcurrentHashMap 类似&#xff0c;提供了基于时间、容量、引用三种回收策略&#xff0c;以及自动加载、访问统计等功能。 基本的配置 Testpublic void testLoadingCache() th…

【精通C语言】:深入解析C语言中的while循环

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; C语言详解 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、while循环1.1语法1.2 执行过程解析1.3 break1.4 continue &#x1f324;️全篇总结 &…

基于Java SSM框架实现旅游资源网站系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现旅游资源网站系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个旅游资源网站 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述旅…

Windows server——部署DHCP服务(2)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.配置DHCP服务 1.DHCP安装的要求 安装DHCP服务器需要满足如下要求&#…

springboot第47集:【思维导图】面向对象,关键字,标识符,变量,数组的使用...

关键字&#xff1a;class,public,static,void等&#xff0c;特点是全部关键字都是小写字母。 image.png image.png 凡是自己起的名字可以叫标识符 image.png image.png image.png image.png 整数类型的使用 image.png image.png image.png 浮点类型 image.png image.png 字符类…

iPhone 恢复出厂设置后如何恢复数据

如果您在 iPhone 上执行了恢复出厂设置&#xff0c;您会发现所有旧数据都被清除了。这对于清理混乱和提高设备性能非常有用&#xff0c;但如果您忘记保存重要文件&#xff0c;那就是坏消息了。 恢复出厂设置后可以恢复数据吗&#xff1f;是的&#xff01;幸运的是&#xff0c;…

八大算法排序@冒泡排序(C语言版本)

冒泡排序 概念 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单直观的排序算法&#xff0c;它重复地遍历待排序序列&#xff0c;一次比较两个相邻的元素&#xff0c;如果它们的顺序错误就将它们交换过来。通过多次的遍历&#xff0c;使得最大的元素逐渐移动到待排序序…

使用monai.visualize.utils.matshow3d函数展示3D医学图像

monai.visualize.utils.matshow3d 函数是 MONAI 包中用于可视化 3D 图像数据的一个实用工具函数。它可以在平面中显示一个或多个3D图像&#xff0c;并提供一些参数来控制显示的方式和外观。 先导入需要的包 import numpy as np import matplotlib.pyplot as plt from monai.v…

C#,入门教程(10)——常量、变量与命名规则的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(09)——运算符的基础知识https://blog.csdn.net/beijinghorn/article/details/123908269 C#用于保存计算数据的元素&#xff0c;称为“变量”。 其中一般不改变初值的变量&#xff0c;称为常变量&#xff0c;简称“常量”。 无论…

阿里云服务器地域怎么选择?2024地域选择方法

阿里云服务器地域和可用区怎么选择&#xff1f;地域是指云服务器所在物理数据中心的位置&#xff0c;地域选择就近选择&#xff0c;访客距离地域所在城市越近网络延迟越低&#xff0c;速度就越快&#xff1b;可用区是指同一个地域下&#xff0c;网络和电力相互独立的区域&#…

FineBI实战项目一(3):Kettle实现ETL到数据仓库

目前&#xff0c;finebi_shop_bi 中是没有任何数据的&#xff0c;是一个空的数据库。而后续我们的所有数据分析都将在该数据库中进行。我们第一件事情就是要将 「finebi_shop」数据库中的所有表抽取到「finebi_shop_bi」数据库中。要抽取并装载数据到「finebi_shop_bi」中&…

Redisson 源码解析 - 分布式锁实现过程

一、Redisson 分布式锁源码解析 Redisson是架设在Redis基础上的一个Java驻内存数据网格。在基于NIO的Netty框架上&#xff0c;充分的利用了Redis键值数据库提供的一系列优势&#xff0c;在Java实用工具包中常用接口的基础上&#xff0c;为使用者提供了一系列具有分布式特性的常…