当前位置: 首页 > news >正文

嵌入式学习 day9:函数

一、二维字符数组

二维字符数组本质上就是一个字符串数组——每一行存一个字符串。

1. 定义

c

char str[5][32]; // 5行,每行最多31个字符(留1个给\0)

2. 元素的访问

c

str[0] // 访问第0行,代表第0个字符串 str[0][2] // 访问第0行第2列,单个字符

3. 初始化

c

// 方式一:逐字符初始化 char str[5][32] = { {'h', 'e', 'l', 'l', 'o', '\0'}, {'w', 'o', 'r', 'l', 'd', '\0'} }; // 方式二:字符串初始化(最常用) char str[5][32] = {"hello", "world", "how", "are", "you"}; // 方式三:全部置零 char str[5][32] = {0};

4. 输入与输出

c

char str[5][32] = {0}; // 输入5个字符串 for (int i = 0; i < 5; i++) { scanf("%s", str[i]); // str[i] 本身就是地址,不用加& } // 输出5个字符串 for (int i = 0; i < 5; i++) { printf("str[%d] = %s\n", i, str[i]); }

⚠️ 二维字符数组的每一行都是一个一维字符数组,str[i]本身就是字符串的首地址,所以scanf不用加&

二、函数

1. 为什么需要函数?

有些操作要反复做——比如求两个数的最大值、判断闰年。每次都把同样的代码复制粘贴一遍,代码会变得又臭又长,改一个地方要改好几处。

函数就是把重复的代码封装起来,哪里需要就调用哪里

2. 函数的定义

c

函数类型 函数名(数据类型 形参1, 数据类型 形参2, ...) { 函数体; return 返回值; }

几个要点

  • 函数名:规则和变量名一样,见名知意

  • 形参:函数要处理的数据通过形参传进来

  • 函数类型:返回值的数据类型,不写默认int,没有返回值就写void

  • 返回值:函数运行完的结果,通过return返回

c

// 例子:求两个整数中较大的那个 int max(int a, int b) { return (a > b) ? a : b; }

3. 函数的调用

c

int result = max(10, 20); // result = 20

传参规则

  • 实参个数和形参个数必须一一对应

  • 类型不匹配时会自动转换(按形参类型转)

4. 函数的声明

如果被调函数写在主调函数下面,需要先声明:

c

// 声明(告诉编译器有这个函数) int max(int a, int b); int main(void) { int m = max(10, 20); return 0; } // 定义 int max(int a, int b) { return (a > b) ? a : b; }

如果被调函数写在主调函数上面,就不需要声明了。

三、变量的作用域和生存周期

1. 作用域(哪里能用)

  • 局部变量:在函数或代码块({})内定义,只能在这个范围内使用

  • 全局变量:在所有函数外面定义,整个文件都能用

c

int global = 100; // 全局变量 void func(void) { int local = 10; // 局部变量 printf("%d\n", global); // ✅ 能用全局 } int main(void) { printf("%d\n", local); // ❌ 错误!main里看不到local printf("%d\n", global); // ✅ 能用全局 return 0; }

2. 生存周期(什么时候存在)

  • 局部变量:执行到定义时开辟空间,出了作用域就回收

  • 全局变量:程序启动时就存在,程序结束才回收

四、变量的存储类型

1. auto(自动型,默认)

c

auto int a; // 等价于 int a;
  • 存在栈区

  • 不初始化就是随机值

  • 进入作用域时开辟,退出时回收

2. register(寄存器存储)

c

register int a;
  • 尽量放在CPU寄存器里(更快)

  • 如果寄存器满了,等价于auto

3. extern(外部声明)

声明变量或函数是在别处定义的,多文件编程时用。

4. static(静态存储)

  • 作用域受限:只能在当前文件里用,防止多文件命名冲突

  • 生命周期延长:程序启动时分配,程序结束才回收

  • 默认初始化为0

c

static int count; // 默认值为0 static void helper(void) { } // 只能在当前文件用

五、函数传参方式

值传递(C语言默认方式)

c

