1、程序执行
程序的执行是有一定的流程的,如果中间没有其它情况发生,程序会一直从头执行到结束。
在C语言的定义中,我们有这样的三种基本流程:分支,顺序,循环。可以说这三种流程,是整个程序的架构基石,一切其它变形的流程都是建立在这三种流程执行,如递归等。
2、if语句
除了从前到后顺序执行之外,有时候我们需要检查一个条件,然后根据检查的结果执行不同的后续代码,在C语言中可以用分支语句( Selection Statement) 实现,比如:
if (x != 0) {
printf("x is nonzero.\n");
}
其中x != 0表示“x不等于0”这个条件,这个表达式称为控制表达式( Controlling Expression) 如果条件成立,则{}中的语句被执行,否则{}中的语句不执行,直接跳到}后面。
有时候我们发现有三种情况,而if只能区分两种情况,这个时候,我们有if/else这样的语句,如下示例
if( x > 0){
printf("x 是正整数.\n");
}else if (x < 0){
printf("x 是负整数.\n");
}else {
printf("x 是0.\n");
}
案例比较简单,不做过多描述。
3、逻辑运算
逻辑只有常见的有这样几种:真,假,非真,非假。我们一般用逻辑计算出来的结果表示这样的逻辑,那么就有了逻辑运算符。逻辑运算符主要有:AND,OR,NOT。
AND表示并且,OR表示或者,NOT表示非。但是在语言中我们不用字符来表示,而是用如下的字符表示。
&& || !
关于真值的逻辑运算称为布尔代数,以它的创始人布尔命名。
if (x > 0 && x < 10){
}else{
printf("x is out of range.\n");
}
if (x < 0 || x > 10 ){
printf("x is out of range.\n");
}
注意一个问题,就算if语句之后跟着的只有一句话,也一定要写上括弧啊,虽然你不写,程序也不会出现任何问题,但是为了代码的安全性和可读性,还是加上!!!
4、switch语句
在介绍switch语句之前,我们先看看前面的情况,if/else似乎已经完全可以分支语句了,实际也确实是,但是我们发现,如果分支很多呢?这个时候我们是不是要写很多if/else这样的语句呢?
那么,这个时候,我们引入switch语句。
switch(控制表达式) {
case 常量表达式:语句序列,break;
case 常量表达式:语句序列,break;
default:语句序列,break;
}
注意以下的两点:
1)case后面跟的必须是常量表达式,且必须是可以精确比较的整型或字符型
2)进入case后如果没有遇到break语句就会一直往下执行,后面其它case或default下面的语句也会被执行到,直到遇到break,或者执行到整个switch语句块的末尾。
5、while语句
while语句的引进是因为,我们有时候会进行一些重复性的计算,比如,从1加到100,这个计算。它实际上有很多的重复性计算,那么,我们该如何实现呢?如下:
int result = 1;
int n = 0;
while (n <= 100) {
result = result + n;
n = n + 1;
}
while由一个控制表达式和一个子语句组成,子语句可以是由若干条语句组成的语句块。如果控制表达式的值为真,子语句就被执行,否则循环终止。变量result在这个循环中的作用是累加器( Accumulator),把每次循环的中间结果累积起来,循环结束后得到的累积值就是最终结果
do-while
这里,我们介绍一下do-while语句,这里我们将之归为while循环的一种变式,唯一的区别是,这里的do-while语句,是先执行,后判断。
我们将上面的代码使用do-while改写,会变成这样:
int result = 1;
int n = 0;
do{
result = result + n;
n = n + 1;
}while( n <= 100 );
如果控制表达式的值一开始就是假, while的循环体一次都不执行,而do/while的循环体至少会执行一次。我们可以将上面的阈值(100)改成1,试试看程序运行的结果。
6、for语句
上面介绍了while和do-while语句,但是我们最常使用的循环语句其实是for循环语句,格式如下:
for(控制表达式1;控制表达式2;控制表达式3)
语句
result = 1;
for(int i= 0; i <= 100; i++){
result = result + i;
}
1)控制表达式1和3都可以为空,但控制表达式2是必不可少的,例如, for(;1;){...}等价于while(1){...}死循环。 C语言规定,如果控制表达式2为空,则当作控制表达式2的值为真,因此,死循环也可以写成for(;;){...}
2)for循环中,控制表达式1只运行一次,就是初始化,而控制表达式2和3会一直运行,一般来说,控制表达式2用来做判断,而控制表达式3用来做赋值操作。
7、终止语句
终止程序的语句,有两种,一种是break,一种是continue。
到了break语句的一种用法,用来跳出switch语句块,这个语句也可以用来跳出循环体。 continue语句也用来终止当前循环,和break语句不同的是, continue语句终止当前循环后又回到循环体的开头准备再次执行循环体。我们看下面这样一段代码,找出从1到100之内的所有素数,如下:
#include <stdio.h>
int is_prime(int n)
{
int i;
for (i = 2; i < n; i++){
if (n % i == 0){
break;
}
}
if (i == n){
return 1;
}else{
return 0;
}
}
int main(void)
{
int i;
for (i = 1; i <= 100; i++) {
if (!is_prime(i)){
continue;
}
printf("%d\n", i);
}
return 0;
}
我们可以在循环中尝试,更改break为continue,看看会发生什么结果,反之,修改continue为break,看看会发生什么呢
8、嵌套循环
在7中,我们上面使用了函数,这里我们先不解释函数这个概念,能够运行上面的程序即可。而实际上,这里是一个嵌套的循环结构,我们将程序改写如下:
#include <stdio.h>
int main(void)
{
int i, j;
for (i = 1; i <= 100; i++) {
for (j = 2; j < i; j++){
if (i % j == 0){
break;
}
}
if (j == i){
printf("%d\n", i);
}
}
return 0;
}
现在内循环的循环变量就不能再用i了,而是改用j,原来程序中is_prime函数的参数n现在直接用i代替。在有嵌套循环的情况下, break只能跳出最内层的循环或switch语句, continue也只能终止最内层循环并回到该循环的开头。
9、goto语句
上面我们介绍了分支和循环这样的概念,在break和continue两种终止语句中,我们只能实现有条件的跳转,而这里介绍的goto可以实现无条件的跳转。
goto语句在C语言中作为关键字进行了保留,但是这里并不推荐使用goto语句,这样的语句会导致结构混乱,流程控制出现许多问题。这里就不再做过多的介绍了。