【嵌入式修炼:C语言篇】——二维字符数组和函数的概念
数据类型数组名 [ 常量表达式1 ][ 常量表达式2 ];1)main函数之前:起到定义和声明的作用,使用时直接调用2)main函数之后:在函数调用前,作函数声明,即函数头 + 分号//函数声明。
在二维字符数组部分注意清理缓冲区的知识点;在函数的部分要训练将问题拆解成更小问题方便实现模块编程的思维,每个函数体也要写得言简意赅,还有理解函数能够被调用的本质原因
(一)二维字符数组
一、定义
1.一般形式:
数据类型 数组名 [ 常量表达式1 ][ 常量表达式2 ];
- eg: char s[3][4] = { };
2.本质:
一维字符数组的一维字符数组
3.用途:
批量存放多个字符串
二、初始化
1.部分初始化:
对数组内部分元素赋值,其余元素的值自动为0
- eg: char s[100][10] = {"hello","world","english","begin"};
2.行省略初始化:
定义数组时不注明数组行数,系统根据初始化的值推断数组行数
- eg:char s[ ][10] = {"hello","world","english","begin"};
三、赋值
1.字符串赋值:
strcpy(s[0], "hello");
//str[0] 相当于是内部的一维数组的数组名 ,将"hello"赋给二维字符数组的第一行
2.输入赋值:
- scanf("%s",str[0]);
- gets(str[0]);
//将"hello"赋给二维字符数组的第一行
3.清理缓存区
while(getchar( )!='\n');(千万不能丢掉分号,因为while的条件语句在执行时已经把'\n'吃掉了,循环体是空!)
//让循环不断读取输入缓冲区 直到 遇到 \n 结束,起到清理作用
4.注意:
在输入字符串时,如果在scanf语句的下一条语句用gets语句的话,需要先清理缓冲区,因为 scanf("%c", &变量) 读取字符时,不会自动丢弃输入缓冲区里的换行符 \n ,而 gets 会读取换行符并直接结束输入;但两个 gets 连续使用时,前一个 gets 会把缓冲区的换行符一起读走,不会影响后一个。gets 函数存在严重的缓冲区溢出风险,C11 标准已将其废弃,实际开发中建议用 fgets 替代。
(二)、函数
一、引入
在C语言中,子程序的作用是由函数来完成的。一个C程序可由一个主函数和若干个其他函数构成。由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次
1.函数的好处:
- 让问题变的容易解决
- 拆解成更小问题方便实现模块编程
- 减少重复代码的编程,提高了编程效率
- 方便调试和提升项目的稳定性
二、函数的实现
1、一般形式
类型说明符 函数名 (形式参数)
{
//声明部分
//语句部分
函数体
}
1)类型说明符:也称为返回值类型,代表的是返回值的数据类型。
- 可以为基本数据类型,但是数组不能做函数的返回值,因为函数无法返回一堆数据。
- 当类型说明符与返回值类型不一致时,以类型说明符为准。
- 返回值类型可以不写,此时默认为int型
2)函数名:本质上是标识符,命名规则和变量命名规则一致,最好见名知意。
- 注意:即使多个变量的类型相同,但是不能省略类型名,每个变量前都需要写类型名
3)( 形式参数 ):用来接收给到函数的数据,可以书写成变量的形式。
- 使用时注意实参和形参做到个数相同、类型一致、顺序一 一对应
- 如果不需要形参,可以写为void,
4)函数体:用来实现函数功能的具体代码。
- 如果函数要带出结果,需要考虑返回值类型的设计
- 若函数不需要带回结果,设计为void(空类型),此时不需要再写return语句,如果要写,return 后面不需要跟任何值,0 也不行
2、实现函数的步骤
step1:根据功能来确实函数名
step2:输入数据——准备数据部分
step3:处理数据——函数体来实现
step4:输出数据——对结果的处
3.函数定义的位置:
1)main函数之前:起到定义和声明的作用,使用时直接调用
2)main函数之后:在函数调用前,作函数声明,即函数头 + 分号
eg: int add(int a,int b); //函数声明
三、函数的调用
1.函数调用语句:
当时函数返回值类型为空时,可以直接通过函数名 + ( 形参)调用
- 函数定义必须写为:void 函数名 (形式参数){ 函数体;}。void必须写,形参可有可无
2.函数表达式:
将函数作为表达式中的一部分来调用
a = 2 + add(1,2);
3.函数作为参数:
将函数作为表达式中一个参数来调用
printf("retd\n",add(a,b));
四、函数的嵌套调用
一个C程序可由一个主函数和若干个其他函数构成。由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次。
1.函数能够实现调用本质 :
1)栈:
特点:
- 是内存上一块空间
- 数据先进后出 FILO
- 空间大小 linux系统下 默认每个程序 栈大小 8M
- 栈的大小可以改
eg: 局部自动变量 都存放栈上
栈上的数据 --- 自动申请自动释放
2)堆:
特点:
- 大
- 手动申请,手动释放
eg: 字符串常量区:
"hello"
3)全局区/静态区 ---- 全局变量 ,静态变量
- 数据不初始化 -- 默认全是 0
4)代码区 :
程序中的代码指令
总结:C语言函数能实现调用,本质是代码区、栈区、全局区、堆区四个内存区域的协同配合:代码区存放函数的二进制指令并提供入口地址,函数调用时CPU跳转至此执行;栈区会创建专属栈帧,存放形参、局部变量和返回地址,函数执行完后自动释放栈帧;全局区存储全局变量和静态变量,为函数调用提供跨调用周期的共享数据;堆区则按需提供手动申请的动态内存,支撑函数对可变大小数据的处理需求。
2.特殊的嵌套调用
自己调用自己 --- 递归
1) int f1() //直接递归
{
printf("f1");
f1(); //自己调用自己
}
2) int f1() //间接递归
{
printf("f1");
f2(); //自己调用自己
}
3) int f2()
{
printf("f2");
f1(); //自己调用自己
}
更多推荐

所有评论(0)