)
目录1. if语句1.1 if1.2 else1.3分支中包含多条语句1.4 嵌套 if1.5 悬空 else 问题2. 关系操作符3.条件操作符4.逻辑操作符||4.1逻辑取反运算符4.2 逻辑与运算符4.3 逻辑或运算符4.5 短路5. switch语句5.1 if语句和switch的对比5.2 switch语句中的break5.3 switch语句中的default5.4 switch语句中的case和default的顺序问题6.while循环6.1 if和while的对比6.2while语句的执行流程6.3while循环的实践6.4 练习7.for循环7.1语法形式7.2 for循环的执行流程7.3 for循环的实践7.4while循环和for循环的对比7.5 练习8.do-while循环8.1语句形式8.2 do while循环的执行流程8.3do while循环的实例8.4练习9.break 和continue语句9.1while循环中break和continue9.1.1break举例9.1.2continue举例9.2for循环中的break和continue9.2.1break举例9.2.2 continue 举例9.3do while循环中的break和continue10.循环的嵌套10.1练习11.goto语句1. if语句1.1 ifif语句的语法形式如下if(表达式) 语句表达式成立为真则语句执行表达式不成立为假则语句不执行。在C语言中0为假非0为真也就是表达式的结果如果是0则语句不执行表达式的结果不是0则语句执行。例子输入一个整数判断是否为奇数#includestdio.h int main() { int num 0; //输入 scanf(%d, num); //判断 if (num % 2 1) printf(奇数\n, num); else printf(偶数\n, num); return 0; }1.2 else如果一个数不是奇数那就是偶数了如果任意一个整数我们要怎么清楚的判断是奇数还是偶数那就要使用if...else语句了该语法形式如下if (表达式) 语句1 else 语句2例子输入一个整数判断是否为奇数如果是奇数打印奇数否则打印偶数。#includestdio.h int main() { int num 0; scanf(%d, num); if (num % 2 0) printf(%d是偶数\n, num); else printf(%d是奇数\n, num); return 0; }练习输入一个年龄18岁就输出成年否则就输出未成年#includestdio.h int main() { int age 0; scanf(%d, age); if (age 18) printf(%成年了\n); else printf(未成年\n); return 0; }1.3分支中包含多条语句默认在 if 和 else 语句中默认都只控制一条语句比如上面的代码你会发现输入的值不管是18,还还是18“可以谈恋爱”都会打印在屏幕上。这是因为 if 语句只能控制一条语句就是printf(成年了\n)if 语句为真则打印成年了if 语句为假则不打印对于 printf“可以谈恋爱了\n”是独立存在的不管 if 语句的条件的真假都会被执行。那如果我们要 if 语句同时控制2条语句那就要使用 { } 将代码扩起来else 后也可以跟上大扩号即保证正确性也美观。如果输入小于18的数if 语句就为假什么都不会被打印。那就需要加上else。1.4 嵌套 if在 if else 语句中else可以与另一个 if 语句连用构成多重判断。比如要求输入一个整数判断输入的整数是0还是正数或者负数。如下所示。#includestdio.h int main() { int num 0; scanf(%d, num); if (num 0) printf(%d是正数\n, num); else if(num 0) printf(%d是负数\n, num); else printf(%d是零\n, num); return 0; }也可以不使用else if 如下所示。#includestdio.h int main() { int num 0; scanf(%d, num); if (num ! 0) { if (num 0) { printf(%d是正数\n,num); } else { printf(%d是负数\n,num); } } else { printf(%d是零\n,num); } return 0; }以上就是嵌套 if 语句的语法有了嵌套 if 语句就可以完成更多复杂逻辑的判断。练习输入一个人的年龄如果年龄18岁打印少年如果年龄在18岁至44岁打印“青年”如果年龄在45岁至59岁打印“中老年”如果年龄在60岁至89岁打印“老年”如果90岁以上打印“老寿星”代码如下#includestdio.h int main() { int age 0; scanf(%d, age); if (age 18) printf(少年\n); else if (age 44) printf(青年\n); else if (age 59) printf(中老年\n); else if (age 89) printf(老年\n); else printf(老寿星\n); return 0; }1.5 悬空 else 问题如果有多个 if 和else可以记住这样一条规则else 总是跟最接近的 if 匹配。#includestdio.h int main() { int a 0; int b 2; if (a 1) if (b 2) printf(hehe\n); else printf(haha\n); return 0; }这个程序运行的结果是什么我们刚刚接触这个语言的时候认为输入个0不等于1那就执行else子句打印haha。但是当运行代码时输出的结果是空。为什么呢这就是悬空else的问题如果有多个 if 和 else 可以记住这样一条规则else 总是跟最接近的 if 匹配。上面的代码排版让 else 和第一 if 语句对齐让我们以为 else 是和第一个 if 匹配的当 if 语句不成立的时候自然想到的就是执行 else 字句打印 haha 但实际 else 是和第二个 if 进行匹配的这样后边的 if...else语句是嵌套在第一个 if 语句中的如果第一个 if 语句不成立嵌套 if 和 else 就没机会执行了最终啥都不打印。就是说我们开始的时候让 a 0 进入条件判断 if(a 1)但是它没有else所以不符合条件所以什么都没有打印除非设置 int a 1它才会进入到内部的 if...else 语句。换成以下代码就更加容易理解了。#includestdio.h int main() { int a 0; int b 2; if (a 1) { if (b 2) printf(hehe\n); else printf(haha\n); } return 0; }或者如果我们希望else确实和第一个 if 匹配可以这样编写#includestdio.h int main() { int a 0; int b 2; if (a 1) { if (b 2) printf(hehe\n); } else { printf(haha\n); } return 0; }只要带上适当的大括号代码的逻辑就会更加的清晰所以以后在写代码的时候要注意括号的使用让代码的可读性更高。2. 关系操作符C语言用于比较的表达式称为“关系表达式”里面使用的运算符就称为“关系运算符”主要有下面6个。 大于运算符 小于运算符 大于等于运算符 相等运算符不相等运算符下面是一些例子。a b; a ! b; a b; a b; a b; a b;关系表达式通常返回 0 或 1表示真假。C语言中0 表示为假所有非零值表示为真。比如2012返回11220返回0。关系表达式常用 if 或者 while 结构。if (x 3) { printf(x is 3.\n); }注意相等运算符与赋值运算符是两个不一样的运算符不要混淆。有时候可能会不小心写出下面的代码他可以运行但很容易出现意料之外的结果。if (x 3)...上面示例中原意式x 3但是不小心写成x 3 。这个式子表示对变量x 赋值 3 它的返回值为3所以 if 判断总是为真。为了防止出现这种错误有的程序员喜欢将变量写在等号的右边。if (3 x)这样的话如果把 误写成 编译器就会报错。如果没写错就会打印输出。另一个需要避免的错误是多个关系运算符不宜连用。i j k上面示例中连续使用两个小于运算符。这是合法表达式不会报错但是通常达不到想要的结果即不是保证变量 j 的值在 i 和 k 之间。因为关系运算符是从左到有计算所以实际执行的是下面的表达式。(i j) k上面式子中i j 返回0或1所以最终是0或1与变量 k 进行比较。如果想要判断变量 j 的值是否在 i 和 k 之间应该使用下面的写法。i j j k比如我们输入一个年龄如果年龄在18~36岁之间我们输出青年。如果我们这样写额当我们输入10的时候依然输出青年如下图这是因为我们先拿18和age中存放的10比较表达式1810为假18age的结果是0再拿0和36比较036为真所以打印了青年因此即使当age是10的时候也能打印青年逻辑上是有问题正确代码如下#includestdio.h int main() { int age 0; scanf(%d, age); if (18 age age 36) { printf(青年\n); } return 0; }3.条件操作符条件操作符也叫三目操作符需要接受三个操作数的形成如下exp1exp2exp3 真 执行 不执行 假 不执行 执行条件操作符的计算逻辑是如果exp1为真exp2计算计算的结果是整个表达式的结果如果exp1为假exp3计算计算的结果是整个表达式的结果。练习1使用条件操作符表示下面代码的逻辑#includestdio.h int main() { int a 0; int b 0; scanf(%d, a); if (a 5) b 3; else b -3; printf(%d, b); return 0; }改造后#includestdio.h int main() { int a 0; int b 0; scanf(%d, a); b (a 5 ? 3 : -3); printf(%d, b); return 0; }练习2使用条件表达式实现找两个数中较大值。#includestdio.h int main() { int a 0; int b 0; scanf(%d %d, a, b); int m (a b ? a : b); printf(%d, m); return 0; }4.逻辑操作符||逻辑运算符提供逻辑判断功能用于构建更复杂的表达式主要有下面三个运算符。逻辑取反运算符改变单个表达式的真假。逻辑与运算符就是并且的意思两侧的表达式都为真则为真否则为假。||逻辑或运算符就是或者的意思两侧至少有一个表达式为真则为真否则为假。注C语言中非表示真0表示假4.1逻辑取反运算符比如我们有一个变量叫flag如果flag为假要做一个什么事情就可以这样写代码#includestdio.h int main() { int flag 0; if (!flag) { printf(do something\n); } return 0; }如果flag为真flag就是假如果flag为假flag就是真。所以上面的代码的意思就是本来flag为假flag 0但是flag 进行取反之后为真执行if语句中的代码。4.2 逻辑与运算符就是与运算符也是并且的意思是一个双目操作符使用方式是ab两边的表达是都是真的时候整个表达式才为真只要有一个是假则整个表达式为假。比如如果我们说月份是3月到5月是春天代码如下#includestdio.h int main() { int month 0; scanf(%d, month); if (month 3 month 5) { printf(春天\n); } return 0; }这里表达的意思就是month既要大于等于3又要小于等于5必须同时满足。4.3 逻辑或运算符||就是或运算符也就是或者的意思||也就是一个双目操作符使用的方式是a || b||两边的表达式只要有一个是真整个表达式就是真两边的表达式都为假的时候才为假。比如我们说一年中月份是12月或者1月或者2月是冬天代码如下#includestdio.h int main() { int month 0; scanf(%d, month); if (month 12 || month 1 || month 2) { printf(冬天\n); } return 0; }4.4 练习闰年的判断输入一个年份year判断year是否是闰年闰年判断的规则1.能被4整除并且不能被100整除是闰年2.能被400整除是闰年#includestdio.h int main() { int year 0; scanf(%d, year); if ((year % 4 0 year % 100 ! 0)||(year % 400 0)) { printf(闰年\n); } else { printf(不是闰年\n); } return 0; }4.5 短路C语言逻辑运算符还有一个特点它总是先对左侧的表达式求值再对右边的表达式求值这个顺序是保证的。如果左边的表达式满足逻辑运算符的条件就不再对右边的表达式求值。这种情况称为“短路”。如前面的代码if(month 3 month 5)表达式中的左操作数是month3操作数是month5当左操作数month 3的结果是0的时候即使不判断month5整个表达式的结果也是0不是春季。所以对于操作符来说左边操作数的结果是0的时候右边操作数就不再执行。if (month 12 || month 1 || month 2)对于||操作符如果month 12 则不用再判断month是否等于1或者2整个表达式的结果也是1(冬季)。所以||操作符的左操作数的结果不为0时就无需执行右操作数。像这种仅仅根据左操作数的结果就能知道整个表达式的结果不再对右操作数进行计算的运算称为短路求值。练习阅读代码计算代码输出的结果int main() { int i 0, a 0, b 2, c 3, d 4; i (a b d); printf(a %d\nb %d\nc %d\nd %d\n, a, b, c, d); return 0; } int main() { int i 0, a 1, b 2, c 3, d 4; i (a || b || d); printf(a %d\nb %d\nc %d\nd %d\n, a, b, c, d); return 0; }5. switch语句除了if语句外C语言还提供了switch语句来实行分支结构。switch语句是一种特殊形式的if...else结构用于判断条件有多个结果的情况。它把多重的else if改为更易用、可读性更好的形式。switch(expression) { case value1:statement case value2:statement ... default:statement }上面代码中根据表达式expression不同的值执行相应的case分支。如果找不到对应的值就执行default分支。switch后的expression必须是整型表达式case后的值必须是整形常量表达式5.1 if语句和switch的对比练习输入任意一个整数值计算除3之后的余数如果使用if 语句完成如下#includestdio.h int main() { int num 0; scanf(%d, num); if (num % 3 0) printf(余数为0\n); else if (num % 3 1) printf(余数为1\n); else printf(余数为2\n); return 0; }如果使用switch语句改写就可以是这样#includestdio.h int main() { int num 0; scanf(%d, num); switch (num % 3) { case 0: printf(余数为0\n); break; case 1: printf(余数为1\n); break; case 2: printf(余数为2\n); break; } return 0; }上述的代码中我们要注意的点有1case和后边的数字之间必须有空格2每一个case 语句中的代码执行完成后需要加上break才能跳出这个 switch 语句。5.2 switch语句中的break前面的代码中如果我们去掉case语句中的break会出现什么情况呢我们发现7除以3本来余数是1但是我们发现程序运行的结果多了一行“余数是2”的打印。原因是switch语句也是分支效果的只有在switch语句中使用break才能在跳出switch语句如果某一个case语句的后面没有break语句代码会继续往下执行有可能执行其他case语句中代码直到遇到break语句或者switch语句结束。就比如上面的代码就执行了case2中的语句。所以在switch语句中break语句是非常重要的能实现真正的分支效果。当然break也不是每个case语句都得有这就得根据实际情况来看了。练习输入一个1~7的数字打印对应的星期几例如输入1 输出星期一输入2 输出星期二输入3 输出星期三输入4 输出星期四输入5 输出星期五输入6 输出星期六输入0 输出星期七#includestdio.h int main() { int num 0; scanf(%d, num); switch (num % 7) { case 1: printf(星期一\n); break; case 2: printf(星期二\n); break; case 3: printf(星期三\n); break; case 4: printf(星期四\n); break; case 5: printf(星期五\n); break; case 6: printf(星期六\n); break; case 0: printf(星期日\n); break; } return 0; }如果需求发生变化变为1.输入1~5输出的是“工作日”2.输入6~7输出“休息日”那参考代码如下#includestdio.h int main() { int num 0; scanf(%d, num); switch (num % 7) { case 1: case 2: case 3: case 4: case 5: printf(工作日\n); break; case 6: case 0: printf(休息日\n); break; } return 0; }上面的练习中可以发现应该根据实际的情况来在代码中觉得是否使用break或者在哪里使用break才能正确完成实际的需求。5.3 switch语句中的default在使用switch语句的时候我们经常可能遇到一种情况比如switch后的表达式中的值无法匹配代码中的case语句的时候这时候要不就不做处理要不就得在switch语句中加入default子句。switch(expression) { case value1: statement case value2: statement default: statement }switch后面的expression的结果不是value1也不是value2的时候就会执行default子句。就比如前面做的打印星期的练习如果day的输入不是1~7的值如果我们要提示输入错误则可以这样完成代码#includestdio.h int main() { int num 0; scanf(%d, num); switch (num % 7) { case 1: case 2: case 3: case 4: case 5: printf(工作日\n); break; case 6: case 0: printf(休息日\n); break; default: printf(输入错误\n); } return 0; }5.4 switch语句中的case和default的顺序问题在switch语句中case子句和default子句有要求顺序吗default只能放在最后吗其实在switch语句中case和default语句是没有顺序要求的只要你的顺序是满足实际需求的就可以。不过我们通常把default子句放在最后处理的。6.while循环C语言提供了3种循环语句while就是其中一种接下来就介绍一下while语句。while语句的语法结构和if语句非常相似。6.1 if和while的对比if表达式 语句 while表达式 语句//如果循环体想包含更多的语句可以加上大括号以下代码进行对比#includestdio.h int main() { if (1) printf(hehe\n);//if后边条件满足打印一次hehe return 0; } #includestdio.h int main() { while (1) printf(hehe\n);//while后边条件满足无限打印hehe return 0; }这就是他们的区别while语句是可以实现循环效果的。6.2while语句的执行流程首先上来就是执行判断表达式表达式的值为0循环直接结束表达式的值不为0则执行循环语句语句执行完后再继续判断是否进行下一次判断。6.3while循环的实践练习在屏幕上打印1~10的值参考代码#includestdio.h int main() { int num 1; while (num 10) { printf(%d\n, num); num; } return 0; }6.4 练习输入一个正的整数逆序打印这个整数的每一位例如输入1234输出4321输入521输出125题目解析1.想要得到n的最低位可以使用n%10的运算得到的余数就是最低位如1234%10得到42.要想去掉n的最低位找出倒数第二位则使用nn/10操作可以去掉最低位的如n1234/10得到123123相较于1234就去掉了最低位123%10就得到倒数第二位3。3.循环1和2两个步骤在n变成0之前就能到所有的位。#includestdio.h int main() { int num 0; scanf(%d, num); while (num ) { printf(%d , num % 10); num / 10; } return 0; }7.for循环7.1语法形式for循环式三种循环中使用最多的for循环的语法形式如下for表达式1表达式2表达式3 语句//如果循环体想包含更多的语句可以加上大括号表达式1用于循环变量的初始化表达式2用于循环结束条件的判断表达式3用于循环变量的调整7.2 for循环的执行流程首先执行表达式1初始化循环变量接下来就是执行表达式2的判断部分表达式2的结果如果0则循环结束表达式2的结果如果0则执行循环语句循环语句执行完后再去执行表达式3调整循环变量然后再去表达式2的地方执行判断表达式2的结果是否为0决定循环是否继续。整个循环的过程中表达式1初始部分只被执行1次剩下的就是表达式2、循环语句、表达式3在循环。7.3 for循环的实践练习在屏幕上打印1~10的值#includestdio.h int main() { int i 0; for(i1; i10; i) { printf(%d ,i); } return 0; }7.4while循环和for循环的对比for和while在实现循环的过程中都有初始化、判断、调整这三个部分但是for循环的三个部分非常集中便于代码的维护而如果代码较多的时候while循环的三个部分就比较分散所以从形式上for循环更优一些。7.5 练习练习1计算1~100之间3的倍数的数字之和#includestdio.h int main() { int i 0; int sum 0; for(i1; i100; i) { if (i % 3 0) sum sum i; } printf(%d ,sum); return 0; }对于这个代码还有优化空间如下#includestdio.h int main() { int i 0; int sum 0; for(i3; i100; i3) { sum sum i; } printf(%d ,sum); return 0; }8.do-while循环8.1语句形式在循环语句中do-while语句的使用最少它的语法如下do 语句 while表达式while 和 for 这两种循环都是先判断条件如果满足就进入循环执行循环语句如果不满足就跳出循环而do while循环则是先直接进入循环体执行循环语句然后再执行while后的判断表达式表达式为真就会进行下一次表达式为假则不再继续循环。8.2 do while循环的执行流程在do while循环中先执行图上的“语句”执行完语句在去执行“判断表达式”判断表达式的结果是0则继续循环执行循环语句判断表达式的结果0则循环结束。所以在do while语句中循环体是至少执行一次的这是do while循环比较特殊的地方。8.3do while循环的实例在屏幕上打印1~10的值#includestdio.h int main() { int i 1; do { printf(%d , i); i; } while (i 10); return 0; }一般 do while使用在循环体至少被执行一次的场景下所以较少一些。8.4练习输入一个正整数计算这个整数是几位数例如输入1234 输出4输入12 输出2#includestdio.h int main() { int i 0; int j 0; scanf(%d, i); do { j; i i / 10; } while (i); printf(%d, j); return 0; }这里并非必须使用do while语句但是这个代码就比较适合实用do while 循环因为n即使是0也是1位数要统计位数的。9.break 和continue语句在循环执行的过程中如果某些状况发生的时候需要提前终止循环这是非常常见的现象。C语言中提供了break和continue两个关键词就是应用到循环中的。break的作用是用于永久的终止循环只要break被执行直接就会跳出现循环继续往后执行。continue的作用是跳过本次循环中continue后边的代码在for循环和while循环中有所差异的。9.1while循环中break和continue9.1.1break举例#includestdio.h int main() { int i 1; while (i 10) { if (i 5) break;//当i等于5后就执行break循环就终i 止了 printf(%d, i); i i 1; } return 0; }执行的结果打印1234后当i等于5的时候循环break的地方终止不再打印不再循环。所以break的作用就是永久的终止循环只要break被执行break外的第一层循环就终止了。那以后我们在循环中想要在某种条件下终止循环则可以使用break来完成我们想要的效果。9.1.2continue举例continue是继续的意思在循环中的作用就是跳过本次循环中continue后边的代码继续进行下一次循环的判断。将上面的代码换成continue#includestdio.h int main() { int i 1; while (i 10) { if (i 5) continue; //当i等于5后就执行continue直接跳过continue的代码去循环判断的地方 //因为这里跳过了i i 1所以i一直为5程序陷入死循环 printf(%d, i); i i 1; } return 0; }到这里我们就能分析出来continue可以帮助我们跳出某一次continue后边的代码直接到循环的判断部分进行下一次循环的判断如果循环的调整是在continue后边的话可能会造成死循环。9.2for循环中的break和continue9.2.1break举例其实和while循环中的break一样for循环中的break也是用于终止循环的不管循环还需要循环多少次只要执行到了break循环就彻底终止。break的作用是永久的终止循环我们在某个条件发生的时候不想再继续循环的时候就可以使用break来完成。9.2.2 continue 举例上面的代码把break换成continue#includestdio.h int main() { int i 1; for(i 1; i 10; i) { if (i 5) continue;//这里continue跳过了后边的打印来到了i的调整部分 printf(%d , i); } return 0; }所以在for循环中continue的作用是跳过本次循环中continue后的代码直接去到循环的调整部分。未来当某个条件发生的时候本次循环无需再执行后续某些操作的时候就可以使用continue来实现。这里我们可以对比一下while循环和for循环中continue的区别9.3do while循环中的break和continuedo while语句中的break和continue的作用和while循环中几乎一摸一样。10.循环的嵌套10.1练习找出100~200之间的素数并打印在屏幕上。注素数又称质数只能被1和本身整除的数字。要从100~200之间找出素数首先得有100~200之间的数这里使用循环解决。假设要判断i是否为素数需要产生2~i-1之间的数字也可以使用循环解决。如果2~i-1之间有数字能整除i则i不是素数如果都不能整除则i是素数。#includestdio.h int main() { int i 0; for (i 100; i 200; i) { int j 0; for (j 2; j i; j) { if (i % j 0) break; } if (i j) printf(%d , i); } return 0; }11.goto语句C语言提供了一种非常特别的语法就是goto语句和跳转标号goto语句可以实现在同一个函数内跳转到设置好的标号处。例如#includestdio.h int main() { printf(hehe\n); goto next; printf(haha\n); next: printf(跳过了haha的打印\n); return 0; }goto语句如果使用不当就会导致在函数内部随意跳转打乱程序的执行流程所以我们的建议是能不用尽量不去使用但是goto语句也不是一无是处在多层循环的代码中如果想快速跳出使用goto就非常的方便。for (...) { for (...) { for (...) { if (disaster) goto error; } } } error: //...本来for循环想提前退出得使用break一个break只能跳出一层for循环如果3层循环嵌套就得使用3个break才能跳出循环所以在这种情况下我们使用goto语句就会更加的快捷。小结本篇博客主要记录了 C 语言学习过程中的一些基础知识点包括 if 语句、switch 语句、关系与逻辑操作符以及 while、for、do-while 循环等内容。同时结合实例代码对常见语法、执行流程以及容易出现的问题进行了整理和总结。由于本人也是 C 语言学习阶段文章难免存在理解不到位或表述不准确的地方欢迎大家批评指正。如果文章中存在错误还请多多包涵也希望能和大家一起交流学习共同进步。相关代码已上传至 Giteehttps://gitee.com/ZhiWeiCoder/student_c。大家也可以关注一下我这个代码库谢谢。