第六章 C控制语句:循环
1 #include<stdio.h> 2 int main(void) 3 { 4 long num; 5 long sum = 0; 6 _Bool input_is_good; 7 printf("Please enter an integer to be summed "); 8 printf("(q to quit): "); 9 input_is_good = (scanf_s("%ld", &num) == 1); 10 while (input_is_good) 11 { 12 sum = sum + num; 13 printf("Please enter next integer(q to quit): "); 14 input_is_good = (scanf_s("%ld", &num) == 1); 15 } 16 printf("Those integers sum to %ld.\n", sum); 17 18 return 0; 19 }
一、循环
1、while和do while循环
(1)== 相等运算符
1)判断status 是否等于1,而 status = 1是将1赋给status, 不要搞混;
2)是while循环下去的条件,而且在while循环内不断修改status的值,且scanf_s接受的是ld,如果输入一个字符,则scanf_s将返回失败,返回一个不等于1的值,此时while循环退出;
3)对于 status =scanf_s("%ld",&num),scanf()返回成功读取输入项的数量,如果scanf()成功读取一个整数,把该数存入 num 并返回 1,随后赋给 status,如果用户输入的不是数字,scanf() 会读取失败并返回 0。如果 scanf() 在转换值之前出了问题(例如,检测到文件结尾或遇到硬件问题),会返回一个特殊值EOF (其值通常被定义为-1)。这个值也会引起循环终止。
1 #include<stdio.h> 2 int main(void) 3 { 4 long num; 5 long sum = 0; 6 int status; 7 8 printf("Please enter an integer to be summed"); 9 printf("(q to quit): "); 10 status=scanf_s("%ld", &num); 11 while (status == 1) 12 { 13 sum = num + sum; 14 printf("Please enter next integer to be summed(q to quit): "); 15 status = scanf_s("%ld", &num); 16 } 17 printf("Those integers sum to %ld.\n", sum); 18 19 return 0; 20 21 }
(2)while可以没有大括号
如下程序,解析:while这一行就是一条语句,进行不断循环,当while循环为假的时候,才跳出循环,此时,n 为4。

(3)fabs函数在while循环中的使用方法
1 #include<math.h> 2 #include<stdio.h> 3 int main(void) 4 { 5 const double ANSWER = 3.14159; 6 double response; 7 8 printf("What is the value of pi?\n "); 9 scanf_s("%lf", &response); 10 while (fabs(response - ANSWER) > 0.0001) 11 { 12 printf("Try again!\n"); 13 scanf_s("%lf", &response); 14 } 15 printf("Close enough!"); 16 17 return 0; 18 }
2、for循环
本章将介绍以下内容:
1、关键字——for、while、do while
2、运算符——<、>、>=、<=、!=、==、+=、*=、-=、/=、%=;
3、函数——fabs();
4、C语言有三种循环——for、while、do while;
5、使用关系运算符构建控制循环的表达式;
6、其他运算符;
7、循环常用的数组;
8、编写有返回值的函数。
一门语言应该提供以下三种形式的程序流:(1)执行语句序列;(2)如果满足某些条件就重复执行语句序列(循环);(3)通过测试选择执行哪一个语句序列(分支)。
6.1 再探 while 循环

解析:1、== 是相等运算符,判断status 是否等于1,而 status = 1是将1赋给status, 不要搞混。2、对于 status =scanf_s("%ld",&num),scanf()返回成功读取输入项的数量,如果scanf()成功读取一个整数,把该数存入 num 并返回 1,随后赋给 status,如果用户输入的不是数字,scanf() 会读取失败并返回 0。如果 scanf() 在转换值之前出了问题(例如,检测到文件结尾或遇到硬件问题),会返回一个特殊值EOF (其值通常被定义为-1)。这个值也会引起循环终止。
status = scanf_s("%ld",&num); while (status == 1) { /* 循环行为 */ status = scanf_s("%ld",&num); } //可以用以下这些代替 while (scanf_s("%ld",&num) { /* 循环体行为 */ }
6.2 while 语句

