C Primer Plus 第6章(C控制语句:循环)

1. while语句

while (expression)
{
	statement
}
  • statement 可以是分号结尾的简单句,也可以是花括号括起来的复合语句
  • expression 部分大多都使用关系表达式
  • 如果 expression 为真(非0),执行 statement 部分一次,然后再次判断 expression
  • 在 expreesion 为假(0)之前,循环的判断和执行一直重复进行
  • 每次循环都被称为一次迭代(iteration)

1.1 终止 while 循环

  • 在构建 while 循环时,必须让测试表达式的值有变化,表达式最终要为假
  • 否则,循环将不会终止

1.2 何时终止循环

  • 只有在对测试条件求值时,才决定是否终止循环

1.3 while:入口条件循环

  • while 循环是使用入口条件(entry condition)的有条件循环
  • 入口条件:满足条件才能进入循环体

1.4 语法要点

  • 只有在测试条件后面的单独语句(简单语句或复合语句)才是循环部分
int i = 0

while (i < 3)
    printf("%d", i);
	i++;
// 无限循环(infinite loop)

while (i++ < 5);
    printf("%d", i);
// 只会输出一次
// 测试条件后面的单独分号是空语句(null statement)

2. 用关系运算符和表达式比较大小

  • while 循环经常依赖测试表达式作比较,这样的表达式被称为关系表达式(relation expression),出现在关系表达式中间的运算符叫作关系运算符(relational operator)
运算符含义
<小于
>大于
<=小于等于
>=大于等于
==等于
!=不等于
  • 关系运算符比较字符时,比较的是机器字符码(ANSII)
  • 不能用关系运算符比较字符串

2.1 什么是真

  • 表达式为真的值是 1
  • 表达式为假的值是 0
int i;
int j;

i = (3 > 2);
j = (3 < 2);

printf("true = %d, flase = %d\n", i, j);
// true = 1, flase = 0

2.2 其它真值

  • 所有的非零值都视为真
  • 只有0被视为假
int i = 5;

while (i)
{
    printf("%d\n", i);
    i--;
}

2.3 真值的问题

  • 不要错用 ==(等于)和 =(赋值)
  • 关系运算符用于构成关系表达式
  • 关系表达式为真时值为1,为假时值为0
  • 通常用关系表达式作为测试条件的语句(while 和 if)可以使用任何表达式作为测试条件,非0为真,0为假

2.4 新的 _Bool 类型

  • C99 针对布尔变量(Boolean variable)新增了 _Bool 类型
  • _Bool 类型的变量只能存储 1(真)或 0(假)
  • 如果把其他非0数值赋值给 _Bool 类型的变量,该变量会被设置为1
  • C99 提供了 stdbool.h 头文件,该头文件让 bool 成为 _Bool的别名,把 true 和 false 分别定义为 1 和 0 的符号常量

2.5 优先级和关系运算符

运算符(优先级从高到低)结合律
()从左往右
-,+,++,–,sizeof从右往左
*,/,%从左往右
+,-从左往右
<,>,<=,>=从左往右
==,!=从左往右
=从右往左

3. 不确定循环和计数循环

  • 不确定循环(indefinite loop):在测试表达式为假之前,预先不知道要执行多少次循环
  • 计数循环(counting loop):在执行循环之前知道要重复执行多少次

4. for 循环

  • for 循环将初始化、测试和更新,3个行为组合在一起
for(初始化; 测试条件; 执行更新)
{
    简单句 / 复合句
}
  • 初始化:只会在 for 循环开始时执行一次

  • 测试条件:在执行循环之前对表达式求值;如果表达式为假,循环结束

  • 执行更新:每次循环结束时求值

  • 括号中的表达式也叫做控制表达式

4.1 利用 for 的灵活性

  • 使用递减运算符来递减计数器
for (int i = 5; i > 0; i--)
{
    printf("%d\n", i);
}
  • 让计数器递增
for (int i = 2; i < 10; i += 2)
{
    printf("%d\n", i);
}
  • 用字符代替数字计数
for (char c = 'a'; c < 'z'; c++)
{
    printf("c = %c = %d\n", c, c);
}
  • 测试其他条件
for (int i = 2; i * i < 10; i++)
{
    printf("%d\n", i);
}
  • 递增的量成几何增长
for (int i = 2; i < 10; i *= 2)
{
    printf("%d\n", i);
}
  • 执行更新,使用任意合法的表达式
int j = 0;

for (int i = 2; i < 10; j = (++i) * 2)
{
    printf("i = %d, j = %d\n", i, j);
}
  • 省略一个或多个表达式(不能省略分号)
for (int i = 2; i < 10;)
{
    printf("%d\n", i);
    i++;
}
  • 初始化,使用printf()
int i = 0;

for (printf("keep enter"); i != 6;)
{
    scanf("%d", &i);
}
  • 循环体中的行为可以改变循环头中的表达式
int j = 0;

for (int i = 1; i < 10; i = i + j)
{
    j = i;
    printf("i = %d, j = %d\n", i, j);
}

5. 其他赋值运算符:+=、-=、*=、/=、%=

运算符含义
+=i += 1 等同于 i = i + 1
-=i -= 1 等同于 i = i - 1
*=i *= 1 等同于 i = i * 1
/=i /= 1 等同于 i = i / 1
%=i %= 1 等同于 i = i % 1

6. 逗号运算符

  • 扩展 for 循环的灵活性,以便在循环头中包含更多的表达式
int i = 0;
int j = 0;

for (i = 1, j = 1; i <= 9; i++, j = 1)
{
    while (j <= i) {
        printf("%d * %d = %2d   ", i, j, i * j);
        j++;
    }
    printf("\n");
}
  • 逗号运算符并不局限于在 for 循环中使用,但是这是它最常用的地方

  • 逗号运算符的两个其他性质

    • 保证了被它分隔的表达式从左往右求值(逗号是一个序列点,所以逗号左侧项的所有副作用都在程序执行逗号右侧项之前发生)

    • 整个逗号表达式的值是右侧项的值

      #include <stdio.h>
      
      int main() {
      
          int i = 0;
          int j = 0;
      
          i = 200, 500;
          printf("i = %d\n", i);
          // i = 200
      
          j = (200, 500);
          printf("j = %d\n", j);
          // j = 500
      }
      

7. 出口条件循环:do while

  • 出口条件循环(exit-condition loop):在循环的每次迭代之后检查测试条件,保证了至少执行循环体中的内容一次
do
    statement
while (expression);
  • statement 可以是一条简单语句或复合语句
  • do while 循环在执行完循环体后才执行测试条件,至少执行循环体一次

8. 如何选择循环

  • 确定使用入口条件循环还是出口条件循环
  • 入口条件循环使用次数较多
    • 一般原则是在执行循环之前测试条件比较好
    • 测试放在循环的开头,程序的可读性更高
    • 在许多应用中,要求在一开始不满足测试条件时就直接跳过整个循环
  • 当循环涉及初始化和更新变量时,用 for 循环比较合适
  • 在其他情况下用 while 循环更好

9. 嵌套循环

  • 嵌套循环(nested loop)指在一个循环内包含另一个循环
  • 嵌套循环常用于按行和列显示数据,一个循环处理一行中的所有列,另一个循环处理所有的行
for (int i = 9; i >= 1; i--) // 外层循环(outer loop)
{
    for (int j = 1; j <= i; j++) // 内层循环(inner loop)
    {
        printf("%d * %d = %2d ", j, i, i * j);
    }
    printf("\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值