C语言学习教程(三)

C语言学习教程(三):本系列教程第10-11章。

10-Decision Making in C

决策结构(Decision Making)要求程序员指定一个或多个要评估或测试的条件,以及如果条件为真时要执行的一个或多个语句,以及可选地,如果条件被确定为假时要执行的其他语句。

以下是在大多数编程语言中发现的典型决策结构的一般形式:

image-20220916174619028

C语言把任何非零和非空值假定为真(True),把零和空值(null)假定为假(False)。

C语言提供了以下类型的决策结构。

(1)if语句

if语句由一个布尔表达式后跟一个或多个语句组成。

C语言中if语句的语法如下:

1
2
3
if(boolean_expression){
  //如果布尔表达式为真,将执行的语句
}

如果布尔表达式结果为真,则if语句内的代码块将会被执行。如果布尔表达式结果为假,则if语句结束后的第一组代码(闭括号后)将被执行。

image-20220916174619028

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>

int main(){

	int a = 10;

	if(a < 20){
		printf("a is less than 20.\n");
	}
	printf("Exact value of a is : %d\n", a ); 

	return 0;
}

执行结果:

1
2
3
4
$ gcc -o test1 test1.c
$ ./test1
a is less than 20.
Exact value of a is : 10

(2)if…else语句

if语句后面可跟可选的else语句,else语句在当布尔表达式为False时执行。

C语言中if…else语句的语法如下:

1
2
3
4
5
if(boolean_expression){
  //如果布尔表达式为真,将执行的语句
}else{
  //如果布尔表达式为假,将执行的语句
}

image-20220916181148609

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <stdio.h>

int main(){

	int a = 100;

	if(a < 20)
	{
		printf("a is less than 20.\n");
	}else{
		printf("a is not less than 20.\n");
	}
	printf("Exact value of a is : %d\n", a ); 

	return 0;
}

运行结果:

1
2
3
4
$ cc -o test2 test2.c
$ ./test2
a is not less than 20.
Exact value of a is : 100

(3)if…else if…else语句

if语句后面可跟可选的else if…else语句,这可用于测试多种条件。

当使用if…else if…else语句时,需要注意:一旦某个 else if 匹配成功,其他的 else if 或 else 将不会再被执行。

C语言中if…else if…else语句的语法如下:

1
2
3
4
5
6
7
8
9
if(boolean_expression 1){
  //如果 布尔表达式1 为真,将执行的语句
}else if(boolean_expression 2){
  //如果 布尔表达式2 为真,将执行的语句
}else if(boolean_expression 3){
  //如果 布尔表达式3 为真,将执行的语句
}else{
  //如果布尔表达式都为假,将执行的语句
}

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

int main(){

	int a = 100;

	if(a == 10){
		printf("Value a is 10.\n");
	}else if(a == 20){
		printf("Value a is 20.\n");
	}else if(a == 30){
		printf("Value a is 30.\n");
	}else{
		printf("None of the values is matching.\n");
	}
	printf("Exact value of a is %d.\n", a);

	return 0;
}

运行结果:

1
2
3
4
$ gcc -o test3 test3.c
$ ./test3
None of the values is matching.
Exact value of a is 100.

(4)嵌套if语句

在C语言中,嵌套if-else语句是合法的,这意味着你可以在一个if或else if语句中使用另一个if或else if语句。

C语言中嵌套if语句的语法如下:

1
2
3
4
5
6
7
8
if(boolean_expression 1)
{
   //如果 布尔表达式1 为真,将执行的语句
   if(boolean_expression 2)
   {
       //如果 布尔表达式2 为真,将执行的语句
   }
}

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main(){

	int a = 100;
	int b = 200;

	if(a == 100){
		if(b == 200){
			printf("Value of a is 100 and b is 200\n" );
		}
	}

	printf("Exact value of a is : %d\n", a ); 
	printf("Exact value of b is : %d\n", b );
	return 0;
}

运行结果:

1
2
3
4
5
$ gcc -o test4 test4.c
$ ./test4
Value of a is 100 and b is 200
Exact value of a is : 100
Exact value of b is : 200

(5)switch语句

switch语句允许测试一个变量等于多个值时的情况。每个值称为一个case,被测试的变量会对每个switch case进行检查。