解析:while这一行就是一条语句,进行不断循环,当while循环为假的时候,才跳出循环,此时,n 为4。
6.3 用关系运算符和表达式比较大小
下面的程序利用 fabs()函数来判断一个数是否接近预期结果
#include<math.h> #include<stdio.h> int main(void) { const double ANSWER = 3.14159; double response; printf("What is the value of pi?\n "); scanf_s("%lf", &response); while (fabs(response - ANSWER) > 0.0001) { printf("Try again!\n"); scanf_s("%lf", &response); } printf("Close enough!"); return 0; }
解析:1、比较浮点数时,尽量只使用<和>。因为浮点数舍入误差会导致在逻辑上应该相等的两数却不相等。2、fabs()函数(声明在math.h 头文件中)可以方便地比较浮点数,该函数返回一个浮点值的绝对值。
6.3.2其他真值:下面的函数证明 “0为假非0为真”

6.3.4 新的_Bool类型
表示真或假的变量被称为布尔变量,而_Bool是C语言中布尔变量的类型名,_Bool类型的变量只能存储1(真)或0(假)。如果把其他非0数值赋给_Bool类型的变量,该变量会被赋予1,这反映了C把所有的非0数值都视为真。
#include<stdio.h> int main(void) { long num; long sum = 0; _Bool input_is_good; printf("Please enter an integer to be summed "); printf("(q to quit): "); input_is_good = (scanf_s("%ld", &num) == 1); while (input_is_good) { sum = sum + num; printf("Please enter next integer(q to quit): "); input_is_good = (scanf_s("%ld", &num) == 1); } printf("Those integers sum to %ld.\n", sum); return 0; }
6.3.5 优先级和关系运算符
算术运算符 > 关系运算符 > 赋值运算符
例如:x > y + 2 等同于x > (y + 2); x = y > 2 等同于 x = (y>2)。
6.4不确定循环和计数循环
概念:1、不确定循环:在测试表达式为假之前,不知道要进行多少次循环,因为你不知道用户会输入一个什么数。
2、计数循环:在执行循环之前就知道要重复执行多少次。
6.5 for循环
1 #include<stdio.h> 2 int main(void) 3 { 4 const int NUMBER = 22; 5 int count; 6 7 double a = 0.01; 8 9 for (count = 1; count <= NUMBER; count++) 10 printf("Be my Valentine!\n"); 11 12 return 0; 13 }
打印输出了22个“Be my Valentine!”
for循环的结构:for ( 初始化 ; 测试条件 ; 执行更新 )初始化只会执行一次,测试条件为假,循环结束

使用for循环创建一个立方表,打印整数1~6及其对应的立方
1 #include<stdio.h> 2 int main(void) 3 { 4 int num; 5 printf(" n n cubed\n");//cube立方,三次幂 6 for (num = 1; num <= 6; num++) 7 printf("%5d %5d\n", num, num * num * num); 8 9 return 0; 10 }
输出结果如下:

