C编程基础二

循环

C 循环

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

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

循环语句允许我们多次执行一个语句或语句组,下面是大多数编程语言中循环语句的流程图

C 语言提供了以下几种循环类型。点击链接查看每个类型的细节。

循环类型 描述
while 循环 当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。
for 循环 多次执行一个语句序列,简化管理循环变量的代码。
do...while 循环 除了它是在循环主体结尾测试条件外,其他与 while 语句类似。
嵌套循环 您可以在 while、for 或 do..while 循环内使用一个或多个循环。

while 循环

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

语法

C 语言中 while 循环的语法

while(condition) {
	statement(s);
}

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

condition 可以是任意的表达式,当为任意非零值时都为 true。当条件为 true 时执行循环。当条件为 false 时,退出循环,程序流将继续执行紧接着循环的下一条语句。

流程图

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

实例

#include <stdio.h>
	
int main () {
	
	/* local variable definition */
	int a = 10;
	
	/* while loop execution */
	while( a < 20 ) {
		printf("value of a: %d\n", a);
		a++;
	}
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
value of a: 16
value of a: 17
value of a: 18
value of a: 19

for 循环

for 循环允许您编写一个执行指定次数的循环控制结构。

C 语言中 for 循环的语法

for ( init; condition; increment ) {
	statement(s);
}

下面是 for 循环的控制流

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

流程图

实例

#include <stdio.h>
	
int main () {
	
	int a;
	
	/* for loop execution */
	for( a = 10; a < 20; a = a + 1 ){
		printf("value of a: %d\n", a);
	}
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
value of a: 16
value of a: 17
value of a: 18
value of a: 19

do...while 循环

不像 forwhile 循环,它们是在循环头部测试循环条件。在 C 语言中,do...while 循环是在循环的尾部检查它的条件。

do...while 循环与 while 循环类似,但是 do...while 循环会确保至少执行一次循环。

C 语言中 for 循环的语法

do {
	statement(s);
}while( condition );

请注意,条件表达式出现在循环的尾部,所以循环中的 statement(s) 会在条件被测试之前至少执行一次。

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

流程图

实例

#include <stdio.h>
	
int main () {
	
	/* local variable definition */
	int a = 10;
	
	/* do loop execution */
	do {
		printf("value of a: %d\n", a);
		a = a + 1;
	}while( a < 20 );
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
value of a: 16
value of a: 17
value of a: 18
value of a: 19

嵌套循环

C编程允许在另一个循环内部使用一个循环。 以下部分将举例说明这个概念。

C 语言中 嵌套 for 循环 语句的语法。

for ( init; condition; increment ) {
	
	for ( init; condition; increment ) {
		statement(s);
	}
	statement(s);
}

C 语言中 嵌套 while 循环 语句的语法。

while(condition) {
	
	while(condition) {
		statement(s);
	}
	statement(s);
}

C 语言中 嵌套 do...while 循环 语句的语法。

do {
	statement(s);
	
	do {
		statement(s);
	}while( condition );
	
}while( condition );

实例

下面的程序使用了一个嵌套的 for 循环来查找 2 到 100 中的质数

#include <stdio.h>
	
int main () {
	
	/* local variable definition */
	int i, j;
	
	for(i = 2; i<100; i++) {
	
		for(j = 2; j <= (i/j); j++)
		if(!(i%j)) break; // if factor found, not prime
		if(j > (i/j)) printf("%d is prime\n", i);
	}
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

2 is prime
3 is prime
5 is prime
7 is prime
11 is prime
13 is prime
17 is prime
19 is prime
23 is prime
29 is prime
31 is prime
37 is prime
41 is prime
43 is prime
47 is prime
53 is prime
59 is prime
61 is prime
67 is prime
71 is prime
73 is prime
79 is prime
83 is prime
89 is prime
97 is prime

循环控制语句

循环控制语句改变你代码的执行顺序。通过它你可以实现代码的跳转。

C 提供了下列的循环控制语句。

控制语句 描述
break 语句 终止循环switch 语句,程序流将继续执行紧接着循环或 switch 的下一条语句。
continue 语句 告诉一个循环体立刻停止本次循环迭代,重新开始下次循环迭代。
goto 语句 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句。

break 语句

C 语言中 break 语句有以下两种用法

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

如果您使用的是嵌套循环(即一个循环内嵌套另一个循环),break 语句会停止执行最内层的循环,然后开始执行该块之后的下一行代码。

C 语言中 break 语句的语法

break;

流程图

实例

#include <stdio.h>
	
int main () {
	
	/* local variable definition */
	int a = 10;
	
	/* while loop execution */
	while( a < 20 ) {
	
		printf("value of a: %d\n", a);
		a++;
	
		if( a > 15) {
		/* terminate the loop using break statement */
		break;
		}
	}
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15

continue 语句

C 语言中的 continue 语句有点像 break 语句。但它不是强迫终止,continue 会跳过当前循环中的代码,强迫开始下一次循环。

对于 for 循环,continue 语句执行后自增语句仍然会执行。对于 whiledo...while 循环,continue语句重新执行条件判断语句。

C 语言中 continue 语句的语法

continue;

流程图

实例

#include <stdio.h>
	
int main () {
	
	/* local variable definition */
	int a = 10;
	
	/* do loop execution */
	do {
	
		if( a == 15) {
			/* skip the iteration */
			a = a + 1;
			continue;
			}
	
		printf("value of a: %d\n", a);
		a++;
	
	} while( a < 20 );
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 16
value of a: 17
value of a: 18
value of a: 19

goto 语句

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

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

C 语言中 goto 语句的语法

goto label;
..
.
label: statement;

流程图

实例

#include <stdio.h>
	
int main () {
	
	/* local variable definition */
	int a = 10;
	
	/* do loop execution */
	LOOP:do {
	
		if( a == 15) {
			/* skip the iteration */
			a = a + 1;
			goto LOOP;
			}
	
		printf("value of a: %d\n", a);
		a++;
	
	}while( a < 20 );
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 16
value of a: 17
value of a: 18
value of a: 19

无限循环

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

#include <stdio.h>
	
int main () {
	
	for( ; ; ) {
		printf("This loop will run forever.\n");
	}
	
	return 0;
}

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

注意:您可以按 Ctrl + C 键终止一个无限循环。

函数

C 函数

函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。

您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。

函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。/p>

C 标准库提供了大量的程序可以调用的内置函数。例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置。

函数还有很多叫法,比如方法、子例程或程序,等等。

定义函数

C 语言中的函数定义的一般形式如下

return_type function_name( parameter list )
{
	body of the function
}

在 C 语言中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分

  • 返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void
  • 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
  • 参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
  • 函数主体:函数主体包含一组定义函数执行任务的语句。

实例

以下是 max() 函数的源代码。该函数有两个参数 num1 和 num2,会返回这两个数中较大的那个数

/* function returning the max between two numbers */
int max(int num1, int num2) {
	
	/* local variable declaration */
	int result;
	
	if (num1 > num2)
		result = num1;
	else
		result = num2;
	
	return result;
}

函数声明

函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。/p>

函数声明包括以下几个部分/p>

return_type function_name( parameter list );

针对上面定义的函数 max(),以下是函数声明

int max(int num1, int num2);

在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:

int max(int, int);

当您在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,您应该在调用函数的文件顶部声明函数。

调用函数

创建 C 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。

当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。

调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。例如

#include <stdio.h>
	
/* function declaration */
int max(int num1, int num2);
	
int main () {
	
	/* local variable definition */
	int a = 100;
	int b = 200;
	int ret;
	
	/* calling a function to get max value */
	ret = max(a, b);
	
	printf( "Max value is : %d\n", ret );
	
	return 0;
}
	
/* function returning the max between two numbers */
int max(int num1, int num2) {
	
	/* local variable declaration */
	int result;
	
	if (num1 > num2)
		result = num1;
	else
		result = num2;
	
	return result;
}

把 max() 函数和 main() 函数放一块,编译源代码。当运行最后的可执行文件时,会产生下列结果

Max value is : 200

函数参数

如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数

形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

当调用函数时,有两种向函数传递参数的方式

调用类型 描述
传值调用 该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
引用调用 通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

默认情况下,C 使用传值调用来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的实际参数。

传值方式调用函数

向函数传递参数的传值调用方法,把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。

默认情况下,C 语言使用传值调用方法来传递参数。一般来说,这意味着函数内的代码不会改变用于调用函数的实际参数。函数 swap() 定义如下:

/* function definition to swap the values */
void swap(int x, int y) {
	
	int temp;
	
	temp = x; /* save the value of x */
	x = y;    /* put y into x */
	y = temp; /* put temp into y */
	
	return;
}

现在,让我们通过传递实际参数来调用函数 swap()

#include <stdio.h>
	
/* function declaration */
void swap(int x, int y);
	
int main () {
	
	/* local variable definition */
	int a = 100;
	int b = 200;
	
	printf("Before swap, value of a : %d\n", a );
	printf("Before swap, value of b : %d\n", b );
	
	/* calling a function to swap the values */
	swap(a, b);
	
	printf("After swap, value of a : %d\n", a );
	printf("After swap, value of b : %d\n", b );
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :100
After swap, value of b :200

上面的实例表明了,虽然在函数内改变了 a 和 b 的值,但是实际上 a 和 b 的值没有发生变化。

引用方式调用函数

通过引用传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

传递指针可以让多个函数访问指针所引用的对象,而不用把对象声明为全局可访问。

/* function definition to swap the values */
void swap(int *x, int *y) {
	
	int temp;
	temp = *x;    /* save the value at address x */
	*x = *y;      /* put y into x */
	*y = temp;    /* put temp into y */
	
	return;
}

如需了解 C 中指针的更多细节,请访问C - 指针章节。

现在,让我们通过引用传值来调用函数 swap()

#include <stdio.h>
	
/* function declaration */
void swap(int *x, int *y);
	
	int main () {
	
	/* local variable definition */
	int a = 100;
	int b = 200;
	
	printf("Before swap, value of a : %d\n", a );
	printf("Before swap, value of b : %d\n", b );
	
	/* calling a function to swap the values.
	* &a indicates pointer to a ie. address of variable a and
	* &b indicates pointer to b ie. address of variable b.
	*/
	swap(&a, &b);
	
	printf("After swap, value of a : %d\n", a );
	printf("After swap, value of b : %d\n", b );
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :200
After swap, value of b :100

上面的实例表明了,与传值调用不同,引用调用在函数内改变了 a 和 b 的值,实际上也改变了函数外 a 和 b 的值。

作用域规则

C 作用域规则

任何一种编程中,作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问。C 语言中有三个地方可以声明变量

  • 在函数或块内部的局部变量
  • 在所有函数外部的全局变量
  • 形式参数的函数参数定义中

让我们来看看什么是局部变量、全局变量和形式参数。

局部变量

在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部的语句使用。局部变量在函数外部是不可知的。下面是使用局部变量的实例。在这里,所有的变量 a、b 和 c 是 main() 函数的局部变量。

#include <stdio.h>
	
int main () {
	
	/* local variable declaration */
	int a, b;
	int c;
	
	/* actual initialization */
	a = 10;
	b = 20;
	c = a + b;
	
	printf ("value of a = %d, b = %d and c = %d\n", a, b, c);
	
	return 0;
}

全局变量

全局变量是定义在函数外部,通常是在程序的顶部。全局变量在整个程序生命周期内都是有效的,在任意的函数内部能访问全局变量。

全局变量可以被任何函数访问。也就是说,全局变量在声明后整个程序中都是可用的。下面是使用全局变量和局部变量的实例

#include <stdio.h>
	
/* global variable declaration */
int g;
	
int main () {
	
	/* local variable declaration */
	int a, b;
	
	/* actual initialization */
	a = 10;
	b = 20;
	g = a + b;
	
	printf ("value of a = %d, b = %d and g = %d\n", a, b, g);
	
	return 0;
}

在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值。下面是一个实例

#include <stdio.h>
	
/* global variable declaration */
int g = 20;
	
int main () {
	
	/* local variable declaration */
	int g = 10;
	
	printf ("value of g = %d\n",  g);
	
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果

>
value of g = 10

形式参数

函数的参数,形式参数,被当作该函数内的局部变量,它们会优先覆盖全局变量。下面是一个实例

#include <stdio.h>
	
/* global variable declaration */
int a = 20;
	
int main () {
	
	/* local variable declaration in main function */
	int a = 10;
	int b = 20;
	int c = 0;
	
	printf ("value of a in main() = %d\n",  a);
	c = sum( a, b);
	printf ("value of c in main() = %d\n",  c);
	
	return 0;
}
	
/* function to add two integers */
int sum(int a, int b) {
	
	printf ("value of a in sum() = %d\n",  a);
	printf ("value of b in sum() = %d\n",  b);
	
	return a + b;
}

当上面的代码被编译和执行时,它会产生下列结果

value of a in main() = 10
value of a in sum() = 10
value of b in sum() = 20
value of c in main() = 30

初始化局部变量和全局变量

当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动对其初始化,如下所示

数据类型 初始化默认值
int 0
char '\0'
float 0
double 0
pointer NULL

正确地初始化变量是一个良好的编程习惯,否则有时候程序可能会产生意想不到的结果,因为未初始化的变量会导致一些在内存位置中已经可用的垃圾值。

 

 

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