目录
在C语言中,一个完整的程序包含三个代码控制流程:
顺序流程
分支流程
循环流程
顺序流程
按照书写的先后顺序,从前到后即从上到下执行的结构。
分支流程
如果满足一个条件(2到10之间)则走向一个流程,否则就走向另一个流程。这个流程属于分支流程。
if关键词
if(测试条件)
条件为真的流程
现在,提出一个新需求:
要求输入一个整数,如果数值在2到10之间,那么输出yes;否则什么也不做。
int x;
scanf_s("%d", &x);
if (2 <= x && x <= 10)
{
printf("yes");
}
else关键词
if(测试条件)
条件为真的流程
else
条件为假所执行的流程
现在有需求:
要求输入一个整数,如果数值在2到10之间,那么输出yes;否则输出no。
int x;
scanf_s("%d", &x);
if (2 <= x && x <= 10)
{
printf("yes");
}
else
{
printf("no");
}
if和else关键词只对它后面的一条语句产生效果,并且if和else之间只允许有一条语句。
如果想要执行多条语句,则使用大括号{},形成复合语句。
嵌套if
现有需求:
要求输入一个整数,如果小于2,则输出left;如果在2到10之间,则输出in;如果大于10,则输出right。
int x;
scanf_s("%d", &x);
if (x < 2)
{
printf("left");
}
else
{
if (x > 10)
{
printf("right");
}
else
{
printf("in");
}
}
但是,如果将代码改成
int x;
scanf_s("%d", &x);
if (x < 2)
{
printf("left");
}
if (2 <= x && x <= 10)
{
printf("in");
}
if (x > 10)
{
printf("right");
}
如此,无论x的值满足哪个条件,都必须经过三个if语句的逻辑判断,虽然结果上是没有变化的,但是,如果x已经满足小于2这个条件,则完全没有必要继续测试后面的条件了,这样做会增加性能的消耗。
else if语句
即省略大括号。
现有需求:
输入一个学生的分数x。
x<60,输出不及格;60<x<70,输出及格;70<x<80,输出一般;80<x<90,输出良好;90<x<100,输出优秀。
int x;
scanf_s("%d", &x);
if (x < 60)
{
printf("不及格");
}
else if (60<=x&&x<70)
{
printf("及格");
}
else if (70 <= x && x < 80)
{
printf("一般");
}
else if (80 <= x && x < 90)
{
printf("良好");
}
else if (90 <= x && x <= 100)
{
printf("优秀");
}
条件运算符
C语言中提供了一种条件表达式,作为if,else语句的一种便捷形式。是C语言中唯一一个三元运算符。
测试条件?表达式1:表达式2;
如果测试条件为真,则表达式1的结果是整个条件表达式的结果;反之,是表达式2的结果。
如果x>=10,则c为Y,反之c则为N:
int x;
char c;
if (x >= 10)
{
c = 'Y';
}
else
{
c = 'N';
}
运用条件运算符,可以写作
int x;
char c;
c = x >= 10 ? 'Y' : 'N';
条件表达式的优先级
标记 | 操作符 | 类型 | 优先级 |
---|---|---|---|
++-- | 自增、自减 | 后缀 | 16 |
++-- | 自增、自减 | 前缀 | 15 |
! | 逻辑非 | 单目 | 15 |
+ - | 正、负号 | 单目 | 15 |
* / % | 乘、除、取余 | 双目 | 13 |
+ - | 加、减 | 双目 | 12 |
< > <= >= | 关系 | 双目 | 10 |
== != | 相等、不相等 | 双目 | 9 |
&& | 逻辑与 | 双目 | 5 |
|| | 逻辑或 | 双目 | 4 |
?: | 条件 | 三目 | 3 |
= | 赋值 | 双目 | 2 |
循环结构
while循环
while(循环条件)
循环行为
(高斯求和)现有需求:计算1+2+3+……+99+100最后的值等于多少
int i = 1, sum = 0;
//sum:用于存放每一次累加结果
//i:表示逐个递增的整数
while (i <= 100)
{
sum = sum + i;
i++;
}
在C语言中,非0即为真。
将while()括号里的内容改为0或其他数,0代表假,1(与其他数)代表真。
例如,while(1)将一直循环。
如何保证正确地、有限次数的循环
开始时,为计数器设置初始值。
计数器与一个有限值比较,作为循环条件
更新计数器
for循环
for(计数器设置初始值;循环条件;计数器更新)
循环行为
使用for循环,可以将高斯求和写成
int i, sum = 0;
for (i = 1; i <= 100; i++)
{
sum = sum + i;
}
代码中,for循环中的计数器,设置初始值仅仅在开始时执行一次,将i赋值为1。
循环条件成立,立即进入循环,否则将结束循环。
运行完一次循环行为后,将进行计数器更新,然后再次判断循环条件是否成立。
如果i仅作为计数器使用,并在循环结束后不关心i的值,则可以把i放在计数器初始化时声明,写成
int sum = 0;
for (int i = 1; i <= 100; i++)
{
sum = sum + i;
}
这样i仅在循环体内有效,结束循环后失效。
可以试着用for打印100以内的所有偶数:
for (int a = 0; a <= 100; a=a+2)
{
printf("%d ", a);
}
for循环括号内的三个部分可以写到其他地方,或都可以为空。
例如
(1)计数器初始化为空
int a = 0;
for ( ;a <= 100; a = a + 2)
{
printf("%d ", a);
}
(2)可以把计数器更新的部分写到循环里面
int a = 0;
for ( ;a <= 100; )
{
printf("%d ", a);
a = a + 2;
(3)循环条件也可以为空,但是这将导致死循环
do while循环
do
循环行为
while(循环条件);
如果要输入一个数,这个数若不是整数或者零,就一直输入,直到输入了整数或者零为止。
int x;
do
{
scanf_s("%d", &x);
} while (x < 0);
do while循环和while循环的差别是——
while进入循环前先检查循环条件是否满足,如果不满足,则一次都不执行。
do while先进行一次循环,再检查循环条件。所以至少会执行一次循环。
循环嵌套
for (char c = 'A'; c <= 'E'; c++)
{
for (int i = 0; i <= 9; i++)
{
printf("%c%d ", c,i);
}
printf("\n");
}
代码中,一个for循环嵌套另一个for循环。外层循环是从字母“A”到“E”,内层循环是从数字0到9。
运行之后,外层循环计数器初始值为A,进入循环后将开始内层循环,从0到9,打印的结果为A0到A9。内层循环执行完毕,输出"\n",外层循环计数器更新为B,再次重复上述的过程。
循环辅助
break关键词
作用:结束循环
int i = 0;
while (1)
{
if (i == 10)
{
break;
}
printf("%d", i);
i++;
}
printf("\ni=%d", i);
break以后的语句均不执行。
现有需求:要求用户刷入一个密码,如果密码不为123456,那么输出密码错误;如果输入正确,则输出登陆成功。
int password;
while (1)
{
scanf_s("%d", &password);
if (password == 123456)
{
break;
}
printf("密码错误\n");
}
printf("登陆成功\n");
continue关键词
作用:跳过本次循环,直接进入下一轮循环
while使用continue:
int i = 0;
while (i<20)
{
if (i == 6)
{
i = 12;
continue;
}
printf("%d ", i);
i++;
}
结果为
0 1 2 3 4 5 12 13 14 15 16 17 18 19
for使用continue
for (int i = 0; i < 20; i++)
{
if (i == 6)
{
i = 12;
continue;
}
printf("%d ", i);
}
结果为
0 1 2 3 4 5 13 14 15 16 17 18 19
两次的结果有一出不同,这是因为对于for循环,每次循环结束,都会执行一次for循环括号内的第三个表达式。
所以continue之后先执行i++,再进行新一轮循环。
for使用break
int i = 0;
for (i = 0; i < 20; i++)
{
if (i == 6)
{
i = 12;
break;
}
printf("%d ", i);
}printf("\ni=%d", i);
结果为
0 1 2 3 4 5
i=12
使用break后直接跳出循环,没有更新计数器。
总结
for中使用continue,将立即更新计数器,再进入新循环;
for中使用break,将直接跳出循环,不会更新计数器。
break和continue嵌套
作用于自己直属上层循环,例如break:
for (;;)
{
for (;;)
{
break;//内层循环调用break,跳到外层循环
}// ↓
break;//外层循环再次调用break, ←
}// 结束外层循环
多重选择语句switch
switch(整形表达式)
{
case 整形常量1:
语句
case 整形常量2:
语句
case 整形常量3:
语句
default:
语句
}
现有一个自动问答机器人,需要写出程序使得它会根据用户提出的问题回复对应的句子的,便可以使用switch语句:
printf("请根据屏幕上的提示进行操作。\n");
int 问题;
scanf_s("%d", &问题);
switch (问题)
{
case 1:
printf("您提问:今天周几?\n");
printf("小C真诚地回答您:今天周日,暂不工作,将在5s后关机,谢谢配合。\n");
break;
case 2:
printf("您提问:吃了吗?\n");
printf("小C真诚地回答您:谢邀,机在维修中心,刚喝汽油。\n");
break;
case 3:
printf("您提问:我可以拿走这个吗?\n");
printf("小C真诚地回答您:不可以呢亲,请先去XX窗口办理相关凭证。为您估算排队时间...预计一个小时。\n");
break;
default://如果输入不符合以上任一情况,则
printf("小C迷惑地回答您:小C听不懂您在说什么呢,请根据提示使用智能小C问答机器——扣1或2或3呢亲。\n");
}
如果case末没有加上break,则程序会把下面语句全部执行。当switch语句运行时遇到break关键字时会跳出,接下来剩下的case语句也不会再执行,switch语句结束。
而switch语句中的break只属于前者,效果只对其有效。(continue不对witch语句产生影响)
假如今天不是周日,智能问答机器小C不会在回答完一句后关机,而是继续服务,则可以写成
printf("请根据屏幕上的提示进行操作。\n");
int 问题;
while (1)
{
scanf_s("%d", &问题);
switch (问题)
{
case 1:
printf("您提问:今天周几?\n");
printf("小C热情地回答您:今天周一,小C将燃尽全油为您服务,请问您有什么问题?\n\n");
break;
case 2:
printf("您提问:吃了吗?\n");
printf("小C猝不及防地回答您:嗝...\n\n");
break;
case 3:
printf("您提问:我可以拿走这个吗?\n");
printf("小C大方地回答您:拿,都可以拿。\n\n");
break;
default:
printf("小C迷惑地回答您:小C听不懂您在说什么呢,请根据提示使用智能小C问答机器——扣1或2或3呢亲。\n\n");
}
}
总结:学会了分支和循环后,感觉在C语言的学习上进了一大步,但是仍然有不足之处,希望能在后面的学习中不断精进。