6.5.1利用for的灵活性
for ( 赋初值; 范围; 递增或递减)
1 #include<stdio.h> 2 int main(void) 3 { 4 int a; 5 for (a = 5; a > 0; a--) 6 printf("%d seconds!\n", a); 7 printf("We have ignition!");//我们点火了! 8 return 0; 9 }
//从A到Z依次输出ASCII的数字代表
1 #include<stdio.h> 2 int main(viod) 3 { 4 char ch; 5 for (ch = 'a'; ch <= 'z'; ch++) 6 printf("The ASCII value for %c is %d.\n", ch, ch); 7 return 0; 8 }
利用for循环从0开始依次递加5,当结果小于30后停止循环,如下:
1 #include<stdio.h> 2 int main(viod) 3 { 4 int n; 5 for (n = 0; n < 30; n = n + 5)//0也会打印出来 6 printf("%d\n",n); 7 return 0; 8 }
for循环可以省略一个或多个表达式(但是不能省略分号),只要在循环中包含能结束循环的语句即可,如下:
1 #include<stdio.h> 2 int main(viod) 3 { 4 int a, n; 5 a = 2; 6 for (n = 3; a <= 25;) 7 a = a * n; 8 printf("n=%d;a=%d.\n", n, a); 9 return 0; 10 }
第一个表达式不一定是给变量赋初值,也可以使用printf().在执行循环的其他部分之前,只对第1个表达式求值一次或执行一次,如下:
1 #include<stdio.h> 2 int main(void) 3 { 4 int num = 0; 5 for (printf("Keep entering numbers!\n"); num != 6;) 6 scanf_s("%d", &num); 7 printf("That's the one i want!\n"); 8 return 0; 9 }
6.6其他赋值运算符: +=、-+、*=、/=、%=
a += 20 与 a = a+2 相同
b -= 2 与 b = b-2 相同
c *= 2 与 c = c*2 相同
time /= 9 与 time = time/9 相同
reduce %= 3 与 reduce = reduce/3 相同
6.7逗号运算符
在for循环里面使用了逗号运算符,以便在循环头中包含更多的表达式。
1 #include<stdio.h> 2 int main(void) 3 { 4 const int a = 6; 5 const int b = 20; 6 int c, d; 7 printf(" c d\n"); 8 for (c = 1, d = a; c <= 16; c++, d += b) 9 printf("%5d $4.2f\n", c, d / 100.0); 10 11 return 0; 12 }
a=249,500;与a=249;500;效果相同
6.8出口条件循环:do while
while循环和for循环都是入口条件循环,即在循环的每次迭代之前检查测试条件,所以有可能根本不执行循环体中的内容。出口条件循环 do while 循环,即在循环的每次迭代之后检查测试条件,这保证了至少执行循环体中的内容一次。
下面即为 do while 循环示例:
1 #include<stdio.h> 2 int main(void) 3 { 4 const int secret_code = 13; 5 int code_entered; 6 do 7 { 8 printf("为了进入游戏的下一关,\n"); 9 printf("请输入两位数数字密码:\n"); 10 scanf_s("%d", &code_entered); 11 } while (code_entered != secret_code); 12 printf("恭喜你!破解了。\n"); 13 14 return 0; 15 }
6.9 如何选择循环
1、先确定是需要入口循环还是需要出口循环:入口循环用的多,因为:(1)、一般原则是在执行循环之前测试条件比较好。(2)、测试放在循环的开头,程序的可读性更高。
2、那么假设需要一个入口循环,是使用 while 还是 for 循环?一般,当循环涉及初始化和更新变量时,用 for循环比较合适,而在其他情况下用 while 比较好。
6.10 嵌套循环
嵌套循环指在一个循环内包含另一个循环。常用于按行和列显示数据,也就是说,一个循环处理一行中的所有列,另一个循环处理所有的行。示例如下:
1 #include<stdio.h> 2 #define ROWS 6 3 #define CHARS 10 4 int main(void) 5 { 6 int row; 7 int ch; 8 for (row = 0; row < ROWS; row++) 9 { 10 for (ch = 'A'; ch < ('A' + CHARS); ch++) 11 printf("%c", ch); 12 printf("\n"); 13 } 14 return 0; 15 }

分析:在外面的 for 循环称为外层循环,在里面的 for循环称为内层循环。内层循环执行完再进行外层循环的迭代。
6.11数组简介(在第十章会详细介绍数组)
1、数组是按顺序存储的一系列类型相同的值。整个数组有一个数组名,通过整数下标访问数组中单独的项或元素。
float debts[20]; 声明 debts 是一个内含20个元素的数组,每个元素都可以存储 float 的值。数组的第1个元素是 debts[0],第2个元素是 debts[1]....debts[19]。注意:数组元素的编号从0开始,不是从1开始。可以给每个元素赋 float 类型的值:
debts[5] = 32.14;
debts[9] = 11.22;
scanf_s(" %f ",&debts[4] ) //把一个值读入数组的第5个元素
陷阱:C编译器不会检查数组的下标是否正确,如:
debts[20] = 88.99; //该数组元素不存在
如果这样做,会导致程序中断或者破坏结果。
用于识别数组元素的数字被称为下标,下标必须是整数,且要从0开始计数。数组的元素被依次存储在内存中相邻的位置

6.11.1 在 for 循环中使用数组。示例如下:
1 #include<stdio.h> 2 int main(void) 3 { 4 int arr[5]; 5 int i; 6 7 for (i = 0; i < 5; i++){ 8 arr[i] = i + 1; 9 } 10 for (i = 0; i < 5; i++){ 11 printf("%d", arr[i]); 12 } 13 return 0; 14 }
输出:12345
本章完成!!!

浙公网安备 33010602011771号