嵌入式学习 day9:函数
一、二维字符数组二维字符数组本质上就是一个字符串数组——每一行存一个字符串。1. 定义cchar str[5][32]; // 5行每行最多31个字符留1个给\02. 元素的访问cstr[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. 输入与输出cchar 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. 函数的调用cint 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. 作用域哪里能用局部变量在函数或代码块{}内定义只能在这个范围内使用全局变量在所有函数外面定义整个文件都能用cint 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自动型默认cauto int a; // 等价于 int a;存在栈区不初始化就是随机值进入作用域时开辟退出时回收2. register寄存器存储cregister int a;尽量放在CPU寄存器里更快如果寄存器满了等价于auto3. extern外部声明声明变量或函数是在别处定义的多文件编程时用。4. static静态存储作用域受限只能在当前文件里用防止多文件命名冲突生命周期延长程序启动时分配程序结束才回收默认初始化为0cstatic int count; // 默认值为0 static void helper(void) { } // 只能在当前文件用五、函数传参方式值传递C语言默认方式cvoid 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; }值传递的本质是拷贝——实参把自己的值复制一份给形参形参怎么改都不影响实参。六、今日总结今天学了二维字符数组和函数核心要点如下二维字符数组本质是字符串数组每一行存一个字符串定义char 数组名[行数][列数]初始化char str[3][32] {hello, world, C};访问str[i]代表第i个字符串str[i][j]代表第i个字符串的第j个字符输入输出scanf(%s, str[i])不用加函数部分函数三要素定义写逻辑、调用用逻辑、声明告诉编译器作用域局部变量只在当前{}内有效全局变量整个文件都能用生存周期局部变量随函数调用而生、随函数结束而灭全局变量随程序static关键字让变量生命周期延长到程序结束同时限制作用域在当前文件值传递C语言传参是拷贝形参改变不影响实参今日感悟以前所有逻辑都堆在main函数里写着写着很容易看混。把功能拆成一个个小函数之后main函数变成了目录一眼就能看懂整个程序的流程简洁易懂。