C语言中switch语句的语法如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
switch(expression){
    case constant-expression  :
       statement(s);
       break;
    case constant-expression  :
       statement(s);
       break; 
    /* you can have any number of case statements */
    default :
       statement(s);
}

switch语句必须遵循下面的规则:

  • switch语句中的expression是一个常量表达式,必须是一个整型或枚举类型。
  • switch语句中可以有任意数量的case语句。每个case后跟一个要比较的值和一个冒号。
  • case的constant-expression必须与switch(expression)中的expression具有相同的数据类型,且必须是一个常量或字面量。
  • 当被测试的变量等于case中的常量时,case后跟的语句将被执行,直到遇到break语句为止。
  • 当遇到break语句时,switch语句终止,控制流将跳出switch语句,然后执行程序剩下的代码。
  • 不是每一个case都需要包含break。如果case语句不包含break,控制流将会继续执行switch中后续的case,直到遇到break为止。
  • switch语句可以有一个可选的default case,出现在switch语句的结尾。default case可用于在上面所有 case 都不为真的时候执行一个任务。default case中的break语句不是必需的。

image-20220916190112176

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>


int main(){

	char grade = 'B';

	switch(grade){
		case 'A':
			printf("Excellent!\n");
			break;
		case 'B':
		case 'C':
			printf("Well done.\n");
			break;
		case 'D':
			printf("You passed.\n");
			break;
		case 'E':
			printf("Better try again.\n");
			break;
		default:
			printf("Invalid grade.\n");
	}
	printf("Your grade is %c.\n", grade);
	return 0;
}

运行结果:

1
2
3
$ ./test5
Well done.
Your grade is B.

(6)嵌套switch语句

您可以把一个switch作为一个外部switch语句序列的一部分,即可以在一个switch语句内使用另一个switch语句。即使内部和外部switch的case常量包含共同的值,也没有矛盾。

C语言中嵌套switch语句的语法如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
switch(ch1) {
   case 'A':
      printf("This A is part of outer switch" );
      switch(ch2) {
         case 'A':
            printf("This A is part of inner switch" );
            break;
         case 'B': /* case code */
      }
      break;
   case 'B': /* case code */
}

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

int main(){
	int a = 100;
	int b = 200;

	switch(a){
		case 100:
			printf("This is part of outer switch.\n");
			switch(b){
				case 200:
					printf("This is part of inner switch.\n");
					break;
			}
			break;
	}
	printf("Exact value of a is: %d.\n", a);
	printf("Exact value of b is: %d.\n", b);

	return 0;
}

运行结果:

1
2
3
4
5
6
$ gcc -o test6 test6.c
$ ./test6
This is part of outer switch.
This is part of inner switch.
Exact value of a is: 100.
Exact value of b is: 200.

(7)?:运算符(三元运算符)

在前面的小节中我们讲解了条件运算符?:,可以用来替代if...else语句。它的一般形式如下:

Exp1 ? Exp2 : Exp3

其中,Exp1、Exp2 和 Exp3 是表达式。需注意,冒号的使用和位置。

?: 表达式的值是由 Exp1 决定的。如果 Exp1 为真,则计算 Exp2 的值,结果即为整个表达式的值。如果 Exp1 为假,则计算 Exp3 的值,结果即为整个表达式的值。

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <stdio.h>

int main(){

	int num;
	printf("请输入一个整数: ");
	scanf("%d",&num);

	(num>10)?printf("输入的数值大于10.\n"):printf("输入的数值小于10.\n");
	return 0;
}

运行结果:

1
2
3
4
5
6
7
$ gcc -o test7 test7.c
$ ./test7
请输入一个整数: 19
输入的数值大于10.
$ ./test7
请输入一个整数: 8
输入的数值小于10.

11-C Loops

有的时候,我们可能需要多次执行同一块代码。一般情况下,语句是按顺序执行的:函数中的第一个语句先执行,接着是第二个语句,依此类推。

编程语言提供了多种更为复杂执行路径的控制结构。

循环语句允许我们多次执行一条语句或一组语句,下面是在大多数编程语言中循环语句的一般形式:

image-20220923175728949

C语言提供以下类型的循环来处理循环要求。

(1)while循环

只要给定的条件为真,C语言中的while循环就会重复执行目标语句。

C语言中while循环语句的语法如下:

1
2
3
4
while(condition)
{
   statement(s);
}

