嵌入式学习Day11 C语言 --- 数组作为函数的形参、标识符的作用域与生命周期

📅 2026/8/18 13:25:09
嵌入式学习Day11 C语言 --- 数组作为函数的形参、标识符的作用域与生命周期
一、数组作为函数的形参1.一维整形数组做函数形参//形式上void printArray(int a[],int len);//实际上void printArray(int *a,int len); //指针的形式2.一维字符型数组做函数形参//形式上void printStr(char s[]); //字符串有结束标志//实际上void printStr(char *s); //字符串有结束标志3.二维整形数组做函数的形参形式上: //形参 --数组形式行数void printArray(int a[3][4],int row);实际上void printArray(int (*a)[4],int row); //编译器 的最终解释实参:printArray(a,row); //数组名 行数int a[3][4] ---int a[][4]int[4] a[]练习定义一个二维整型数组实现一个函数对二维数组元素求和4.二维字符型数组做函数形参:char s[3][10] {hello,world,china};形式上void printStr(char s[][10],int row) //注意需要传行数因为操作多个字符串本质上:void printStr(char (*s)[10],int row)实参printStr(s,row); //数组名 行数练习:准备3个字符串实现函数 找出最大值练习:准备3个字符串排序二、标识符的作用域和可见性问题生命周期栈中存储局部变量函数内部定义的变量其作用域仅限于该函数。比如在一个C语言函数中定义的整型变量 int num 10;当函数被调用时这个变量就会被压入栈中。函数执行结束后这些局部变量所占的栈空间会被释放。函数形参函数调用时传递的参数也会被保存到栈里。例如在调用 func(int a, int b) 函数时实参的值会被复制到栈上传递给函数这样函数内部就可以使用这些参数进行运算。返回地址记录函数调用结束后要返回的程序位置。当一个函数调用另一个函数时会把当前函数的下一条指令地址压入栈中被调用函数执行完毕后会根据栈中保存的返回地址返回到原函数继续执行。中断上下文程序状态在发生中断如硬件中断、软件中断时会把当前程序的状态信息如寄存器的值保存到栈中。以微处理器为例当中断发生时会将程序计数器PC、状态寄存器等的值压入栈。中断处理程序执行完后再从栈中恢复这些信息使程序能够从中断处继续执行。堆区在操作系统为进程分配的内存空间里堆区是其中一部分。它由程序员手动管理用于动态分配内存。与栈区由系统自动分配和释放内存不同堆区为程序提供了更灵活的内存使用方式允许程序在运行时根据实际需求来决定分配和释放内存的时机和大小。使用malloc()、calloc()和realloc()等函数来请求操作系统分配指定大小的内存块。使用free()函数来释放之前用malloc()等函数分配的内存。如上述C语言代码中在使用完arr后需要添加free(arr);来释放内存。作用域:作用的范围局部变量 --- 一定在某一个{} 范围内全局变量 --- 不在任何一个{} 范围内可见性:程序运行到某个点哪些标识符可见标识符的可见性的规则:1.先定义后使用2.同一作用域中不能有同名标识符3.在不同的作用域同名标识符相互之间没有影响4.如果是不同的作用域但是作用域之间存在嵌套关系,则 内层的作用域的同名标识符会屏蔽外层的作用域的同名标识符(就近原则)生命周期:动态变量(局部变量的 (生命周期):从定义的语句开始到所在的作用域范围结束eg:栈上的是局部变量 自动申请 自动释放 全局区(静态区)上的是 静态变量 (全局变量)从程序一开始运行就存在直到程序结束时销毁注意:全局变量(静态变量)1.不能用变量进行初始化,只能常量初始化 int a 10; //true int b a;//error2.静态区的变量只会被初始化一次 int a ; a 10; //error int a 10; //true int a; //truefor(i 0;i 3;i) { static int b 0; b; printf(b %d,b); //打印三次分别是 b 1,b 2,b 3 }3.值具有 继承性auto int a; //这个是一个自动变量 --- 栈上开辟的变量static int a; //静态区//修饰的是 局部变量register int a; //CPU 寄存器//建议性考点:不能 (取地址)因为是cpu内部的寄存器取地址运算是取得内存的地址register int i; 将变量存储在寄存器中提高访问速度for( i 0; i 100000000; i){}extern int a; //扩展 延伸//表示 此时这个a 不是在当前文件中定义的 //如果要用请到别的文件中寻找//多文件编程//一般使用在多文件编程中://如果想在当前文件使用别的文件中的 全局变量 //此时可以使用//extern int a; //做声明//相当于把别的文件中的变量作用域扩展到当前文件//全局变量前面static 修饰局部变量//将局部变量 存储在了 全局区(静态区)//将局部变量的生命周期延长 作用域不变 //只能被初始化一次#include stdio.h void function() { static int counter 0; // 使用 static 修饰的局部变量 counter; printf(Counter: %d\n, counter); } int main() { function(); // 第一次调用 function 函数 function(); // 第二次调用 function 函数 function(); // 第三次调用 function 函数 return 0; }在上述代码中function 函数内部定义了一个 static 局部变量 counter 并初始化为 0。当第一次调用 function 函数时counter 被初始化为 0然后递增为 1 并输出。当第二次调用 function 函数时counter 不会再次被初始化为 0而是保持上一次调用后的值 1然后递增为 2 并输出。同样第三次调用时counter 保持上一次的值 2递增为 3 并输出static 修饰全局变量//表示 将全局变量 的作用域限定到本文件中//别的文件中不能extern了extern 可以放在函数声明中 --函数声明//表示的意思 --将函数作用域扩展到当前文件static 加在函数前面// 此时效果与修饰全局变量效果一样// 将函数作用域限定到本文件中面试题:1.你知道static吗?