前言
C语言是结构化的程序设计语言,实际上不仅是C语言, 我们生活中万事万物都可以拆分成三种结构: 顺序结构, 选择结构, 循环结构。
C语言一共有九种控制语句,其中我们可以使用分支语句if语句、switch语句实现分支结构,使用for语句、while语句、do-while语句实现循环结构。此外还有四种转向语句: break语句、goto语句、continue语句、return语句。
一. 分支语句
1.1 if语句
1.1.1 if
if语句的语法形式如下:
if ( 表达式)
语句; // 如果表达式结果为真, 则语句执行.
C语言中,0为假,非0为真,表达式的结果成立(为真)结果就非0,则语句执行,表达式结果不成立(为假)结果为0,则语句不执行。
例子:输入一个整数,判断是否为奇数
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if (num % 2 == 1)
printf("%d 是奇数\n", num); //输入的是奇数,表达式为真,打印内容
//输入的不是奇数,不打印
return 0;
}
1.1.2 else
if else语法形式如下:
if ( 表达式 )
语句1;
else
语句2;
例子1:输入一个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印是偶数。
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if (num % 2 == 1)
printf("%d 是奇数\n", num);
else
printf("%d 是偶数\n", num);//一个整数不是奇数就是偶数
//所以一个分支就可以包含全部可能
return 0;
}
例子2:输入一个年龄,>=18岁就输出:成年,否则就输出:未成年
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
printf("成年\n");
else
printf("未成年\n");
return 0;
}
分支中包含多条语句:
#include <stdio.h> int main() { int age = 0; scanf("%d", &age); if (age >= 18) printf("成年了\n"); printf("可以打游戏了\n"); return 0; }
上面的代码,不论输出的是>=18 还是<18,"可以打游戏了"都会打印在屏幕上。**因为if语句只能控制一条语句,就是
printf("成年了\n");
,而printf("可以打游戏了\n");
是独立存在的,不受if语句控制。如果要让if语句同时控制两条或多条语句,需要使用{}
将需要控制的代码括起来,else同理。如下:#include <stdio.h> int main() { int age = 0; scanf("%d", &age); if (age >= 18) { printf("成年了\n"); printf("可以打游戏了\n"); } return 0; }
1.1.3 嵌套if
语法形式如下:
if ( 表达式1 )
语句1;
else if ( 表达式2 )
语句2;
else
语句3;
if ( 表达式1 )
{
if ( 表达式2 )
语句1;
else
语句2;
}
else
语句3;
if else语句中else与另一个if语句连用,构成多重判断。
例子1:要求输入一个整数,判断输入的整数是0,还是正数或者负数。
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if (num == 0)
printf("输入的数字是零\n");
else if (num > 0) //这里的if相当于嵌套在else语句中形成嵌套结构
printf("输入的数字是正数\n");
else
printf("输入的数字是负数\n");
return 0;
}
例子2:输入一个整数,如果是正数,再判断是奇数还是偶数,并输出;如果不是正数则输出:非正数。
#include <stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
if (num > 0)
{
if (num % 2 == 0)
printf("偶数\n");
else
printf("奇数\n"); //if else语句嵌套在if语句中
}
else
printf("非正数\n");
return 0;
}
1.1.4 悬空else
我们给出一下代码
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
if (a == 1)
if (b == 2)
printf("hehe\n");
else
printf("haha\n"); //else会跟最接近的if匹配
return 0;
}
因为else总是跟最接近的if匹配,所以在第一个if语句不成立后,else与它匹配的if因为嵌套在第一个语句下,无法执行,最终不打印,代码运行后的结果如下
如果要让else与第一个if匹配,可以这样修改代码
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
if (a == 1)
{
if (b == 2)
printf("hehe\n");
}
else
{
printf("haha\n");
}
return 0;
}
1.2 操作符
1.2.1 关系操作符
C语言用于比较的表达式,称为“关系表达式”,里面使用的运算符就称为“关系运算符”。
主要有下面六个:
- > 大于运算符
- < 小于运算符
- >= 大于等于运算符
- <= 小于等于运算符
- == 相等运算符
- != 不相等运算符
关系表达式通常返回0或1,表示真假。
注意:
- 相等运算符
==
与赋值运算符=
,是两个不一样的运算符。- 多个关系运算符不宜连用
例如:(i < j) < k
中(i < j)
返回0或1,所以最终是0或1与变量k进行比较。
1.2.2 条件操作符
条件操作符也叫三目操作符,形式如下:
exp1 ? exp2 : exp3
其计算逻辑是:如果exp1为真,exp2计算;如果exp1为假,exp3计算。
计算结果均是整个表达式的结果
例子:
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
if (a > 5)
b = 3;
else
b = -3;
printf("%d\n", b);
return 0;
}
改造后
#include <stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
b = (a > 5 ? 3 : -3);
printf("%d\n", b);
return 0;
}
1.2.3 逻辑操作符(与或非)
逻辑运算符提供逻辑判断功能,主要有以下三个运算符:
&&
:逻辑与运算符(两侧的表达式都为真,则为真,否则为假)||
:逻辑或运算符(两侧的表达式至少有一个为真,则为真,否则为假)!
:逻辑取反运算符(改变单个表达式的真假)
例子1:有一个变量flag,若flag为假,则要做一个什么事情
#include <stdio.h>
int main()
{
int flag = 0;
if (!flag)
printf("do something\n");
return 0;
}
例子2:输入一个整数,代表月份,如果是3月到5月,输出春季
#include <stdio.h>
int main()
{
int month = 0;
scanf("%d", &month);
if (month >= 3 && month <= 5)
printf("春季\n");
return 0;
}
例子3:输入一个整数,代表月份,如果是12月到1月,输出冬季
#include <stdio.h>
int main()
{
int month = 0;
scanf("%d", &month);
if (month == 12||month == 1||month == 2)
printf("冬季\n");
return 0;
}
短路:C语言的逻辑运算符,总是先对左侧的表达式求值,在对右边的表达式求值。如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”
1.3 switch语句
switch语句的语法形式如下:
switch (expression) //表达式expression为整形表达式
{
case value1:statement //value的值是整型常量表达式
case value2:statement
default:statement
}
1.3.1 if与switch对比
例子:输入任意整数值,计算除3之后的余数
//用if语句完成
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
if (n % 3 == 0)
printf("余数是0\n");
else if (n % 3 == 1)
printf("余数是1\n");
else
printf("余数是2\n");
return 0;
}
//用switch语句改写
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch(n % 3)
{
case 0:
printf("余数是0\n");
break;
case 1:
printf("余数是1\n");
break;
case 2:
printf("余数是2\n");
break;
}
return 0;
}
1.3.2 switch语句中的break
如果去掉case语句中的break:
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
switch(n % 3)
{
case 0:
printf("余数是0\n");
case 1:
printf("余数是1\n");
case 2:
printf("余数是2\n");
}
return 0;
}
测试的结果为:
而6除以3余数是0,运行结果却将后两个也打印了出来。因为switch 语句是分⽀效果的,只有在 switch 语句中使⽤ break 才能在跳出 switch 语句。
例子1:输⼊⼀个1~7的数字,打印对应的星期⼏
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
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 7:
printf("星期天\n");
break;
}
return 0;
}
例子2:输⼊1到5,输出的是“⼯作⽇”;输⼊6到7,输出“休息⽇”。
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("⼯作⽇\n");
break;
case 6:
case 7:
printf("休息⽇\n");
break;
}
return 0;
}
1.3.3 switch语句中的default
当 switch 表达式的值并不匹配所有 case 标签的值时,就需要default 子句的加入。
例如,1.3.2的例子2中,如果 day 的输⼊不是1到7的值,我们可以提示输入错误:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("⼯作⽇\n");
break;
case 6:
case 7:
printf("休息⽇\n");
break;
default:
printf("输⼊错误\n");
break;
}
return 0;
}
在 switch 语句中 case 语句和 default 语句是没有顺序要求的,不过我们通常是把 default ⼦句放在最后处理.
二. 循环语句
2.1 三种循环语句
2.1.1 while循环
while循环的语法形式如下:
while ( 表达式)
语句;
while语句可以实现循环效果。
例子:在屏幕上打印 1~10 的值
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
printf("%d ", i);
i = i + 1;
}
return 0;
}
2.1.2 for循环
for 循环在三种循环中使⽤最多,它的语法形式如下:
for (表达式1; 表达式2; 表达式3)
语句;//表达式1 ⽤于循环变量的初始化
//表达式2 ⽤于循环结束条件的判断
//表达式3 ⽤于循环变量的调整
例子:在屏幕上打印1~10的值
#include <stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
printf("%d ", i);
}
return 0;
}
while循环和for循环的对⽐,for 循环的三个部分⾮常集中,便于代码的维护,while 循环的三个部分就⽐较分散,所以从形式上 for 循环要更优⼀些。
2.1.3 do-while循环
do-while循环的语法形式如下:
do
语句;
while (表达式);
do-while循环循环至少执行一次,因为do while 循环是先直接进⼊循环体,然后再执⾏ while 后的判断表达式。
例子:在屏幕上打印1~10的值
#include <stdio.h>
int main()
{
int i = 1;
do
{
printf("%d ", i);
i = i + 1;
} while (i <= 10);
return 0;
}
2.2 break和continue语句
- break 的作⽤是⽤于永久的终⽌循环,只要 break 被执⾏,直接就会跳出循环,继续往后执⾏。
- continue 的作⽤是跳过本次循环中 continue 后边的代码,在 for 循环和 while 循环中有所差异的。
2.2.1 while循环中的break和continue
break举例:
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break;
printf("%d ", i);
i = i + 1;
}
return 0;
}
运行结果:
可以看出,循环中只要遇到break,就停止后期的所有的循环,直接终止循环,所以 break 的作⽤就是永久的终⽌循环。
continue举例:
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
i = i + 1;
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
运行结果:
可以看出,continue 可以帮助我们跳过某⼀次循环 continue 后边的代码,用于终止本次循环。
2.2.2 for循环中的break和continue
break 举例:
#include <stdio.h>
int main()
{
int i = 1;
for (i = 1; i <= 10; i++)
{
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
运行结果:
continue举例:
#include <stdio.h>
int main()
{
int i = 1;
for (i = 1; i <= 10; i++)
{
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
运行结果:
2.2.3 do while循环中的break和continue
do.while 语句中的 break 和 continue 的作⽤和 while 循环中⼏乎⼀模⼀样。不多赘述。
2.3 goto 语句
goto 语句可以实现在同⼀个函数内跳转到设置好的标号处。
例子:
#include <stdio.h>
int main()
{
printf("hehe\n");
goto next;
printf("haha\n");
next:
printf("跳过了haha的打印\n");
return 0;
}