在这里,statement(s)可以是一个单独的语句,也可以是几个语句组成的代码块。

condition可以是任意的表达式,当为任意非零值时都为true。

当条件为true时执行循环,当条件为false时,退出循环,程序流将继续执行紧接着循环的下一条语句。

BFE13459-897C-41A5-AE94-D71B0CA50FB6

在这里,while循环的关键点是循环可能永远都不会被执行。当条件为false时,循环主体会被跳过,并且紧接着while循环后的下一条语句就会被执行。

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>

int main(){

	int a = 10;

	while(a < 20){
		printf("Value a is: %d.\n", a);
		a++;
	}

	return 0;
}

运行结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ gcc -o test1 test1.c
$ ./test1
Value a is: 10.
Value a is: 11.
Value a is: 12.
Value a is: 13.
Value a is: 14.
Value a is: 15.
Value a is: 16.
Value a is: 17.
Value a is: 18.
Value a is: 19.

(2)for循环

for循环是一种重复控制结果,它允许你编写一个需要执行特定次数的循环。

C语言中for循环语句的语法如下:

1
2
3
for(init; condition; increment){
    statement(s);
}

![Screen Shot 2022-09-26 at 11.12.31](/img/Screen Shot 2022-09-26 at 11.12.31.png)

  • init会首先被执行,且只执行一次。这一步允许你声明并初始化任何循环控制变量。你也可以不在这里写任何语句,只要有一个分号出现即可。
  • 接下来,会判断condition。如果为真,则执行循环体内的语句;如果为假,循环体内的语句就不会执行,并且控制流会跳转到紧接着for循环的下一条语句。
  • 在执行完for循环主体内的语句后,控制流会跳转回上面的increment语句。该语句允许你更新循环控制变量。你也可以不在这里写任何语句,只要在condition后有一个分号出现即可。
  • condition会再次被判断。如果为真,则执行循环体内的语句。这个过程会不断重复(循环主体,然后更新循环控制变量,再重新判断条件)。如果为假,循环体内的语句就不会执行,并且控制流会跳转到紧接着for循环的下一条语句。

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <stdio.h>

int main(){

	for(int a=10; a < 20; a=a+1){
		printf("Value of a is: %d.\n", a);
	}

	return 0;
}

运行结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ gcc -o test2 test2.c
$ ./test2
Value of a is: 10.
Value of a is: 11.
Value of a is: 12.
Value of a is: 13.
Value of a is: 14.
Value of a is: 15.
Value of a is: 16.
Value of a is: 17.
Value of a is: 18.
Value of a is: 19.

(3)do…while循环

在C语言中,forwhile循环的循环判断条件(condition)在循环头部;do...while循环的循环判断条件(condition)在循环尾部。

C语言中do…while循环语句的语法如下:

1
2
3
do{
  statement(s);
}while(condition);

![Screen Shot 2022-09-26 at 14.47.27](/img/Screen Shot 2022-09-26 at 14.47.27.png)

需要注意的是,条件表达式condition在代码的尾部,所以该循环体中的代码块statement(s)在条件被测试之前至少执行一次。

如果条件为真,控制流就会跳转回上面的do,然后重新执行循环体中的statement(s)。这个过程会不断重复,知道给定的条件变为假为止。

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>

int main(){

	int a = 10;

	do{
		printf("Value of a is: %d.\n", a);
		a = a + 1;
	}while(a < 20);

	return 0;
}

运行结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ gcc -o test3 test3.c
$ ./test3
Value of a is: 10.
Value of a is: 11.
Value of a is: 12.
Value of a is: 13.
Value of a is: 14.
Value of a is: 15.
Value of a is: 16.
Value of a is: 17.
Value of a is: 18.
Value of a is: 19.
➜  11-C Loops

(4)嵌套循环

C语言允许在一个循环内使用另一个循环。

C语言中嵌套for循环语句的语法如下:

1
2
3
4
5
6
for(init; condition; increment){
	for(init; condition; increment){
        statement(s);
    }
    statement(s);
}

C语言中嵌套while循环语句的语法如下:

1
2
3
4
5
6
while(condition){
    while(condition){
        statement(s);
    }
    statement(s);
}

C语言中嵌套do...while循环语句的语法如下:

1
2
3
4
5
6
do{
	statement(s);
    do{
        statement(s);
    }while(condition);
}while(condition);