void swap(int a, int b) { int tmp = a; a = b; b = tmp; } int main(void) { int x = 10, y = 20; swap(x, y); printf("x=%d, y=%d\n", x, y); // 还是 10, 20,没变! return 0; }

值传递的本质是"拷贝"——实参把自己的值复制一份给形参,形参怎么改都不影响实参。

六、今日总结

今天学了二维字符数组函数,核心要点如下:

二维字符数组

  1. 本质是字符串数组,每一行存一个字符串

  2. 定义:char 数组名[行数][列数]

  3. 初始化:char str[3][32] = {"hello", "world", "C"};

  4. 访问:str[i]代表第i个字符串,str[i][j]代表第i个字符串的第j个字符

  5. 输入输出:scanf("%s", str[i])不用加&

函数部分

  1. 函数三要素:定义(写逻辑)、调用(用逻辑)、声明(告诉编译器)

  2. 作用域:局部变量只在当前{}内有效,全局变量整个文件都能用

  3. 生存周期:局部变量随函数调用而生、随函数结束而灭,全局变量随程序

  4. static关键字:让变量生命周期延长到程序结束,同时限制作用域在当前文件

  5. 值传递:C语言传参是"拷贝",形参改变不影响实参

今日感悟

以前所有逻辑都堆在main函数里,写着写着很容易看混。把功能拆成一个个小函数之后,main函数变成了"目录",一眼就能看懂整个程序的流程,简洁易懂。

http://www.jsqmd.com/news/1291831/

相关文章:

  • CAN总线技术详解:从差分信号到STM32实战应用
  • 2026Python内存优化实战教程:布尔数组从1MB到100KB,从入门到精通
  • 本地代码大模型评测实战(五):公平对比的5个陷阱
  • 思维链技术:提升大模型推理能力的关键方法
  • STM32环境监测系统仿真:从ADC采集到Proteus虚拟调试全流程
  • 五线谱谱号快速识别指南:G、F、C谱号核心逻辑与实战心法
  • 真正有效的面试复盘,只需要做两件事
  • 天津宝坻厂库房房东直招哪家可靠
  • RT1052开发环境搭建:MCUXpresso IDE配置与调试实战指南
  • MFC画图工具实战:从GDI绘图到双缓冲与文档视图架构
  • 前端架构的未来趋势:Islands 架构、Qwik 与局部水合的技术演进方向
  • C语言指针进阶——字符串函数手写实现、指针与二维数组
  • 2026年7月代理记账服务内容/内蒙古工商注册加代理记账专业公司推荐_乌海市桔橙财税有限公司 - 行业平台推荐
  • 2026年7月本地麻辣烫加盟/黏糊麻辣烫加盟哪家更好吃_张亮麻辣烫 - 行业平台推荐
  • 三.Linux开发:通讯录(结构体实现)
  • AI仓储不是“买软件”,而是重构作业神经网:3个被低估的底层能力缺口(附自检清单)
  • vLLM大模型推理引擎:PagedAttention原理与生产部署实践
  • 甲骨文云免费服务器从注册到SSH连接完整避坑指南
  • 从零实现C/C++词法分析器:编译原理核心实践指南
  • SAP交货单日期修改实战:BAPI接口详解与ABAP代码实现
  • 计算机网络期末考核心题型精解:从子网划分到TCP状态机实战
  • STM32驱动OLED显示屏实战:从I2C通信到图形界面开发
  • 独立开发者的下一个机会:AI Native 工具市场的细分领域与技术趋势
  • Locale Remulator:彻底解决Windows游戏乱码问题的专业工具
  • Unity ToggleGroup默认选中首项问题:原理剖析与根治方案
  • WPF与YOLO标注工具整合:高效数据标注实战
  • 2026年AI搜索成获客主力,天津老板都在愁这些事 - 星序拾遗
  • FPGA设计核心:硬件并发思维与资源优化实践指南
  • KMS智能激活实战手册:轻松解决Windows与Office激活难题
  • C/C++实现任意进制转换:从原理到工程实践