“知道做不到就是不知道”
一、条件循环
1. while
只要条件为真(true
),就会重复执行循环体内的代码。
while (条件) {// 循环体(要重复执行的代码)
}//示例
int i = 1;
while (i <= 5) {printf("%d\n", i);i++; // 让 i 递增,否则会无限循环
}输出:
1
2
3
4
5
(1)检查
条件
是否为真(true
)。(2)如果为真,执行循环体代码。
(3)再次检查
条件
,重复上述过程。(4)如果
条件
为假(false
),退出循环。
2. do-while
do-while在进入循环的时候不做检查,而是执行完一轮循环体的代码之后,再来检查循环的条件是否满足,如果满足,则继续执行下一轮;不满足,则结束循环。
do
{//循环体语句
}while(条件);
注意事项:
(1)不要忘记在while条件最后的分号!!
(2)while和do-while循环的区别就在于前者是先判断条件再执行语句;后者是先执行1次语句,再判断条件。
(3)对比判断条件:if是一次性的,while是反复多次的。
(4)要求在循环体内有结束循环的机会,否则就会进入死循环。
3. 示例1-猜数游戏
让计算机随机产生一个数,然后让用户来猜。用户每输入一个数字,就告诉用户是输大了,还是输小了,直到用户猜中为止,最后再输出计算机一共猜了多少次。
分析:可以知道,只要用户输入的数字a和计算机随机生成的数字不相等,循环就应该继续执行下去,所以a与随机数相等就是循环的停止条件。
补充:每次使用rand()函数就得到一个随机的整数。计算机随机生成的数一般都比较大,为了获取两位整数,可以将数据在输出的时候对100取余。a%n(得到的结果是0~n-1)
printf("猜数字游戏(1-100)开始!\n");while (1) {printf("请输入你的猜测:");scanf("%d", &guess);attempts++;if (guess > target) {printf("太大了!\n");} else if (guess < target) {printf("太小了!\n");} else {printf("恭喜你猜中了!数字是 %d。\n", target);printf("你一共猜了 %d 次。\n", attempts);break;}
}return 0;
4. 示例2-整数逆序
基本的方法:先对10取余,得到个位数,再除以10,去掉个位数;按此方法,再得到十位数、百位数……
(1)要在写程序之前就确定好需要哪些变量;
(2)不同的题目有不一样的要求,700对应的是007还是7,其表达的意思都是不一样的,但是前者就算使用printf(不换行)也是可以做到的;后者有个十百千……位具体的要求,需要乘以相应的倍数。
#include <stdio.h>int main() {//不保留前导零,计算数值int num, reversed = 0;printf("请输入一个最多三位数的整数:");scanf("%d", &num);// 使用 while 循环计算逆序while (num > 0) {reversed = reversed * 10 + num % 10;num /= 10;}printf("逆序结果:%d\n", reversed);return 0;
}输出:
输入:700
输出:7 // 因为 007 和 7 数值相同
二、for循环
for(初始动作(1);条件(2);每轮的动作(3))
{//语句块(4)
}
1. 在条件为真的情况下,执行的顺序是(1)-(2)-(4)-(3);如果不满足条件(2),就直接停止;如果满足条件(2),则一定会执行(4)、(3)
2. (1)和(3)可以分别放到for语句的前后,在括号中省略,此时相当于while语句。
初始动作(1)for( ;条件(2); )
{//语句块(4)
}每轮的动作(3)
理解:for循环就像一个计数循环:设定一个计数器,初始化,然后在计数器达到某值之前,重复执行循环体,而每执行一轮循环,计数器值以一定的步进进行调整:++或者--
3. 注意事项
(1)求和的程序初始值设为0;求积的程序初始值设为1。
(2)循环控制变量只在循环里面被用到了,在循环外面是无法访问的,因此可以把该变量的定义直接写在for语句中去。
(3)通过控制for语句后面的条件,可以控制语句能否进入到循环中,进而简化运算。比如说for(int i = 1;i<=i,i*i),这个语句就根本没有意义,就可以改变判断条件,让过程跳过该语句。
4. 循环的选择
(1)次数:i=0;i<5;i++ 相当于 i=1;i<=5;i++ 初始值和条件判断是互相关联的!!
(2)选择方法
a)如果有固定的次数——for
b)如果无论如何必须要执行一次——do-while
c)其他情况——while
三、循环嵌套
1. 嵌套的循环
(1)外层循环控制行数,内层循环实行具体的语句(计算、空格…)
注意:
(1)每一层循环里面的计数变量应该是有区别的
(2)注意在for循环里面声明的变量,不一定非要出现在条件语句里面,只要能够控制循环的结束即可
(2)具体案例(右侧图案)
#include <stdio.h>int main() {int rows = 4; // 金字塔的行数for (int i = 0; i < rows; i++) {// 打印前导空格(用于居中)for (int space = 0; space < rows - i - 1; space++) {printf(" ");}// 打印左半部分(递减字母)for (int j = i; j >= 0; j--) {printf("%c ", 'A' + j);}// 打印右半部分(递增字母,从第二个字母开始)for (int j = 1; j <= i; j++) {printf("%c ", 'A' + j);}printf("\n");}return 0;
}输出:A B A B C B A B C
D C B A B C D
(3)提高程序效率的方法
a)在满足题目条件的情况下,在for循环中,用“break”提前结束程序的循环部分;
b)利用if语句的特点,用0和非0来标志是否进入循环以及“返回值”。
2. 跳出嵌套训循环
案例-凑硬币:如何用1/2/5角的硬币凑出10元以下的金额?
(1)接力break(传统教材方式):因为break和continue只能控制最近的循环,所以单纯地把break放在想要结束的语句后面是行不通的。故同样需要一个变量来记录语句的成功和失败。1表示成功;0表示失败。在判断语句中给变量重新赋值,之后想要结束循环的时候就可以直接“if(exit==1) break;”
(2)“goto语句”:离开所有的循环!!跳到最外面去!!最好只是在有多重嵌套的环境下使用。很多人认为这个“goto”破坏了程序的结构性!!
四、其他“碎碎念”
- 进入循环之前尽可能的保留一份原有数据,输出的时候可能会用到(新定义一个变量用于存储);
- 循环条件决定了能不能进入循环体 : x>2?x>=2?
- 预先设定的用于计数的变量和循环进入的条件是互相影响的,要考虑能不能进,计数次数是多了还是少了,要实践。刚开始的时候可以用表格/手写的方式分析;
- 自加、自减,要注意放在语句中的位置!(会影响循环的开始和结束)
- 循环控制
- break:跳出最近的循环
- continue:跳过最近的循环内部剩余的语句,到达该次循环的最后,再进入下一轮的循环(或者开始外部代码)!
6. 不借用第三个变量实现数值交换
//用其中一个变量保存和,可以作差互相计算int i=3;j=5;j=i+j; //j=3+5=8
i=j-i; //i=8-3=5
j=j-i; //j=8-5=3
写在最后:
更新C语言学习笔记
如有错误,烦请多多批评指正!