while 循环
标准格式的伪代码:
获得第一个用于测试的值
当测试为真时
处理值
获取下一个值
精简版本的伪代码
当获取值和判断值都成功时
处理该值
通用形式
while(expression)
statement
expression:关系表达式,
为真执行starement一次,然后再次判断,
循环判断和执行,每次循环称为一次迭代,
为假时结束循环,执行循环后一条语句
statement:可以是分号结尾的简单语句,也可以是花括号括起来的复合语句
如果没有花括号,循环只会执行while后紧接着的第一句简单语句
如果while后紧跟;则循环是空语句,只执行expression
入口条件循环:入口条件满足时才会进循环,测试表达式的值要至少有一次为真,否则不会进入循环体
循环测试的值在测试前必须初始化
循环只有在对测试条件求值时才决定继续还是终止循环
测试表达式的值必须有变化,
表达式最终要为假,或者使用break和if,否则循环不会中止
long num; // 使用long存储更大的整数
long sum = 0L; /*把sum 初始化为0L(long类型的0)*/
int status;
printf("Please enter an integer to be summed ");
printf("(q to quit):");
status = scanf("%ld", &num);
/*键盘取值赋给num,
*scanf返回值赋给status,取值成功时返回取值个数,输入的不是数字时会读取失败返回0,任何非数值的数据都会导致循环终止
*在循环开始前获取并检查值*/
while (status == 1)
/*== 的意思是“等于”,判断status是否等于1,不为1时循环结束
也可以是while(scanf("ld", &num) == 1)*/
{ // 复合语句
sum = sum + num;
printf("Please enter next integer (q to quit): ");
status = scanf("%ld", &num); // 在循环内读取数据,才能为下一次循环做准备
}
printf("Those integers sum to %ld.\n", sum);
// int index;
// index = 1;
// while (index < 5) // 值不变,循环条件一直成立,无限循环
// printf("GOOD Morning\n"); // 简单语句
// index = 1;
// while (--index < 5) // 值变化,但不正确,只会在index减小到其类型可容纳的最小负值并变成最大正值时才会终止,最大正值加1一般会得到一个负值,最小负值减1一般会得到最大正值
// printf("GOOD Morning\n");
int n = 5;
while (n < 7)
{
printf("n=%d\n", n);
n++; // 当n加到7时并不会马上退出循环,会等到while处判断条件不成立时才会停止循环
printf("Now n = %d\n", n);
}
printf("The loop has finished.\n");
// int n = 0;
// while (n < 3)
// printf("n=%d\n", n); // 没有花括号时只执行到第一个分号结束,循环内并没有修改条件,无限循环
// n++;
// printf("That's all this program does\n");
n = 0;
while (n++ < 3);
/*只执行到第一个分号结束,即执行空语句,可以用于跳过某些条件,最好分号放在第二行便于看到是空语句
*在n<3时什么都不执行,n>3时执行下一步
while(scanf("%d",&num)==1); //跳过整数输入*/
printf("n=%d\n", n); //
printf("That's all this program does\n");
不确定循环和记数循环
不确定循环:在测试表达式为假之前,预先不知道执行多少次循环
记数循环:在执行循环之前就知道要重复执行多少次
const int NUMBER = 22;
int count = 1; // 初始化计数器
while (count <= NUMBER) // 测试,计数器和有限的值作比较
{
printf("Be my Valentine!\n"); // 行为
count++; // 更新计数器
}
do while循环
出口条件循环:循环每次迭代之后检查测试条件,保证至少执行循环体一次
通用形式:
do
statement //可以是简单语句或复合语句
while(expression); //以分号结尾
在expression变为假后也会执行statement 一次
const int secret_code = 13;
int code_entered;
do
{
printf("To enter thr triskaidekaphobia therapy club,\n");
printf("please enter the secret code number:");
scanf("%d", &code_entered);
} while (code_entered != secret_code);
printf("Congratulations! You are cured!\n");
// 与以下while程序等价
printf("To enter thr triskaidekaphobia therapy club,\n");
printf("please enter the secret code number:");
scanf("%d", &code_entered);
while (code_entered != secret_code)
{
printf("To enter thr triskaidekaphobia therapy club,\n");
printf("please enter the secret code number:");
scanf("%d", &code_entered);
}
printf("Congratulations! You are cured!\n");
for循环
入口条件循环,循环内条件不成立可能一次都不执行
for(获得初值; 值满足测试条件; 获得下一个值)
{
}
const int NUMBER = 22;
int count;
/*
*第一个表达式:初始化,只会在for循环开始时执行一次
第二个表达式:测试条件,在每次执行循环之前对表达式求值,为假时循环结束
第三个表达式:执行更新,在每次循环结束时求值
*/
for (count = 1; count <= NUMBER; count++)
printf("Be my Valentine!\n");
int num;
printf("n n cubed\n");
/*num的初值,num的终值和每次循环num的增量
*打印1-6的立方
*num终值为7,n==6时执行循环语句,执行结束num++,为7时不满足测试条件退出循环*/
for (num = 1; num <= 6; num++)
printf("%5d %5d\n", num, num * num * num);
int secs;
// 递减运算符递减计数器
for (secs = 5; secs > 0; secs--)
printf("%d seconds!\n", secs);
printf("We have ignition!\n");
int n;
// 从2开始,每次递增13
for (n = 2; n < 60; n = n + 13)
printf("%d \n", n);
char ch;
// 打印a-z的ASCII值,相当与整数记数
for (ch = 'a'; ch <= 'z'; ch++)
printf("The ASCII value for %c is %d.\n", ch, ch);
for (int num = 1; num * num * num <= 216; num++)
; // 测试条件可随需求变化
double debt;
// 几何增长,每次都乘以固定值
for (debt = 100.0; debt < 150.0; debt = debt * 1.1)
printf("Your debt is now %.2f.\n", debt);
int x;
int y = 55;
// 第三个表达式可以是任意合法的,每次迭代都更新值的表达式,3个表达式可以是不同的变量
for (x = 1; y <= 75; y = (++x * 5) + 50)
printf("%10d %10d\n", x, y);
int ans, cnt;
ans = 2;
// 每一个表达式都可省略,分号不可省略,循环必须能结束
for (cnt = 3; ans <= 25;)
ans = ans * cnt;
printf("n = %d;ans = %d.\n", cnt, ans);
// 第1个表达式可以是函数。执行循环之前只对第1个表达式求值一次或执行一次。
for (printf("Keep entering numbers!\n"); num != 6;)
scanf("%d", &num);
printf("That's right\n");
const int FIRST_OZ = 46; // 2013邮资
const int NEXT_OZ = 20; // 2013邮资
int ounces, cost;
printf(" ounces cost\n");
/*
* 初始化表达式的逗号是两个值都可进行初始化
* 更新表达式的初始化可使两个值每次迭代都变化
*/
for (ounces = 1, cost = FIRST_OZ; ounces <= 16; ounces++, cost += NEXT_OZ)
printf("%5d $%4.2f\n", ounces, cost / 100.0);
如何选择循环
入口条件循环
执行循环之前测试条件比较好
测试放在循环开头,提高程序可读性
一开始不满足条件时需要不执行循环
for
循环涉及 初始化和更新变量、涉及索引计数、已知迭代次数 比较合适
for(;test;) 和 while(test){} 效果相同
while
初始化;while(测试){其他语句;更新语句;}
和 for(初始化;测试;更新语句)效果相同
出口条件循环
至少需要执行一次
嵌套循环
在一个循环内包含另一个循环
常用于按行列显示数据
一个循环执行所有行,另一个循环执行所有列
const int ROWS = 6;
const int CHARS = 10;
int row;
char ch;
for (row = 0; row < ROWS; row++)
{ // 外层循环,0-6,每一次外层循环时都执行完所有的内层循环
for (ch = 'A'; ch < ('A' + CHARS); ch++) // 内层循环,'A'-'J'
printf("%c", ch);
printf("\n");
}
// 嵌套变式
for (row = 0; row < ROWS; row++)
{ // 每次外层循环时内层循环完成不同的任务
for (ch = ('A' + row); ch < ('A' + CHARS); ch++) // 内层循环开始字符取决于外层循环的迭代次数
printf("%c", ch);
printf("\n");
}
数组
在内存中相邻的按顺序存储的一系列相同类型的值
数组名[整数下标](索引、偏移量)访问数组中单独的元素
长度为n 的数组下标从0开始,n-1结束
数组可以是任意数据类型
#define SIZE 10 // 指定数组大小,便于设置循环边界和定义数组
// float debts[20];
// /* 声明debts 是一个内含20个元素的数组,每个元素都可以存储float类型的值
// debts[0],debts[1]...debts[19]结束, debts[20]下标越界*/
// debts[5] = 123.12; // 给数组指定元素赋相同类型的值
// scanf("%f", &debts[4]); // 把键盘输入的浮点数赋值给数组的第5个元素
// int nannies[22]; // 可存储22个int类型整数的数组
// char actors[26]; // 可存储25个字符的数组,末尾包含一个'\0',占一个位置,字符串
// long big[500]; // 可存储500个long类型整数的数组
// 在for循环中使用数组
int index, score[SIZE];
int sum = 0;
float average;
printf("Enter %d golf scores : \n", SIZE);
for (index = 0; index < SIZE; index++) // 处理一个大小为SIZE的数组,0-(size-1)
scanf("%d", &score[index]); // 读取10个分数,取数组元素地址:&数组名[下标]
printf("The scores read in are as follows : \n");
for (index = 0; index < SIZE; index++)
printf("%5d", score[index]); // 验证输入
printf("\n");
for (index = 0; index < SIZE; index++)
sum += score[index]; // 求总分数
average = (float)sum / SIZE; // 求总分数
printf("Sum of scores = %d,average = %8.2f\n", sum, average);
printf("That's a handicap of %.0f.\n", average - PAR);
// 3个for循环可以放在1个for循环里,注意模块化:程序不同的部分彼此独立
用函数返回值的循环
设计算法
在函数中设计算法并返回计算结果
测试函数
声明,定义,调用函数,return
#include <stdio.h>//包含输入输出的原型
double power(double n,int p);
/*函数原型,先声明再使用,未执行到定义之前需要使用的时候需要先声明
*声明一个名为power,返回double 类型,需要一个double和一个int类型参数的函数
*末尾有分号*/
// 驱动程序:设计用来测试函数的小程序
double x, xpow;
int exp;
printf("Enter a number and the positive integer power");
printf("to which\n the number will be raised.Enter q");
printf("to quit.\n");
while (scanf("%lf%d", &x, &exp) == 2)
{ // 每次读完2个参数后进行循环测试直到输入错误
xpow = power(x, exp);
/*函数调用,传参入函数,函数计算,返回计算结果,
*返回值可以赋值给变量,也可以是表达式中的值,作为另一个函数的参数*/
printf("%.3g to the power %d is %.5g\n", x, exp, xpow);
printf("Enter next pair of numbers or q to quit.\n");
}
printf("Hope you enjoyed this power trip --bye!\n");
double power(double n, int p) // 函数定义,末尾无分号,
{ // 传需要的参数:指定哪个数的多少次幂
double pow = 1;
int i;
for (i = 1; i <= p; i++)
{ // 预先知道循环次数用for循环
pow *= n;
}
return pow; // 返回计算结果,pow的值,也可以返回表达式的值 return 2*x+b;
}