C-study(六)

本文介绍了编程中的关系运算符,如比较浮点数时避免舍入误差的策略。详细讲解了while、for和do...while循环的使用,包括循环条件的设定和跳出机制。同时,提到了数组的概念和在循环中的应用。
摘要由CSDN通过智能技术生成

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值