概述
一、控制流。 -- switch语句
1、为什么会有switch语句?
就是因为if/else语句,如果出现分支多的情况,那么就会造成代码很累赘。
2、基本框架?
aaaa;
switch(判断的值) --> 整型、字符型、枚举类型 --> 不可以填字符串、浮点型、数组、指针。
{
case 结果1: //如果判断的值等于结果1,则执行bbbb。
bbbb;
break; //break在switch语句中作用:结束分支。
case 结果2: //如果判断的值等于结果2,则执行cccc。
cccc;
break; //break在switch语句中作用:结束分支。
default: //如果判断的值不满足以上的所有结果,则会执行dddd。
dddd;
break;
}
eeee;
3、处理流程。
aaaa; --> 判断的值是否与下面的case语句后面的结果一致,例如判断的值等于结果2 --> 执行cccc --> eeee
例题: 从键盘中获取一个值,存放在变量中。
数字1 --> 打印one
数字10 --> 打印ten
如果都不是 -> 打印error
#include <stdio.h>
int main(int argc,char *argv[])
{
int x;
scanf("%d",&x);
switch(x)
{
case 1:
printf("one!n");
break;
case 10:
printf("ten!n");
break;
default:
printf("error!n");
break;
}
return 0;
}
4、如果不写break语句会怎么样? --> 会一直往下运行代码
int main()
{
int c = 1;
switch(c)
{
case 1:
c++;
case 2:
c+=5;
break;
default:
c+=4;
}
printf("c = %dn",c); //7
}
5、switch语句能不能进行范围判断?
从键盘中获取一个数字
0~100 --> small
100~200 --> middle
201~300 --> large
其他 --> error
#include <stdio.h>
/*
0~100 --> small
101~200 --> middle
201~300 --> large
其他 --> error
*/
int main(int argc,char *argv[])
{
int x;
scanf("%d",&x);
switch(x)
{
case 0 ... 100:
printf("small!n");
break;
case 101 ... 200:
printf("middle!n");
break;
case 201 ... 300:
printf("large!n");
break;
default:
printf("error!n");
break;
}
return 0;
}
6、switch语句容易错的地方。
1)判断的值必须是整型。
2)每一个case语句后面记得添加break; 除非有意去执行后面的代码
3)记得写default,即使这个default永远都不会执行。
4)break语句在switch语句是跳出switch分支,与循环无关。
5)在进行范围判断时,记得"..."的两边一定有空格,不然也是编译出错。
二、两个影响着控制流的语句。 -- break语句和continue语句。
1、break语句。
1)作用对象:switch语句、 for循环、while循环、do_while循环。
2)作用: 跳出switch语句 跳出循环
2、作用场景:
1)当break作用于switch语句的时候:
switch(x)
{
case 1:
xxx;
break; --> 仅仅是跳出switch语句而已。
}
yyy;
2)当break语句作用于循环时,一般都是与if分支连用。
aaa;
while(1)
{
xxx;
yyy;
if(判定条件) //如果判定条件为真,那么就执行break语句
{
break; //跳出循环(虽然与if语句连用,但是break跳出不是if,而是循环)
}
}
bbb;
处理流程:
aaa --> xxx; --> yyy; --> 判定条件 -> 真 --> break --> bbb;
3、几个特殊的例子。
1)
int main()
{
while(1)
{
while(1)
{
while(1)
{
break;
xxx;
}
yyy; --> 当break语句执行后,就会运行yyy
}
zzz;
}
qqq;
return 0;
}
2)
int main()
{
while(1)
{
switch(x)
{
case 1:
break;
}
xxx; --> 当break语句执行后,就会执行xxx
}
yyy;
}
练习:
int main()
{
int k=5,n=0;
do{
switch(k)
{
case 1:
case 3: n+=1; break;
default: n=0; k--;
case 2:
case 4: n+=2; k--; break;
}
printf("%dn",n);
}while(k>0 && n<5); // 2345
}
2、continue语句。
1)作用对象: for循环、while循环、do_while循环。
2)作用: 立即结束当次循环,马上开始下一次循环。
3)场景:
aaa;
while(1)
{
xxx;
if(判定条件)
{
continue;
}
yyy;
}
zzz;
处理流程:
aaa; --> xxx; -> 判定条件 --> 真 --> continue --> xxx; -> 判定条件 -> 假 -> yyyy --> xxx;
三、函数概念。
1、什么是函数?
C语言是一种面向过程的语言,任何的一个大过程都可以拆分为多个小过程。
大过程 --> 程序
小过程 --> 函数
C语言称之为函数式语言 -> C语言程序是由函数堆砌出来的。
函数其实就是一个模块的封装。 --> 例如: 快餐店就是(买菜,做菜,端菜,洗碗)的一个封装。
2、封装成函数有什么意义?
1)简化代码,使得代码变成一个独立的模块
int main()
{
int a = 吃早餐(); //a就是存储着吃早餐这个过程的结果
if(a == 0)
{
printf("我吃饱了");
}
else{
printf("我没吃饱");
}
搭地铁();
上课();
吃饭();
}
2)方便工程师后期维护项目。
3)对于调用者而言,不需要关心实现过程,只需要关心调用函数之后的结果就可以。
四、函数书写规则。
1、在C语言中,有哪些函数种类?
main函数:主函数,在程序中有且仅有一个,程序从main函数开始,从main函数结束。
系统函数:在man手册的第2手册,用户只需要调用即可,不需要写实现过程。
库函数: 在man手册的第3手册,用户只需要调用即可,不需要写实现过程。
自定义函数:不能通过man手册去查询,用户必须要写清楚函数实现过程才可以调用。
#include <stdio.h>
int main(int argc,char *argv[])
{
printf("helloworld!n"); //调用库函数,用户不需要写实现过程
//my_fun(); //调用自定义函数,用户必须要写清楚函数实现过程,才可以调用
return 0;
}
2、如何书写自定义函数?
1)确定函数的函数名。
必须: 命名规则与变量声明规则一致。 例如:my_fun
非必须: 函数名最好能够体现函数的功能。例如:play_music
2)确定函数的形式参数。 --> 写在函数名的后面。
有形式参数: my_fun(形式参数1,形式参数2,形式参数3,...);
无形式参数: my_fun()
吃早餐(一些钱,哪种面包) --> 你想调用吃早餐这个函数,就必须向函数中传递金钱金额以及面包的种类。
快餐店(一些钱,哪些菜,用餐人数)
my_fun(int a) --> 你想调用my_fun这个函数,就必须向函数中传递一个整型数据。
my_fun() --> 你想调用my_fun这个函数,直接调用就可以了,不需要传递任何额外的参数。
3)函数体。
my_fun(int a) -->函数头
{ -->函数体
/* 函数的实现过程 */
}
4)确定返回值类型 --> 写在函数名的前面
有返回值 --> 必须确定好类型
int --> 无论这个函数成功还是失败,都会返回一个int类型的数据。
char --> 无论这个函数成功还是失败,都会返回一个char类型的数据。
int my_fun(int a)
{
return 0; //0就是返回值的结果,必须与这个int匹配。
}
无返回值 ---> void 代表这个函数没有返回值
void my_fun(int a)
{
return; --> 代表该函数返回,但是没有返回值结果。
}
总结自定义函数框架:
返回值类型 函数名字(形式参数列表)
{
....;
....;
return ?;
}
例题: 写一个函数,要求接收两个int类型的数据,函数功能是求和。
#include <stdio.h>
int add_sum(int x,int y)
{
int z;
z = x + y;
return z;
}
int main(int argc,char *argv[])
{
int ret = add_sum(10,20);
printf("ret = %dn",ret); //30
return 0;
}
五、如何调用函数?
1、确保调用的函数的实现过程已经写好了。
int add_sum(int x,int y) //x,y形式参数 x=10 y=20
{
int z;
z = x + y;
return z;
}
2、在函数体内,直接写函数的名字就可以了,后面紧跟着一个圆括号,圆括号写实际参数。
int main()
{
add_sum(10,20); //10,20 --> 实际参数
//当我们调用该函数时,会直接将10赋值给x,将20赋值给y
}
结论: 形式参数的值是由实际参数直接初始化,这个过程是不可逆的。
思考题:不可逆是什么意思?
修改b的值,a的值不会受到影响。
func(int b) //b = a
{
b = 200;
}
int main()
{
int a = 100;
func(a); //a是实际参数
printf("a = %dn",a); //100
}
3、往往调用函数时,都要保存函数的返回值结果,那么这样就知道函数的结果是什么。
关心返回值是什么:
int ret;
ret = add_sum(10,20);
printf("ret = %dn",ret);
不关心返回值是什么:
add_sum(10,20);
练习1: 写一个函数,实现接收3个int类型的数据,要求函数内经过约定的计算之后,得到结果并打印出来。
前面2个参数用于计算,最后一个参数是计算方式。
1 -> +
2 -> -
3 -> *
4 -> /
func(3,4,1); -> 7
func(3,3,4); -> 1
#include <stdio.h>
int my_func(int x,int y,int z)
{
int ret;
switch(z)
{
case 1:
ret = x + y;
break;
case 2:
ret = x - y;
break;
case 3:
ret = x * y;
break;
case 4:
ret = x / y;
break;
}
return ret;
}
int main(int argc,char *argv[])
{
int ret = my_func(3,4,4);
printf("ret = %dn",ret);
return 0;
}
六、函数声明。
1、函数的定义与函数的声明有什么区别?
函数的定义:它包含了函数的名字、函数形参、函数返回值类型、函数的实现过程。
int add_sum(int x,int y)
{
int z;
z = x + y;
return z;
}
函数的声明:它包含了函数的名字、函数形参、函数返回值类型。
int add_sum(int x,int y);
2、什么时候需要写函数的声明?
1)如果函数的定义写在main函数的前面,则不需要声明该函数。
#include <stdio.h>
int add_sum(int x,int y)
{
int z;
z = x + y;
return z;
}
int main(int argc,char *argv[])
{
int ret = add_sum(10,20);
printf("ret = %dn",ret); //30
return 0;
}
2)如果函数的定义写在main函数的后面,则需要声明该函数。
#include <stdio.h>
int add_sum(int x,int y); //如果不声明,就会编译警告。
int main(int argc,char *argv[])
{
int ret = add_sum(10,20);
printf("ret = %dn",ret); //30
return 0;
}
int add_sum(int x,int y)
{
int z;
z = x + y;
return z;
}
七、从内存角度去分析函数的调用过程。
请求出以下程序的结果:
int my_fun(int z)
{
z = z/5;
return z; //3
}
int func(int x,int y)
{
int c;
c = x + y;
my_fun(c); --> 不关心返回值
return c; //15
}
int main(int argc,char *argv[])
{
int a = 10,b = 5;
int ret = func(a,b);
printf("ret = %dn",ret); //15
return 0;
}
1、遇到这种给程序,求结果的题目,直接画内存图来分析。
2、从main函数开始分析。
3、局部变量是在栈区申请空间,全局变量在data/bss段申请空间。
4、当调用函数时,就开始去这个函数中分析代码。
5、形式参数也是属于这个函数中的局部变量。
6、形式参数与实际参数占用不同的内存空间。
7、形式参数的值是由实际参数直接初始化。
8、在函数体内,是执行完return语句之后,局部变量才会释放。
9、函数的返回值会返回到函数调用的地方。
练习2:求出以下结果
int swap(int x,int y)
{
int t;
t = x;
x = y;
y = t;
return 0;
}
int main()
{
int a,b;
scanf("%d %d",&a,&b); 5 3
swap(a,b);
printf("a = %d,b = %dn",a,b); 5 3
return 0;
}
为什么没有调换过来?
形式参数的值是由实际参数直接初始化,这个过程不可逆。形式参数x与y的值确实可以交换,但是并没有影响到实参a与b,所以没有调换。
练习3:求出以下结果
int fun(int a,int b)
{
if(a > b)
{
return a;
}
else{
return b;
}
}
int main()
{
int x = 3,y = 8,z = 6,r;
r = fun(2*z,fun(x,y));
printf("r = %dn",r);
}
练习4:求出以下程序的结果。
#include <stdio.h>
int get_2_max(int x,int y)
{
if(x > y)
return x;
else
return y;
}
int get_4_max(int x,int y,int z,int k)
{
int m = get_2_max(x,y);
m = get_2_max(m,z);
m = get_2_max(m,k);
return m;
}
int main(int argc,char *argv[])
{
//1. 连续从键盘中获取四个数字
int a,b,c,d;
scanf("%d %d %d %d",&a,&b,&c,&d); //10 40 30 20
//2. 求出四个数字的最大值
int ret = get_4_max(a,b,c,d);
printf("ret = %dn",ret);
return 0;
}
最后
以上就是大意洋葱为你收集整理的第三篇,嵌入式中控制流语句(接上一篇)和函数详细说明。的全部内容,希望文章能够帮你解决第三篇,嵌入式中控制流语句(接上一篇)和函数详细说明。所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复