关于嵌套循环有一点需要注意:你可以在任意类型的循环内嵌套其他任何类型的循环。比如,一个for循环可以嵌套在一个while循环中,反之亦然。

(5)break语句

C语言中break语句由两种用法:

  • break语句出现在一个循环内时,循环会立即终止,写程序控制流将继续执行紧接着循环的下一条语句。
  • break语句可以用于终止switch语句中的一个case。

C语言中break语句的语法如下:

1
break;

break跳出while循环:

image-20220926175423040

break跳出do…while循环:

image-20220926175527215

break跳出for循环:

image-20220926175634425

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <stdio.h>

int main(){

	int a = 10;

	while(a < 20){
		printf("Value of a is: %d.\n", a);
		a++;
		if(a > 15){
			break;
		}
	}

	return 0;
}

运行结果:

1
2
3
4
5
6
7
8
$ gcc -o test4 test4.c
$ ./test4
Value of a is: 10.
Value of a is: 11.
Value of a is: 12.
Value of a is: 13.
Value of a is: 14.
Value of a is: 15.

(6)continue语句

C中的continue语句和break语句类似,但它直接跳出循环,continue会跳出本次循环,接着开始执行下一次循环。

对于 while 和 do…while 循环,continue 语句会跳转重新执行条件判断语句。

对于 for 循环,continue 语句执行后会跳转重新执行条件判断语句,循环控制变量语句仍然会被执行。

C语言中continue语句的语法如下:

1
continue;

continue跳出while的本次循环执行下一次循环:

image-20220926182404155

continue跳出do…while的本次循环执行下一次循环:

image-20220926182501153

continue跳出for的本次循环执行下一次循环:

对于for循环,continue语句执行后,循环控制变量语句仍然会执行。

image-20220926182613503

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main(){

	int a = 10;

	do{
		if(a == 15){
			a = a + 1;
			continue;
		}
		printf("Value of a is: %d.\n", a);
		a = a + 1;
	}while(a < 20);

	return 0;
}

运行结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ gcc -o test5 test5.c
$ ./test5
Value of a is: 10.
Value of a is: 11.
Value of a is: 12.
Value of a is: 13.
Value of a is: 14.
Value of a is: 16.
Value of a is: 17.
Value of a is: 18.
Value of a is: 19.

(7)goto语句

C 语言中的goto语句允许把控制流无条件的转移到同一函数内的被标记的语句处。

注意:在任何编程语言中,都不建议使用goto语句。因为它使得程序的控制流难以跟踪,使程序难以理解和难以修改。任何使用goto语句的程序可以改写成不需要使用goto语句的写法。

C语言中goto语句的语法如下:

1
2
3
4
goto label;
...
...
label statement;

在这里,“label"可以是任何除 C 关键字以外的任何纯文本,它可以设置在 C 程序中 goto 语句的前面或者后面任何位置。

image-20220926183848588

image-20220926183822909

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main(){

	int a = 10;

	LOOP:do{
		if(a == 15){
			a = a + 1;
			goto LOOP;
		}
		printf("Value of a is: %d.\n", a);
		a++;
	}while(a < 20);

	return 0;
}

运行结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ gcc -o test6 test6.c
$ ./test6
Value of a is: 10.
Value of a is: 11.
Value of a is: 12.
Value of a is: 13.
Value of a is: 14.
Value of a is: 16.
Value of a is: 17.
Value of a is: 18.
Value of a is: 19.

(8)无限循环

如果条件永远不为假,则循环将变成无限循环。

for循环在传统意义上可用于实现无限循环。由于构成循环的三个表达式中任何一个都不是必需的,因此可以将某些条件表达式留空来构成一个无限循环。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <stdio.h>

int main(){
    
    for( ; ; ){
        printf("This loop will run forever.\n");
    }
    
    return 0;
}

运行结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ gcc -o test7 test7.c
$ ./test7
This loop will run forever.
This loop will run forever.
This loop will run forever.
This loop will run forever.
This loop will run forever.
This loop will run forever.
This loop will run forever.
...
...

当条件表达式不存在时,它被假设为真。你也可以设置一个初始值和增量表达式,但是一般情况下,C 程序员偏向于使用 for(;;) 结构来表示一个无限循环。可以按 Ctrl + C 键终止一个无限循环。

updatedupdated2023-04-242023-04-24