for循环
for格式除了看上去很像while,更像是进阶版的while循环
说是功能等价while循环,倒不如说for循环是计数循环,当你设定一个计数器,初始化数值,在数值到达你设定的某个值之前,不断循环执行循环体内的表达式,而每循环一轮,计数器数值都会按你的设定进行调整
通俗易懂一点就是:对于一开始的初始化条件,每当循环条件成立时,重复循环体内的语句,每轮执行完循环体后,执行每轮的动作,调整计数器的数值
当掌握这三种循环语句后,如何选择它们倒是成了个问题
- 如果有固定次数,使用for
- 如果必须执行一次用do_while
- 其他情况才用while
for循环格式
每个表达式都是可以省略的
for ( ;循环条件; ) == while ( 循环条件 )
1 | for ( 初始化条件; 循环条件; 每轮的动作 ){ |
代码示例
阶乘
所谓阶乘就是
n!
,其结果是1*2*3*4*5*...*n
使用代码实现这一过程,让用户输入n的值,然后计算出n!的结果
(需要注意的是,在做求和的程序时,初始化变量为0,而在做求积的变量时,初始化变量应该为1)
首先使用while来实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22/*
* 定义变量n,i,fact
* n的值是用户自行输入的
* i不断的从1递增到n
* fact保存计算结果
* 当i小于或等于用户输入值n后结束循环
* 循环体内fact的值就是1*2*3*...*n的算法
* 每循环一次i++*/
int main() {
int n;
int fact = 1 ;
int i = 1;
scanf("%d", &n);
while ( i <= n ){
fact *= i;
i ++;
}
printf("%d!=%d", n, fact);
return 0;
}我们改成for循环
循环控制变量i只在for循环表达式中被使用,所以能将定义变量i写在for循环中,但要注意的是,在初始化条件处定义变量只有C99才能使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20/*
* 定义变量n,fact
* n的值是用户自行输入的
* fact保存计算结果
* 定义变量i并初始化
* 当i小于或等于n时进入循环体
* 每进行一轮循环让i++
* 直到循环条件不满足i小于或等于n*/
int main() {
int n;
int fact = 1 ;
scanf("%d", &n);
for ( int i = 2; i <= n; i++ ) {
fact *= i;
}
printf("%d!=%d", n, fact);
return 0;
}换个思路想,如果从n乘到1还能实现该功能吗?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/* 一:
* 定义变量n,i,fact
* n的值是用户自行输入的
* i的值保存用户输入的n
* fact保存计算结果
* 循环体内fact的值就是n*n-1...的算法
* 每循环一次n--
* 当n的值小于或等于1就结束循环*/
int main() {
int n;
int fact = 1 ;
scanf("%d", &n);
int i = n;
for ( ; n > 1; n--) {
fact *= n;
}
printf("%d!=%d", i, fact);
return 0;
}素数
- 当用户输入一个数时,判断其是否为素数
仅输出1到100范围内的前20个素数
所谓素数即只能被1或自己整除的数,例如
2,3,5,7,11,13,17,19...
1在狭义的范围中不算是素数,所以在此不列举1为素数
break的作用是跳出整个循环,另一个其他的用法是continue,但是它的意义只是跳过后续的循环体,回到for循环开头
||意为或者,用于多个条件判断时,只要满足其一即true,任一条件不满足即false
&&意为且,用于多个条件判断时,当所有条件同时满足时即true,否则false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61/*
* 定义用户输入变量x
* 定义判断条件变量isPrime
* 定义并初始化i的值为2
* 当i的值小于用户输入x时进行循环判断
* 每当循环结束就让i的值自增
* i < x 可以理解成i的值永远都是x - 1
* 如果x余i的值为0的话就将isPrime的值变成0
* 并跳出整个循环
* 判断isPrime的值是1还是0
* 如果为0或者x为1,就输出不是素数
* 否则输出是素数*/
int main() {
int x;
int isPrime = 1;
scanf("%d", &x);
for (int i = 2; i < x; i++) {
if (x % i == 0) {
isPrime = 0;
break;
}
}
if (isPrime == 0 || x == 1) {
printf("%d不是素数", x);
} else {
printf("%d是素数", x);
}
printf("\n\n在100以内的前50个素数有:\n");
secondary();
return 0;
}
/*
* 定义变量x,使用循环实现x的值是从1到100
* 定义变量time,限制time为20
* 定义变量isPrime,用于记录是否为素数
* 定义变量i,用于判断是否为素数
* 初始化x的值为1,初始化计数器time为0
* 在1到100中当计数器小于20时,执行循环体内的语句
* 每当有一个素数产生时,让计数器的数+1
* 每五个素数换行显示,并让所有数都对齐*/
int secondary() {
for (int x = 1, time = 0; x <= 100 && time < 20; x++) {
int isPrime = 1;
for (int i = 2; i < x; i++) {
if (x % i == 0) {
isPrime = 0;
}
}
if (isPrime == 1 && x != 1) {
time++;
printf("%d\t", x);
if (time % 5 == 0) {
printf("\n");
}
}
}
return 0;
}
枚举硬币
用1角,2角,五角的硬币凑出10元以下的金额
我看到这题愣了半天没想明白应该怎么实现,无奈看完整个视频才缕清思路
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25/*
* 变量x为用户输入值
* one为一角,two为二角,five为五角
* one至多循环x*10-1次,two至多循环x*10\2-1次,five至多循环x*10/5-1次
* 当循环的过程中,满足了one+two*2+five*5等于x*10
* 就输出结果,否则就继续循环
* goto可以指定跳转到任意处*/
int main() {
int x;
scanf("%d", &x);
for (int one = 1; one < x * 10; one++) {
for (int two = 1; two < x * 10 / 2; two++) {
for (int five = 1; five < x * 10 / 5; five++) {
if (one + two * 2 + five * 5 == x * 10) {
printf("%d个1角加%d个2角加%d个5角可以得到%d元", one, two, five, x);
goto exit;
}
}
}
}
exit:
return 0;
}f(n)
f(n) = 1+1/2+1/3+1/4+…+1/n
计算出1/1~1/n所有数的和
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/*
* 定义整型变量n,用户输入值
* 定义浮点变量sum。求和记录数
* 定义整型变量x,循环计数器
* 当x小于等于用户输入数时,x的值从1开始
* sum的值等于sum加上1/x
* 每轮循环结束x的值都会加1*/
int main() {
int n;
scanf("%d", &n);
double sum = 0.0;
for (int x = 1; x <= n ; x++) {
sum += 1.0 / x ;
}
printf("f(%d)=%f", n, sum);
return 0;
}如果f(n)=1-1/2+1/3-1/4+1/5…+1/n呢?
实现方式也很简单的,只需要定义一个浮点类型的变量,初始值等于1,当每次循环结束前,将这个浮点类型的变量变成负数,修改分母为这个变量即可
1
2
3double z = 1.0;
sum += z / x;
z = -z;