100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > C语言学习笔记07-1-语句结构:选择/循环(附三元运算符;DevC可以for定义临时变量的设

C语言学习笔记07-1-语句结构:选择/循环(附三元运算符;DevC可以for定义临时变量的设

时间:2024-04-17 11:31:25

相关推荐

C语言学习笔记07-1-语句结构:选择/循环(附三元运算符;DevC可以for定义临时变量的设

选择/分支 与 循环/重复 语句结构

本质与流程图的三种结构类似,只是C语言没有until型循环,不难理解。文末捎带说一下goto语句。

结构化语句可以实现程序单一出口,goto 是非结构化的,会打乱程序的运行结构,建议是初学者慎用goto。

1. 选择/分支语句(if语句和switch语句语法)

1.1. C语言if语句形式(附三目运算符)

(1) if (条件) 表达式;(表达式可以换行缩进写;下面条件用ccc代表,表达式用字母代替。)

 或者:

if (ccc) {

xxx1;

xxx2;

}

(2) if (ccc) xxx;

else yyy;

 或者:

 if (ccc) {xxx1; xxx2;}else {yyy1; yyy2;}

(3)级联形式(与多个if的连用效果不同,它的本质是多个if else 的嵌套):

if (ccc1) {… …}else if (ccc2) {… …}else if (ccc3) {… …}else {… …}

(一个基础的判断原则:用大于号判断时,数值从高处往下走;用小判断从低开始走。)

顺带一提三元运算符,形如:<表达式1> ? <表达式2> : <表达式3>,表达式1通常是逻辑/关系表达式,表达式2和表达式3可以是常量、变量或表达式,含义是:如果表达式1为真则执行表达式2,否则执行表达式3,并返回执行结果。优先级仅高于赋值运算符,?:遵循就近匹配原则,编程时注意是否需要加括号。

注意点:

(i)条件的表示是逻辑表达式,主要运用关系运算符,条件只有真(值为1,或值非0)或假(值为0)两种。注意编程中==与=的差异

(ii)if-else语句可以没有{},但此时只有紧跟的一句语句受其控制。

(iii)else总和最近的还没有与else匹配的if匹配,if elseif else也是一样。(勤加{}减少出错)

(iv)if语句支持嵌套,三元运算符也能嵌套

比较两数的大小——

方案1:
方案2:
方案3:

比较三个数大小——

方案1:
方案2:

或者写成:

此时务必加第一组(),否则会出错。

1.2. switch-case(切换-情况)

switch (变量表达式) {

case 常量1: 语句;break;

case 常量2: 语句;break;

case 常量3: 语句;break;

default: 语句;break;

}

switch语句作用是提高一些情况下级联的if-else语句的执行效率,可以嵌套。

注意事项:

(1)switch()的参数类型只能是整数型结果;

(2)case标签必须是常量表达式(整数型的常数或常数计算表达式,C99支持此处是整数型常变量),case标签必须唯一(不同case不能出现相同的值);

(3)当变量表达式的计算的值与一个case的常量相等时,就从上往下依次执行后面所有的case中的语句直到switch语句结束,除非使用break;语句跳出switch语句,如果没有符合的常量就执行default中的默认语句。

(4)switch中不能单独用continue循环控制,除非是写在循环中的switch。(if类似)

判断成绩——

#include <stdio.h>int main() {printf("输入成绩0~100:");double grade = 0;scanf("%lf", &grade);while (getchar() != '\n') {;}switch ((int)grade / 10) {//强制类型优先级仅次于最顶级优先级case 10://{//if (grade > 100) break;//}case 9:{printf("A.\n");}break;case 8:{printf("B.\n");}break;case 7:{printf("C.\n");}break;case 6:{printf("D.\n");}break;case 5:case 4:case 3:case 2:case 1:case 0:{printf("F.\n");}break;default:{printf("Error!\n");}break;}char rank;printf("请输入等级(如:A):");scanf("%c", &rank);switch (rank) {case 'A': printf("90~100\n"); break;case 'B': printf("80~89\n"); break;case 'C': printf("70~79\n"); break;case 'D': printf("60~69\n"); break;case 'F': printf("0~59\n"); break;}return 0;}

一年的第几天?(闰年判断)——

闰年:公历年份是4的倍数且不是100的倍数是闰年 或者 公历年是整百数的必须是400的倍数也是闰年。闰年366天(2月29天),平年365天。

int year, month, date,isLeap, //闰年 leap yeardays = 0; //天数printf("输入日期(格式:yyyy-mm-dd),""如-1-11,请输入:");scanf("%d-%d-%d", &year, &month, &date);isLeap = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);switch (month) {case 12: days += 30;case 11: days += 31;case 10: days += 30;case 9: days += 31;case 8: days += 31;case 7: days += 30;case 6: days += 31;case 5: days += 30; case 4: days += 31;case 3: days += 28 + isLeap;case 2: days += 31; //1月天数,注意是错开的case 1: days += date; break;default: printf("month error"); return -1;}printf("%d-%02d-%02d是这一年的第%d天。\n", year, month, date, days);

2. 循环/重复语句(3类)——“何时是个头?”

循环的逻辑一定要想明白,要符合需求,逻辑错误是没有报错的。次数固定选择for,必须先做选择dowhile,其他情况选while。循环也支持嵌套。

2.1. while(当型,先判断后做) in loop~~~

if与while的区别就是执行一次还是多次。关键是循环内要有改变条件的机会,否则会陷入死循环(除非是你想要一个永远执行的循环,一般需要避免死循环)。

注意语法正确和逻辑正确的不同;检查方式:debug调试,printf输出代码位置here1或变量值、地址等,边界值覆盖测试。重点是会思考循环计算中变量值的变化及输出的情况,思考循环次数(初值0、1或n与条件<还是<=等)

循环计算位数——

初始版是用if + /10,无法计算任意位

循环处理本质是数数,但是计算机不能预先看到位数,因此只能倒着从个位数起。

2.2. do…while(先做再判断)

两种while循环与until循环(C没有until)的差异,while是满足这个条件下执行,until是到满足这个条件时停止(不满足时执行)。

dowhile注意while()后一定加; 不要忘记!!!

来个练习:整数求逆——

思路:对一个整数%10得到个位数,/10就去掉了个位数。循环这样的操作就实现了对整数的分解。不同输出要求不同处理。

如果要正序输出呢?最简单的想法:两次逆序负负得正,但无法处理结尾有0的情况,解决办法先确定位数或一个用来/出最高位的数,再做其它处理。

整数正序分解——

#include <stdio.h>int main() {int x = 13425, cnt = 0; //7000 0scanf("%d", &x);int mask = 1, tmp = x;//位数判断while (tmp > 9) {tmp /= 10;cnt ++;mask *= 10; //double pow 10 cnt-1}//printf("%d",mask);do {int d = x / mask;printf("%d", d);if (mask > 9) {printf(" ");}x %= mask;mask /= 10;//printf("x=%d,mask=%d,d=%d\n",x,mask,d);} while (mask > 0);printf("\n");//逆序再逆序//int ret = 0;//do {//int d = x % 10;//ret = ret * 10 + d;//x /= 10;//} while (x > 0);//printf("ret = %d\n", ret);////x = ret;//do {//int d = x % 10;//printf("%d", d);//if (x >= 10) {//printf(" ");//}//x /= 10;//} while (x > 0);//printf("\n");return 0;}

补充:1. 求平均数套路,初值0累加求和,同时循环计数。2. 求阶乘n!:求积的小套路是初值为1。

2.3. for循环——“最古老的循环”

for(初始条件; 循环条件; 每轮循环的必要动作) {;;…;} 。for也是先判断再做,三个表达式可以选择省略,具体看需求及解决方式是如何的。当初值和动作为空时for( ;条件; ) == while(条件)

for循环括号中定义临时变量的方式需C99支持,有时C编译器还需要添加额外选项,C++是直接可以这样写的。

如Dev中,工具-编译选项-编译器,勾选编译时加入以下命令,添加命令选项 -std=c99

同时选择代码生成/优化->C编译器:->支持所有ANSI C标准为No

这样devcpp就支持定义循环临时变量了:

99乘法表1:

99乘法表2:

输出时先j后i是因为i控制了列。

素数判断——

素数(质数):在大于1的自然数中,只能被1和自己整除的数是素数,反之是合数。

此处素数与上面的闰年的判断中,包含一个小套路:设置标志的变量如isPrime或isLeap(exit、flag),其初值1或0及计算结果1或0,可辅助做判断或计算。

【修改一下判断条件:】

【可以避免负数、0、1的误判。】

当判断出不是素数时break直接跳出循环,不用再跑完整个循环了。

简单素数表——

int cnt = 0;int x = 100;printf("打印素数表,如您想知道100以内的素数就输入100,:"); scanf("%d", &x);for (int i = 2; i <= x; i++) {int isPrime = 1;for (int j = 2; j < i; j++) {if (i % j == 0) {isPrime = 0;break;}}if (isPrime == 1) {cnt ++;printf("\t%d", i);if (cnt % 5 == 0) {printf("\n");}}}printf("\n共有%d个素数。\n", cnt);

确定范围内的素数统计并求和——

int m, n;scanf("%d %d", &m, &n);if (m == 1) {m = 2;}int cnt = 0, sum = 0;for (int i = m; i <= n; i ++) {int isPrime = 1;for (int j = 2; j < i; j ++) {if (i % j == 0) {isPrime = 0;break;}}if (isPrime) {cnt ++;sum += i;}}printf("%d %d", cnt, sum);

2.4. 关于continue、break 和 return

循环控制语句,不支持在分支语句中单独用,除了switch中的break。

continue:跳过本次循环后面的执行语句,进入本个循环的下一轮(你别干了,下一个)

break:跳出一个循环,到循环外了(都别干了)。

(跳出多重循环的方法:循环结尾 if(exit == 1) break;接力break。除此外还可以使用goto语句)

return是表示从被调函数返回主调用处继续执行,可以附带一个返回值,用来结束函数。返回值类型必须与所在函数类型一致,如在void函数中只可写return ; 而在int型函数中return必须跟上一个整数型返回值。int型返回0表示正常退出,错误时可以是1、-1等表示异常终止;指针型返回相应的地址,错误时返回NULL。返回位置是调用处的下一条语句处。

【main函数返回一个浮点数会取整、返回字符型value值ascii码、不能不写返回值。】

3. goto语句介绍

可以直接进行代码间的跳转,接近于汇编语言,拥有极高的效率(比switch效率更高)。

使用方式:在代码中某处预先写一个锚点(标记label或其它易识别的符号)如 label: 表达式; ,在需要跳转到此处时的另一个位置处写 “goto label;” 即可。goto和标签必须处于同一个函数内,是函数内无条件跳转而不可跨函数。标签的作用域在函数内部,可以在goto之前或之后,不遵循先定义再使用。

参考 mooc翁恺 和 B站up考鼎录的讲解:

经常使用的场景:

(1)跳出多重循环。

(2)异常处理:函数出错时goto fail进行统一释放分配的内存( if 判断需要释放哪些)。一般C程序中常见goto failed、goto error、goto done。

与goto语句异曲同工的用法:

do {

if(ccc)break;

}while (0);

但是存在争议是如果这个循环体很长可读性下降,另外它增加了缩进级数。

C语言学习笔记07-1-语句结构:选择/循环(附三元运算符;DevC可以for定义临时变量的设置;continue break return;goto语句简单说明)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。