2.分支和循环语句
2.1 分支语句
C语言把任何非零和非空的值假定为 true,把零或 null 假定为 false
2.1.1 if else
-
if语句
if(boolean_expression) { /* 如果布尔表达式为真将执行的语句 */ }
-
if...else...
if(boolean_expression) { /* 如果布尔表达式为真将执行的语句 */ } else { /* 如果布尔表达式为假将执行的语句 */ }
-
if...else if...else...
- 一个if后可跟一个或零个else语句,else必须在所有else if之后
- 一个if后可跟多个或零个else if语句,else if必须在else之前
- 一旦某个else if匹配成功,其他的else if或else将不会被测试
if(boolean_expression1) { /* 当布尔表达式1为真时执行 */ } else if(boolean_expression2) { /* 当布尔表达式2为真时执行 */ } else if(boolean_expression3) { /*当布尔表达式3为真时执行*/ } else { /* 当上面条件都不为真时执行 */ }
-
嵌套if语句
if( boolean_expression1) { /* 当布尔表达式1为真时执行 */ if(boolean_expression2) { /* 当布尔表达式2为真时执行 */ } } // 可以在一个if...else...或if...else if...else..语句中 // 嵌套一个if...else...或if...else if...else..语句
2.1.2 switch
-
switch
switch(expression){ case constant-expression : statement(s); break; /* 可选 */ case constant-expression : statement(s); break; /* 可选 */ default : /* 可选 */ statement(s); }
- expression为常量表达式,必须是一个整形或枚举类型
- constant-expression必须和expression的数据类型相同,且为一个常量或字面量
- 当被测试的变量等于case中的常量时,case后面的语句执行,直到遇到break语句
- default case中的break语句不是必须的
- default语句可以放在任意位置
-
嵌套switch
一个switch语句种包含另一个switch语句
switch(expression1) { case constant-expression: switch(expression2) { case constant-expression: ... break; case constant-expression: ... } break; case constant-expression: ... }
2.1.3 :?运算符(三目运算符)
Exp1 ? Exp2 : Exp3;
// ? 表达式的值是由 Exp1 决定的。
// 如果 Exp1 为真,则计算 Exp2 的值,结果即为整个表达式的值
// 如果 Exp1 为假,则计算 Exp3 的值,结果即为整个表达式的值
2.2 循环语句
2.2.1 for
for ( init; condition; increment )
{
statement(s);
}
// init: 首先执行,声明并初始化循环控制变量,可留空
// condition: 判断,如果为真,执行statement(s),否则结束循环
// increment: 执行完for循环主体statement(s);之后,执行increment语句。该语句一般是更新循环控制变量,可留空
2.2.2 while
while(condition)
{
statement(s); // 一条语句或语句块
}
2.2.3 do while
for和while循环在循环开始时测试循环条件,而do...while...在每次循环中执行statement(s)语句之后,测试循环条件。
do
{
statement(s);
}while( condition )
// statement(s);至少被执行一次
2.2.4 嵌套循环
-
嵌套for循环
for (initialization; condition; increment/decrement) { statement(s); for (initialization; condition; increment/decrement) { statement(s); } }
-
嵌套while循环
while (condition1) { statement(s); while (condition2) { statement(s); } }
-
嵌套 do while 循环
do { statement(s); do { statement(s); }while (condition2); }while (condition1)
-
混合嵌套
2.3 循环控制语句
2.3.1 break
终止循环或switch语句。在嵌套语句中,终止break所在的最内层的循环或switch语句。
2.3.2 continue
结束本次循环,进行下一次迭代。
2.3.3 goto
控制转移到被标记的语句。但是不建议在程序中使用goto语句(使得程序的控制流难以跟踪,使程序难以理解和难以修改)。
goto label;
...
...
label: statement;
// goto语句只能在一个函数范围内跳转,不能跨函数
// 一般不使用,跳出多层嵌套时使用
2.4 无限循环
for( ; ; )
{
...
}
// 倾向于使用该语句实现无限循环
2.3 习题
2.3.1 最大公约数
最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个。
-
一般方法
int main() { int a = 12; int b = 16; int max = a; // 为a、b中较小的一个赋值给最大公约数 if (max > b) { max = b; } for (; max >= 1 ; max--) { if (a % max == 0 && b % max == 0) { printf("%d\n", max); break; } } return 0; }
-
辗转相除法
欧几里得算法:gcd(a, b) = gcd(b, a mod b)
int main() { int a = 12; int b = 16; int t = 0; while (t = a % b) { a = b; b = t; } printf("%d", b); return 0; }
2.3.2 最小公倍数
两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。
-
一般方法
int main() { int a = 12; int b = 16; int min = a; // 存放a、b中较大值 if (min<b) { min = b; } for ( ; ; min++) { if (min % a == 0 && min % b == 0) { printf("%d", min); break; } } return 0; }
-
公式法
最小公倍数 × 最大公约数 = a × b
int main() { int a = 12; int b = 16; int mul = a * b; // a和b的乘积 int t = 0; while (t = a % b) { a = b; b = t; } printf("%d", mul / b); return 0; }
2.3.3 排序
问题描述:给定三个数,从大到小输出
int main()
{
int a = 3;
int b = 8;
int c = 5;
if (a < b)
{
int t = a;
a = b;
b = t;
}
if (a < c)
{
int t = a;
a = c;
c = t;
}
if (b < c)
{
int t = b;
b = c;
c = t;
}
printf("%d %d %d", a, b, c);
return 0;
}
2.3.4 闰年
闰年(Leap Year)是为了弥补因人为历法规定造成的年度天数与地球实际公转周期的时间差而设立的。补上时间差的年份为闰年。闰年共有366天(1月~12月分别为31天、29天、31天、30天、31天、30天、31天、31天、30天、31天、30天、31天)。
-
规则:四年一闰,百年不闰,四百年再闰。
-
方法一:
int main() { int sum = 0; for (int i = 0; i <= 2050; i++) { if ( 0 == i % 4) { if (0 == i % 100) { if (0 == i % 400) { printf("%d\n", i); } } else { printf("%d\n", i); } } } return 0; }
-
方法二:
int main() { int sum = 0; for (int i = 0; i <= 2050; i++) { if ((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0 )) { printf("%d是闰年\n", i); sum++; } } printf("sum = %d\n", sum); }
2.3.5 素数(质数)
在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
int main()
{
for (int i = 2; i <= 100; i++)
{
int j = i - 1;
for ( ; j>=1; j-- )
{
if (0 == i % j)
{
break;
}
}
if (j == 1)
{
printf("%d\n", i);
}
}
}
-
优化:
int main() { for (int i = 2; i <= 100; i++) { int flag = 1; // flag=1时为素数 int j = 2; for ( ; j*j <= i ; j++) { if (0 == i % j) { flag = 0; // flag为0时不为素数 break; } } if (flag) { printf("%d\n", i); } } }
2.3.6 goto使用
# Windows关机命令
shutdown -s -t 60 # 设置关机
shutdown -a # 取消关机
// C语言中使用system("")执行系统命令
// system()函数在<stdlib.h>头文件中
// C语言中两个字符串不能使用`==`比较大小
// 可使用strcmp(str1, str2)函数
// 字符串相等函数返回0,该函数在<string.h>头文件中
#include <stdlib.h>
#include <string.h>
int main()
{
char input[20] = { 0 };
Lable:
system("shutdown -s -t 60");
printf("电脑将在1min之后关机,请输入密码进行取消:");
scanf("%s", input);
if (0 == strcmp(input, "123"))
{
system("shutdown -a");
}
else {
goto Lable;
}
return 0;
}
- 小问题
#define _CRT_SECURE_NO_WARNINGS // 源文件第一行(忽略VS的安全检测)