C语言语法入门-程序的循环控制
9unk Lv5

Do语句

C语言中提供了 3 中循环执行程序语句。这里首先学习 do 语句。

do 语句

输入一个整数,显示出它是奇数还是偶数。然后询问是否重复同样的操作,并按照要求进行处理。

代码清单4-1

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
/*程序名:list0401.c*/
/*
输入的整数是奇数还是偶数(按照自己的意愿进行循环操作)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int retry;

do
{
int no;

printf("请输入一个整数:");
scanf("%d", &no);

if (no % 2)
puts("这个整数是奇数。");
else
puts("这个整数是偶数。");

printf("要重复执行一次吗? 【yes...0/No...9】:");
scanf("%d", &retry);
} while (retry == 0);

return 0;
}

1

反汇编

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
62
//do 
//{
///int no;

//printf("请输入一个整数:");
0061528F 68 28 7E 61 00 push 617E28h
00615294 E8 13 C1 FF FF call 006113AC
00615299 83 C4 04 add esp,4

//scanf("%d", &no);
0061529C 8D 45 E8 lea eax,[ebp-18h]
0061529F 50 push eax
006152A0 68 30 7B 61 00 push 617B30h
006152A5 E8 48 C1 FF FF call 006113F2
006152AA 83 C4 08 add esp,8

//if (no % 2)
006152AD 8B 45 E8 mov eax,dword ptr [ebp-18h]
006152B0 25 01 00 00 80 and eax,80000001h
006152B5 79 05 jns 006152BC
006152B7 48 dec eax
006152B8 83 C8 FE or eax,0FFFFFFFEh
006152BB 40 inc eax
006152BC 85 C0 test eax,eax
006152BE 74 19 je 006152D9

//puts("这个整数是奇数。");
006152C0 8B F4 mov esi,esp
006152C2 68 F0 7C 61 00 push 617CF0h
006152C7 FF 15 70 B1 61 00 call dword ptr ds:[0061B170h]
006152CD 83 C4 04 add esp,4
006152D0 3B F4 cmp esi,esp
006152D2 E8 59 BF FF FF call 00611230
006152D7 EB 17 jmp 006152F0

//else
//puts("这个整数是偶数。");
006152D9 8B F4 mov esi,esp
006152DB 68 48 7E 61 00 push 617E48h
006152E0 FF 15 70 B1 61 00 call dword ptr ds:[0061B170h]
006152E6 83 C4 04 add esp,4
006152E9 3B F4 cmp esi,esp
006152EB E8 40 BF FF FF call 00611230

//printf("要重复执行一次吗? 【yes...0/No...9】:");
006152F0 68 B0 85 61 00 push 6185B0h
006152F5 E8 B2 C0 FF FF call 006113AC
006152FA 83 C4 04 add esp,4

//scanf("%d", &retry);
006152FD 8D 45 F4 lea eax,[ebp-0Ch]
00615300 50 push eax
00615301 68 30 7B 61 00 push 617B30h
00615306 E8 E7 C0 FF FF call 006113F2
0061530B 83 C4 08 add esp,8

//} while (retry == 0);
0061530E 83 7D F4 00 cmp dword ptr [ebp-0Ch],0
00615312 0F 84 77 FF FF FF je 0061528F

//return 0;
00615318 33 C0 xor eax,eax

do…while 语句架构

1
2
3
4
do: 
循环体
cmp xxx
jCC do

复合语句(程序块)中的声明

使用 do 语句的话,从键盘读取的数值是有限制的。

代码清单4-2

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
/*程序名:list0402.c*/
/*
根据读取的整数值显示所处的拳(只接收0、1、2)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int hand;

do
{
printf("请选择出什么拳[0...石头/1...剪刀/2...布]:");
scanf("%d", &hand);
} while (hand < 0 || hand>2);

printf("你选择了");
switch (hand)
{
case 0: printf("石头。\n"); break;
case 1: printf("剪刀。\n"); break;
case 2: printf("布。\n"); break;
}

return 0;
}

2

反汇编

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
	//do
//{
//printf("请选择出什么拳[0...石头/1...剪刀/2...布]:");
002B528F 68 10 86 2B 00 push 2B8610h
002B5294 E8 13 C1 FF FF call 002B13AC
002B5299 83 C4 04 add esp,4
//scanf("%d", &hand);
002B529C 8D 45 F4 lea eax,[ebp-0Ch]
002B529F 50 push eax
002B52A0 68 30 7B 2B 00 push 2B7B30h
002B52A5 E8 48 C1 FF FF call 002B13F2
002B52AA 83 C4 08 add esp,8
//} while (hand < 0 || hand>2);
002B52AD 83 7D F4 00 cmp dword ptr [ebp-0Ch],0
002B52B1 7C DC jl 002B528F
002B52B3 83 7D F4 02 cmp dword ptr [ebp-0Ch],2
002B52B7 7F D6 jg 002B528F

//printf("你选择了");
002B52B9 68 F0 7C 2B 00 push 2B7CF0h
002B52BE E8 E9 C0 FF FF call 002B13AC
002B52C3 83 C4 04 add esp,4

//switch (hand)
002B52C6 8B 45 F4 mov eax,dword ptr [ebp-0Ch]
002B52C9 89 85 2C FF FF FF mov dword ptr [ebp+FFFFFF2Ch],eax
002B52CF 83 BD 2C FF FF FF 00 cmp dword ptr [ebp+FFFFFF2Ch],0
002B52D6 74 14 je 002B52EC
002B52D8 83 BD 2C FF FF FF 01 cmp dword ptr [ebp+FFFFFF2Ch],1
002B52DF 74 1A je 002B52FB
002B52E1 83 BD 2C FF FF FF 02 cmp dword ptr [ebp+FFFFFF2Ch],2
002B52E8 74 20 je 002B530A
002B52EA EB 2B jmp 002B5317
//{
//case 0: printf("石头。\n"); break;
002B52EC 68 48 7E 2B 00 push 2B7E48h
002B52F1 E8 B6 C0 FF FF call 002B13AC
002B52F6 83 C4 04 add esp,4
002B52F9 EB 1C jmp 002B5317
//case 1: printf("剪刀。\n"); break;
002B52FB 68 B0 85 2B 00 push 2B85B0h
002B5300 E8 A7 C0 FF FF call 002B13AC
002B5305 83 C4 04 add esp,4
002B5308 EB 0D jmp 002B5317
//case 2: printf("布。\n"); break;
002B530A 68 34 7B 2B 00 push 2B7B34h
002B530F E8 98 C0 FF FF call 002B13AC
002B5314 83 C4 04 add esp,4
//}

//return 0;
002B5317 33 C0 xor eax,eax

逻辑非运算符.德摩根定律

3

德摩根定律

4

求多个整数的和及平均值

不停地输入整数,显示其和及平均值。

代码清单4-3

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
/*程序名:list0403.c*/
/*
不停地输入整数,显示其和及平均值。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int sum = 0;
int cnt = 0;
int retry;

do
{
int t;
printf("请输入一个整数:");
scanf("%d", &t);
sum = sum + t;
cnt = cnt + 1;

printf("是否继续? <Yes...0/No...9>:");
scanf("%d", &retry);
} while (retry == 0);

printf("和为%d,平均值为%.2f。\n", sum, (double)sum / cnt);

return 0;
}

反汇编

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
//do
//{
//int t;
//printf("请输入一个整数:");
00F4529D 68 10 86 F4 00 push 0F48610h
00F452A2 E8 05 C1 FF FF call 00F413AC
00F452A7 83 C4 04 add esp,4
//scanf("%d", &t);
00F452AA 8D 45 D0 lea eax,[ebp-30h]
00F452AD 50 push eax
00F452AE 68 30 7B F4 00 push 0F47B30h
00F452B3 E8 3A C1 FF FF call 00F413F2
00F452B8 83 C4 08 add esp,8
//sum = sum + t;
00F452BB 8B 45 F4 mov eax,dword ptr [ebp-0Ch]
00F452BE 03 45 D0 add eax,dword ptr [ebp-30h]
00F452C1 89 45 F4 mov dword ptr [ebp-0Ch],eax
//cnt = cnt + 1;
00F452C4 8B 45 E8 mov eax,dword ptr [ebp-18h]
00F452C7 83 C0 01 add eax,1
00F452CA 89 45 E8 mov dword ptr [ebp-18h],eax

//printf("是否继续? <Yes...0/No...9>:");
00F452CD 68 D8 7B F4 00 push 0F47BD8h
00F452D2 E8 D5 C0 FF FF call 00F413AC
00F452D7 83 C4 04 add esp,4
//scanf("%d", &retry);
00F452DA 8D 45 DC lea eax,[ebp-24h]
00F452DD 50 push eax
00F452DE 68 30 7B F4 00 push 0F47B30h
00F452E3 E8 0A C1 FF FF call 00F413F2
00F452E8 83 C4 08 add esp,8
//} while (retry == 0);
00F452EB 83 7D DC 00 cmp dword ptr [ebp-24h],0
00F452EF 74 AC je 00F4529D

//printf("和为%d,平均值为%.2f。\n", sum, (double)sum / cnt);
00F452F1 F2 0F 2A 45 F4 cvtsi2sd xmm0,dword ptr [ebp-0Ch]
00F452F6 F2 0F 2A 4D E8 cvtsi2sd xmm1,dword ptr [ebp-18h]
00F452FB F2 0F 5E C1 divsd xmm0,xmm1
00F452FF 83 EC 08 sub esp,8
00F45302 F2 0F 11 04 24 movsd mmword ptr [esp],xmm0
00F45307 8B 45 F4 mov eax,dword ptr [ebp-0Ch]
00F4530A 50 push eax
00F4530B 68 48 7E F4 00 push 0F47E48h
00F45310 E8 97 C0 FF FF call 00F413AC
00F45315 83 C4 10 add esp,10h

//return 0;
00F45318 33 C0 xor eax,eax

复合赋值运算

5

代码清单4-4

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
/*程序名:list0404.c*/
/*
不停地输入整数,显示其和及平均值。(其2)
使用复合赋值运算和后置递增运算符
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int sum = 0;
int cnt = 0;
int retry;

do
{
int t;
printf("请输入一个整数:");
scanf("%d", &t);
sum += t;
++cnt;

printf("是否继续? <Yes...0/No...9>:");
scanf("%d", &retry);
} while (retry == 0);

printf("和为%d,平均值为%.2f。\n", sum, (double)sum / cnt);

return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
//sum += t;
004052BB 8B 45 F4 mov eax,dword ptr [sum]
004052BE 03 45 D0 add eax,dword ptr [ebp-30h]
004052C1 89 45 F4 mov dword ptr [sum],eax

//cnt ++;
004052C4 8B 45 E8 mov eax,dword ptr [cnt]
004052C7 83 C0 01 add eax,1
004052CA 89 45 E8 mov dword ptr [cnt],eax
1
2
3
4
5
6
7
8
9
//sum += t;
000A52BB 8B 45 F4 mov eax,dword ptr [sum]
000A52BE 03 45 D0 add eax,dword ptr [ebp-30h]
000A52C1 89 45 F4 mov dword ptr [sum],eax

//++cnt;
000A52C4 8B 45 E8 mov eax,dword ptr [cnt]
000A52C7 83 C0 01 add eax,1
000A52CA 89 45 E8 mov dword ptr [cnt],eax

在 do…while 循环体中,++cnt 和 cnt++的反汇编没有区别。

While 语句

与 do 语句不同,在循环体执行之前对循环的继续执行条件进行判断的是 while 语句。

while 语句

输入一个整数值,显示出从它开始递减到0的每一个整数的程序。

代码清单4-5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*程序名:list0405.c*/
/*
从输入的0整数开始倒数到0
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int no;
printf("请输入一个正整数:");
scanf("%d", &no);

while (no >= 0)
{
printf("%d\n", no);
no--;
}

return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while (no >= 0)
006952AD 83 7D F4 00 cmp dword ptr [no],0
006952B1 7C 1C jl __$EncStackInitStart+63h (06952CFh)
{
printf("%d\n", no);
006952B3 8B 45 F4 mov eax,dword ptr [no]
006952B6 50 push eax
006952B7 68 34 7B 69 00 push offset string "%d\n" (0697B34h)
006952BC E8 EB C0 FF FF call _printf (06913ACh)
006952C1 83 C4 08 add esp,8
no--;
006952C4 8B 45 F4 mov eax,dword ptr [no]
006952C7 83 E8 01 sub eax,1
006952CA 89 45 F4 mov dword ptr [no],eax
}
006952CD EB DE jmp __$EncStackInitStart+41h (06952ADh)

循环体中 no–和–no

1
2
3
4
//no--;
00E852C4 8B 45 F4 mov eax,dword ptr [no]
00E852C7 83 E8 01 sub eax,1
00E852CA 89 45 F4 mov dword ptr [no],eax
1
2
3
4
//--no;
008D52C4 8B 45 F4 mov eax,dword ptr [no]
008D52C7 83 E8 01 sub eax,1
008D52CA 89 45 F4 mov dword ptr [no],eax

while 循环体中 no-- 和 --no 没有区别。

while 语句反汇编架构

1
2
3
4
5
6
7
start:
cmp xxx
JCC end
循环体
jmp start
end:
xxx

使用递减运算符简化程序代码

下面灵活使用后置递减运算符的特性进一步简化到计数的程序。

代码清单4-6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*程序名:list0406.c*/
/*
从输入的0整数开始倒数到0(其2)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int no;
printf("请输入一个正整数:");
scanf("%d", &no);

while (no >= 0)
{
printf("%d\n", no--);
}

return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//printf("%d\n", no--);
00F252B3 8B 45 F4 mov eax,dword ptr [no]
// 局部变量 no 备份到 [ebp-xxx] 中
00F252B6 89 85 2C FF FF FF mov dword ptr [ebp-0D4h],eax
//局部变量 no=no-1
00F252BC 8B 4D F4 mov ecx,dword ptr [no]
00F252BF 83 E9 01 sub ecx,1
00F252C2 89 4D F4 mov dword ptr [no],ecx
//将之前备份的值压入堆栈
00F252C5 8B 95 2C FF FF FF mov edx,dword ptr [ebp-0D4h]
00F252CB 52 push edx
00F252CC 68 34 7B F2 00 push offset string "%d\n" (0F27B34h)
00F252D1 E8 D6 C0 FF FF call _printf (0F213ACh)
00F252D6 83 C4 08 add esp,8
1
2
3
4
5
6
7
8
9
//printf("%d\n", --no);
000452B3 8B 45 F4 mov eax,dword ptr [no]
000452B6 83 E8 01 sub eax,1
000452B9 89 45 F4 mov dword ptr [no],eax
000452BC 8B 4D F4 mov ecx,dword ptr [no]
000452BF 51 push ecx
000452C0 68 34 7B 04 00 push offset string "%d\n" (047B34h)
000452C5 E8 E2 C0 FF FF call _printf (0413ACh)
000452CA 83 C4 08 add esp,8

在printf函数中 no-- 和 --no 操作就不一样了。
no–:先将当前变量 no 的值做备份x,然后再将no值-1,最后将备份值 x 压入堆栈。
–no:表示直接将no的值减一,并压入堆栈中。

数据递增

这次编写一段跟之前相反的程序,显示出从0开始递增到输入的整数的各个整数。

代码清单4-7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:list0407.c*/
/*
递增显示从0到输入的整数为止的各个整数。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i,no;

printf("请输入一个正整数:");
scanf("%d", &no);

i = 0;
while (i <= no)
{
printf("%d\n", i++);
}

return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
10
11
//printf("%d\n", i++);
00C052BC 8B 45 F4 mov eax,dword ptr [i]
00C052BF 89 85 20 FF FF FF mov dword ptr [ebp-0E0h],eax
00C052C5 8B 4D F4 mov ecx,dword ptr [i]
00C052C8 83 C1 01 add ecx,1
00C052CB 89 4D F4 mov dword ptr [i],ecx
00C052CE 8B 95 20 FF FF FF mov edx,dword ptr [ebp-0E0h]
00C052D4 52 push edx
00C052D5 68 34 7B C0 00 push offset string "%d\n" (0C07B34h)
00C052DA E8 CD C0 FF FF call _printf (0C013ACh)
00C052DF 83 C4 08 add esp,8
1
2
3
4
5
6
7
8
9
printf("%d\n", ++i);
008552BC 8B 45 F4 mov eax,dword ptr [i]
008552BF 83 C0 01 add eax,1
008552C2 89 45 F4 mov dword ptr [i],eax
008552C5 8B 4D F4 mov ecx,dword ptr [i]
008552C8 51 push ecx
008552C9 68 34 7B 85 00 push offset string "%d\n" (0857B34h)
008552CE E8 D9 C0 FF FF call _printf (08513ACh)
008552D3 83 C4 08 add esp,8

这里的 “i++” 和 “++i” 的反汇编与4-6中的原理一样。i++:备份值,再对变量做加法操作,最后使用备份值做参数。++i:直接对变量使用加法操作,再将变量作为参数。

限定次数的循环操作

输入一个整数后,并排连续显示出该整数个 *,具体的程序代码如下。

代码清单 4-8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:list0408.c*/
/*
输入一个整数,连续显示该整数个 *
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int no;

printf("请输入一个正整数:");
scanf("%d", &no);

while (no-- > 0)
{
putchar('*');
}
putchar('\n');

return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//while (no-- > 0)
002D52AD 8B 45 F4 mov eax,dword ptr [no]
002D52B0 89 85 2C FF FF FF mov dword ptr [ebp-0D4h],eax
002D52B6 8B 4D F4 mov ecx,dword ptr [no]
002D52B9 83 E9 01 sub ecx,1
002D52BC 89 4D F4 mov dword ptr [no],ecx
002D52BF 83 BD 2C FF FF FF 00 cmp dword ptr [ebp-0D4h],0
002D52C6 7E 0C jle __$EncStackInitStart+68h (02D52D4h)
002D52C8 C7 85 28 FF FF FF 01 00 00 00 mov dword ptr [ebp-0D8h],1
002D52D2 EB 0A jmp __$EncStackInitStart+72h (02D52DEh)
002D52D4 C7 85 28 FF FF FF 00 00 00 00 mov dword ptr [ebp-0D8h],0
002D52DE 83 BD 28 FF FF FF 00 cmp dword ptr [ebp-0D8h],0
002D52E5 74 16 je __$EncStackInitStart+91h (02D52FDh)
//{
//putchar('*');
002D52E7 8B F4 mov esi,esp
002D52E9 6A 2A push 2Ah
002D52EB FF 15 88 B1 2D 00 call dword ptr [__imp__putchar (02DB188h)]
002D52F1 83 C4 04 add esp,4
002D52F4 3B F4 cmp esi,esp
002D52F6 E8 35 BF FF FF call __RTC_CheckEsp (02D1230h)
//}
002D52FB EB B0 jmp __$EncStackInitStart+41h (02D52ADh)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//while (--no > 0)
009152AD 8B 45 F4 mov eax,dword ptr [no]
009152B0 83 E8 01 sub eax,1
009152B3 89 45 F4 mov dword ptr [no],eax
009152B6 83 7D F4 00 cmp dword ptr [no],0
009152BA 7E 16 jle __$EncStackInitStart+66h (09152D2h)
//{
//putchar('*');
009152BC 8B F4 mov esi,esp
009152BE 6A 2A push 2Ah
009152C0 FF 15 88 B1 91 00 call dword ptr [__imp__putchar (091B188h)]
009152C6 83 C4 04 add esp,4
009152C9 3B F4 cmp esi,esp
009152CB E8 60 BF FF FF call __RTC_CheckEsp (0911230h)
//}
009152D0 EB DB jmp __$EncStackInitStart+41h (09152ADh)

while 中的 no-- 和 --no 也是不一样的。

前置递增和前置递减运算符

代码清单4-9

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
/*程序名:list0409.c*/
/*
输入规定个数整数并显示它们的合和平均值。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i = 0;
int sum = 0;
int num, tmp;

printf("请输入一个正整数:");
scanf("%d", &num);

while (i < num)
{
printf("No.%d", ++i);
scanf("%d", &tmp);
sum += tmp;
}

printf("合计值:%d\n", sum);
printf("平均值:%2.f\n", (double)sum / num);

return 0;
}

逆向显示整数

输入一个非负整数,并进行逆向显示。例如:输入 1963 的时候,显示出的结果是3691。

代码清单4-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
26
27
28
29
30
31
/*程序名:list0410.c*/
/*
逆向显示正整数。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int no;

do
{
printf("请输入一个正整数:");
scanf("%d", &no);

if (no <= 0)
puts("\a请不要输入非正整数。");
} while (no <= 0);

//no比0大时
printf("该整数逆向显示的结果是");
while (no > 0)
{
printf("%d", no % 10);
no /= 10;
}
puts("。");
return 0;
}

反汇编

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
62
//do 
//{
//printf("请输入一个正整数:");
00C7528F 68 10 86 C7 00 push 0C78610h
00C75294 E8 13 C1 FF FF call 00C713AC
00C75299 83 C4 04 add esp,4
//scanf("%d", &no);
00C7529C 8D 45 F4 lea eax,[ebp-0Ch]
00C7529F 50 push eax
00C752A0 68 30 7B C7 00 push 0C77B30h
00C752A5 E8 48 C1 FF FF call 00C713F2
00C752AA 83 C4 08 add esp,8

//if (no <= 0)
00C752AD 83 7D F4 00 cmp dword ptr [ebp-0Ch],0
00C752B1 7F 17 jg 00C752CA
//puts("\a请不要输入非正整数。");
00C752B3 8B F4 mov esi,esp
00C752B5 68 D8 7C C7 00 push 0C77CD8h
00C752BA FF 15 70 B1 C7 00 call dword ptr ds:[00C7B170h]
00C752C0 83 C4 04 add esp,4
00C752C3 3B F4 cmp esi,esp
00C752C5 E8 66 BF FF FF call 00C71230
//} while (no <= 0);
00C752CA 83 7D F4 00 cmp dword ptr [ebp-0Ch],0
00C752CE 7E BF jle 00C7528F

//no比0大时
//printf("该整数逆向显示的结果是");
00C752D0 68 F0 7C C7 00 push 0C77CF0h
00C752D5 E8 D2 C0 FF FF call 00C713AC
00C752DA 83 C4 04 add esp,4
while (no > 0)
00C752DD 83 7D F4 00 cmp dword ptr [ebp-0Ch],0
00C752E1 7E 29 jle 00C7530C
//{
//printf("%d", no % 10);
00C752E3 8B 45 F4 mov eax,dword ptr [ebp-0Ch]
00C752E6 99 cdq
00C752E7 B9 0A 00 00 00 mov ecx,0Ah
00C752EC F7 F9 idiv eax,ecx
00C752EE 52 push edx
00C752EF 68 30 7B C7 00 push 0C77B30h
00C752F4 E8 B3 C0 FF FF call 00C713AC
00C752F9 83 C4 08 add esp,8
//no /= 10;
00C752FC 8B 45 F4 mov eax,dword ptr [ebp-0Ch]
00C752FF 99 cdq
00C75300 B9 0A 00 00 00 mov ecx,0Ah
00C75305 F7 F9 idiv eax,ecx
00C75307 89 45 F4 mov dword ptr [ebp-0Ch],eax
//}
00C7530A EB D1 jmp 00C752DD
//puts("。");
00C7530C 8B F4 mov esi,esp
00C7530E 68 E4 7B C7 00 push 0C77BE4h
00C75313 FF 15 70 B1 C7 00 call dword ptr ds:[00C7B170h]
00C75319 83 C4 04 add esp,4
00C7531C 3B F4 cmp esi,esp
00C7531E E8 0D BF FF FF call 00C71230
//return 0;
00C75323 33 C0 xor eax,eax

for 语句

比起使用 while 语句,使用 for 语句实现循环会使得程序更加简洁、易读。

for 语句

下面使用 for 语句对代码清单4-7的递增程序进行修改。

代码清单4-11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*程序名:list0411.c*/
/*
递增显示从 0 到输入的正整数(使用for循环)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i,no;

printf("请输入一个整数:");
scanf("%d", &no);

for (i = 0; i <= no; i++)
{
printf("%d\n", i);
}
//putchar('\n');
return 0;
}

反汇编

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
//printf("请输入一个整数:");
0010528F 68 10 86 10 00 push offset string "\xc7\xeb\xca\xe4\xc8\xeb\xd2\xbb\xb8\xf6\xd5\xfb\xca\xfd\xa3\xba" (0108610h)
00105294 E8 13 C1 FF FF call _printf (01013ACh)
00105299 83 C4 04 add esp,4

//scanf("%d", &no);
0010529C 8D 45 E8 lea eax,[no]
0010529F 50 push eax
001052A0 68 30 7B 10 00 push offset string "%d" (0107B30h)
001052A5 E8 48 C1 FF FF call _scanf (01013F2h)
001052AA 83 C4 08 add esp,8

//for (i = 0; i <= no; i++)
001052AD C7 45 F4 00 00 00 00 mov dword ptr [i],0
001052B4 EB 09 jmp __$EncStackInitStart+53h (01052BFh)
001052B6 8B 45 F4 mov eax,dword ptr [i]
001052B9 83 C0 01 add eax,1
001052BC 89 45 F4 mov dword ptr [i],eax
001052BF 8B 45 F4 mov eax,dword ptr [i]
001052C2 3B 45 E8 cmp eax,dword ptr [no]
001052C5 7F 13 jg __$EncStackInitStart+6Eh (01052DAh)
//{
// printf("%d\n", i);
001052C7 8B 45 F4 mov eax,dword ptr [i]
001052CA 50 push eax
001052CB 68 34 7B 10 00 push offset string "%d\n" (0107B34h)
001052D0 E8 D7 C0 FF FF call _printf (01013ACh)
001052D5 83 C4 08 add esp,8
//}
001052D8 EB DC jmp __$EncStackInitStart+4Ah (01052B6h)
//return 0;
001052DA 33 C0 xor eax,eax

for语句反汇编架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//for 括号中的第一个表达式(可选项):局部变量初始化(i = 0)
for1:
mov xxx,idata
jmp for2
// for括号中的第三个表达式(可选项):循环体执行后要做的操作(i++)
for3:
xxx
// for括号中的第二个表达式(可选项):判断条件(i <= no)
for2:
cmp xxx,xxx
JCC end
loop:
循环体
jmp for3
end:
xor eax,eax //return 0;

6
7

忽略个表达式的反汇编

一、忽略第一个表达式

反汇编

1
2
3
4
5
6
7
8
//for (; i <= no; i++)
00D652B4 EB 09 jmp __$EncStackInitStart+53h (0D652BFh)
00D652B6 8B 45 F4 mov eax,dword ptr [i]
00D652B9 83 C0 01 add eax,1
00D652BC 89 45 F4 mov dword ptr [i],eax
00D652BF 8B 45 F4 mov eax,dword ptr [i]
00D652C2 3B 45 E8 cmp eax,dword ptr [no]
00D652C5 7F 13 jg __$EncStackInitStart+6Eh (0D652DAh)

反汇编框架

1
2
3
4
5
6
7
8
9
10
11
	jmp for2
for3:
xxx
for2:
cmp xxx
JCC end
loop:
循环体
jmp for3
end:
xxx

二、忽略第三个表达式
反汇编

1
2
3
4
//for (;i <= no;)
004252B4 8B 45 F4 mov eax,dword ptr [i]
004252B7 3B 45 E8 cmp eax,dword ptr [no]
004252BA 7F 13 jg __$EncStackInitStart+63h (04252CFh)

反汇编框架

1
2
3
4
5
6
7
8
for2:
cmp xxx
JCC end
loop:
循环体
jmp for2
end:
xxx

三、无表达式
反汇编

1
2
3
4
5
6
7
8
9
10
//for (;;)
//{
//printf("%d\n", i);
002052B4 8B 45 F4 mov eax,dword ptr [i]
002052B7 50 push eax
002052B8 68 34 7B 20 00 push offset string "%d\n" (0207B34h)
002052BD E8 EA C0 FF FF call _printf (02013ACh)
002052C2 83 C4 08 add esp,8
//}
002052C5 EB ED jmp __$EncStackInitStart+48h (02052B4h)

反汇编框架

1
2
3
4
5
loop:
循环体
jmp loop
end:
xxx

如果for语句无表达式就是一个死循环。

for 语句实现固定次数的循环

使用 for 语句对代码清单4-8中的程序进行修改,实现同样的功能。

代码清单4-12

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*程序名:list0412.c*/
/*
输入一个整数,连续显示出该整数个*(使用for循环)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i,no;

printf("请输入一个整数:");
scanf("%d", &no);

for (i=1;i<=no;i++)
{
putchar('*');
}
putchar('\n');
return 0;
}

代码清单4-13

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
/*程序名:list0413.c*/
/*
输入规定个数的整数并显示出它们的合计值和平均值(使用for循环)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i = 0;
int sum = 0;
int num, tmp;

printf("输入多少个整数:");
scanf("%d", &num);

for (i=0;i<num;i++)
{
printf("No.%d:", i + 1);
scanf("%d", &tmp);
sum += tmp;
}
printf("合计值:%d\n", sum);
printf("平均值:%.2f\n", (double)sum / sum);

return 0;
}

偶数的枚举

下面的程序,实现宿儒一个整数值,显示该整数值一下的正偶数。

代码清单4-14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*程序名:list0414.c*/
/*
显示输入的整数值以下的偶数
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i, n;
printf("整数值:");
scanf("%d", &n);

for (i = 2; i <= n; i += 2)
{
printf("%d", i);
}
putchar('\n');

return 0;
}

约数的枚举

实现输入一个整数值,显示该整数值的所有约数。

代码清单4-15

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
/*程序名:list0415.c*/
/*
显示输入的整数值的约数
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i, n;
printf("请输入一个值:");
scanf("%d", &n);
printf("整数%d的约数是:",n);

for (i = 1; i <= n; i ++)
{
if (n % i == 0)
{
printf("%d ", i);
}
}
putchar('\n');

return 0;
}

表达式语句和空语句

8

在while和for循环语句表达式后面加上分号,表示该循环体为空。

多重循环

在循环体中继续写循环语句,就可以进行二重循环、三重循环。这样的循环称为多重循环。

二重循环

之前的循环结构都比较简单。实际上,在一个循环中还可以嵌套另一个循环。根据所嵌套的循环的多少,有二重循环、三重循环。它们统称为多重循环。

代码清单4-16

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:list0416.c*/
/*
显示九九乘法表
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i, j;

for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
{
printf("%5d", i * j);
}
putchar('\n');
}

return 0;
}

反汇编

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
//for (i = 1; i <= 9; i++)
002A43A5 C7 45 F8 01 00 00 00 mov dword ptr [i],1
002A43AC EB 09 jmp __$EncStackInitStart+2Bh (02A43B7h)
002A43AE 8B 45 F8 mov eax,dword ptr [i]
002A43B1 83 C0 01 add eax,1
002A43B4 89 45 F8 mov dword ptr [i],eax
002A43B7 83 7D F8 09 cmp dword ptr [i],9
002A43BB 7F 45 jg __$EncStackInitStart+76h (02A4402h)
//{
// for (j = 1; j <= 9; j++)
002A43BD C7 45 EC 01 00 00 00 mov dword ptr [j],1
002A43C4 EB 09 jmp __$EncStackInitStart+43h (02A43CFh)
002A43C6 8B 45 EC mov eax,dword ptr [j]
002A43C9 83 C0 01 add eax,1
002A43CC 89 45 EC mov dword ptr [j],eax
002A43CF 83 7D EC 09 cmp dword ptr [j],9
002A43D3 7F 17 jg __$EncStackInitStart+60h (02A43ECh)
//{
// printf("%5d", i * j);
002A43D5 8B 45 F8 mov eax,dword ptr [i]
002A43D8 0F AF 45 EC imul eax,dword ptr [j]
002A43DC 50 push eax
002A43DD 68 10 86 2A 00 push offset string "%5d" (02A8610h)
002A43E2 E8 C5 CF FF FF call _printf (02A13ACh)
002A43E7 83 C4 08 add esp,8
//}
002A43EA EB DA jmp __$EncStackInitStart+3Ah (02A43C6h)
//putchar('\n');
002A43EC 8B F4 mov esi,esp
002A43EE 6A 0A push 0Ah
002A43F0 FF 15 88 B1 2A 00 call dword ptr [__imp__putchar (02AB188h)]
002A43F6 83 C4 04 add esp,4
002A43F9 3B F4 cmp esi,esp
002A43FB E8 30 CE FF FF call __RTC_CheckEsp (02A1230h)
//}
002A4400 EB AC jmp __$EncStackInitStart+22h (02A43AEh)

//return 0;
002A4402 33 C0 xor eax,eax

用break语句强制结束循环

代码清单4-16a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*程序名:list0416a.c*/
/*
显示九九乘法表(使用break跳出循环)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i, j, eski=0;
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
{
int eski = i * j;
if (eski > 40)
break;
printf("%5d", eski);
}
}

return 0;
}

反汇编

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
//for (i = 1; i <= 9; i++)
00F143AC C7 45 F8 01 00 00 00 mov dword ptr [i],1
00F143B3 EB 09 jmp __$EncStackInitStart+32h (0F143BEh)
00F143B5 8B 45 F8 mov eax,dword ptr [i]
00F143B8 83 C0 01 add eax,1
00F143BB 89 45 F8 mov dword ptr [i],eax
00F143BE 83 7D F8 09 cmp dword ptr [i],9
00F143C2 7F 3F jg __$EncStackInitStart+77h (0F14403h)
//{
//for (j = 1; j <= 9; j++)
00F143C4 C7 45 EC 01 00 00 00 mov dword ptr [j],1
00F143CB EB 09 jmp __$EncStackInitStart+4Ah (0F143D6h)
00F143CD 8B 45 EC mov eax,dword ptr [j]
00F143D0 83 C0 01 add eax,1
00F143D3 89 45 EC mov dword ptr [j],eax
00F143D6 83 7D EC 09 cmp dword ptr [j],9
00F143DA 7F 25 jg __$EncStackInitStart+75h (0F14401h)
//{
//int eski = i * j;
00F143DC 8B 45 F8 mov eax,dword ptr [i]
00F143DF 0F AF 45 EC imul eax,dword ptr [j]
00F143E3 89 45 D4 mov dword ptr [ebp-2Ch],eax
//if (eski > 40)
00F143E6 83 7D D4 28 cmp dword ptr [ebp-2Ch],28h
00F143EA 7E 02 jle __$EncStackInitStart+62h (0F143EEh)
//break;
00F143EC EB 13 jmp __$EncStackInitStart+75h (0F14401h)
//printf("%5d", eski);
00F143EE 8B 45 D4 mov eax,dword ptr [ebp-2Ch]
00F143F1 50 push eax
00F143F2 68 30 7B F1 00 push offset string "%5d" (0F17B30h)
00F143F7 E8 05 D0 FF FF call _printf (0F11401h)
00F143FC 83 C4 08 add esp,8
//}
00F143FF EB CC jmp __$EncStackInitStart+41h (0F143CDh)
//}
00F14401 EB B2 jmp __$EncStackInitStart+29h (0F143B5h)

//return 0;
00F14403 33 C0 xor eax,eax

break 语句使用 jmp 指令跳出当前的循环语句。

图形显示

用程序显示长方形。

代码清单4-17

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
/*程序名:list0417.c*/
/*
使用*,打印出一个长方形。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i, j;
int height, width;

puts("画一个长方形。");
printf("高:"); scanf("%d", &height);
printf("宽:"); scanf("%d", &width);

for (i = 1; i <= height; i++)
{
for (j = 1; j <= width; j++)
putchar('*');
putchar('\n');
}

return 0;
}

代码清单4-18

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
/*程序名:list0418.c*/
/*
使用*,打印出一个直角在左边的等腰三角形。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i, j, len;


puts("生成一个直角在左边的等腰三角形。");
printf("短边:"); scanf("%d", &len);

for (i = 1; i <= len; i++)
{
for (j = 1; j <= i; j++)
putchar('*');
putchar('\n');
}

return 0;
}

代码清单4-19

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
/*程序名:list0419.c*/
/*
使用*,打印出一个直角在右边的等腰三角形。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i, j, k, len;


puts("生成一个直角在右边的等腰三角形。");
printf("短边:"); scanf("%d", &len);

for (i = 1; i <= len; i++)
{
for (j = 1; j <= len-i; j++)
{
putchar(' ');
}
for (j = 1; j <= i; j++)
{
putchar('*');
}
putchar('\n');
}

return 0;
}

代码清单4-19a

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
/*程序名:list0419.c*/
/*
使用*,打印出一个直角在右边的等腰三角形。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i, j, k, len;


puts("生成一个直角在右边的等腰三角形。");
printf("短边:"); scanf("%d", &len);

for (i = 1; i <= len; i++)
{
for (j = len; j > i; j--)
{
putchar(' ');
}
for (k = 1; k <= i; k++)
{
putchar('*');
}
putchar('\n');
}

return 0;
}

多重循环

do语句、while语句和for语句,都可以通过嵌套结构实现多重循环。

代码清单4-20

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
/*程序名:list0420.c*/
/*
输入一个整数,显示该整数个*(循环次数可任意指定)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int retry;


do
{
int i, no;
do
{
printf("请输入一个正整数:");
scanf("%d", &no);
if (no <= 0)
puts("\a请不要输入非正整数。");
} while (no <= 0);

for (i = 1; i <= no; i++)
putchar('*');
putchar('\n');

printf("是否继续执行? [Yes....0/Np....9]: ");
scanf("%d", &retry);

} while (retry == 0);

return 0;
}

程序的组成元素和格式

关键字

9

运算符

10

标识符

11

分隔符

12

常量和字符串常量

13

自由的书写格式

C语言原则上允许开发人员以自由的格式编写程序。它并不像其他编程语言那样,规定了程序中必须从第几个字符开始写,或者每条语句必须写在一行之内等。

代码清单4-21

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*程序名:list0421.c*/
/*
显示九九乘法表
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(
void) {int i, j
;
for (i = 1; i <= 9; i
++) {
for (j = 1; j <= 9; j++) printf("%3d", i * j);
putchar('\n');
}
return 0;
}

14
15

连接相邻的字符串常量

16

缩进

17

总结

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
/*程序名:summarya.c*/
/*
显示九九乘法表
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int i, j;
int x, y, z;

do
{
printf("0-100的数值:");
scanf("%d", &x);
} while (x < 0 || x>100);

y = x;
z = x;

while (y >= 0)
printf("%d %d\n", y--, ++z);

printf("宽和高为整数面积为 %d"
"的长方形的边长是:\n", x);

for (i = 1; i < x; i++)
{
if (i * i > x) break;
if (x % i != 0) continue;
printf("%d x %d\n", i, x / i);
}

puts("5行7列的星号");
for (i = 1; i <= 5; i++)
{
for (j = 1; j <= 7; j++)
putchar('*');
putchar('\n');
}

return 0;
}

课后练习

练习4-1

18

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
/*程序名:lx4-1.c*/
/*
代码清单3-9是判断所输入的整数值的符号的程序,请将其改写为可以将输入显示这一过程循环任意次。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int y;
do
{
int x;
printf("请输入一个数字:"); scanf("%d", &x);

if (x > 0)
puts("输入的值是正数\n");
else if (x < 0)
puts("输入的值是负数\n");
else
puts("输入的值是0.\n");

printf("是否继续输入<YES......0/NO......9>:\n"); scanf("%d", &y);
} while (y == 0);

system("pause");
return 0;
}

练习4-2

19

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
/*程序名:lx4-2.c*/
/*
编写一段程序,像下面这样读取两个整数的值,然后计算出它们之间所有整数的和。

请输入两个整数。
整数a:
整数b:
大于等于28小于等于37的所有整数的和是325。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int y, sum=0, min = 0, max = 0;

puts("请输入两个整数。");
do
{
int a, b;
printf("整数a:"); scanf("%d", &a);
printf("整数b:"); scanf("%d", &b);

if (min == 0 && max == 0)
{
(a > b) ? (max = a )&&( min = b ) : (max = b)&&(min = a);
}
else
{
if (max < a || max < b)
{
max = a;
if (max < b)
max = b;
}
else if (min > a || min > b)
{
min = a;
if (min > b)
min = b;
}
}

sum += a+b;

printf("是否继续输入<YES......0/NO......9>:"); scanf("%d", &y);
} while (y == 0);

printf("\n大于等于%d小于等于%d的所有整数的和是%d。", min, max, sum);

system("pause");
return 0;
}

练习4-3

20

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
/*程序名:lx4-3.c*/
/*
对代码4-5中的程序进行修改,当输入的值为负数的时候不执行换行操作。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
printf("请输入一个整数:"); scanf("%d", &x);

while (x >= 0)
{
printf("%d ", x);
x--;
}
if (x >= 0)
{
printf(" \n");
}
system("pause");
return 0;
}

练习4-4

21

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
/*程序名:lx4-4.c*/
/*
对代码4-6的程序进行修改,使其
.递减到1而非递减到0
.当输入的值小于0时,不进行换行。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
printf("请输入一个整数:"); scanf("%d", &x);

while (x >= 1)
{
printf("%d ", x--);
}
if (x >= 0)
printf("\n");
system("pause");
return 0;
}

练习4-5

22

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
/*程序名:lx4-5.c*/
/*
对代码清单4-7的程序进行如下修改。
.从1开始递增。
.输入的值小于0的时候不换行。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
int i = 1;
printf("请输入一个整数:"); scanf("%d", &x);

while (i <= x)
{
printf("%d ", i++);
}
if(x>=0)
printf(" \n");
system("pause");
return 0;
}

练习4-6

23

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
/*程序名:lx4-6.c*/
/*
编写一段程序,像右面这样按照升序显示出小于输入值的所以正偶数
输入值:19
2 4 6 8 10 12 14 16 18
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x, i = 2;
printf("输入值:"); scanf("%d", &x);

while (x > i)
{
if (i % 2 == 0)
printf("%d ", i);
i += 2;
}
printf("\n");
system("pause");
return 0;
}

练习4-7

24

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
/*程序名:lx4-7.c*/
/*
编写一段程序,像右面这样按照升序显示出小于输入值的整数的所有2的乘方。
输入值:19
2 4 8 16
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x, i = 2;
printf("输入值:"); scanf("%d", &x);

while (x > i)
{
if (i % 2 == 0)
printf("%d ", i);
i *= 2;
}
printf("\n");
system("pause");
return 0;
}

练习4-8

25

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:lx4-8.c*/
/*
改写4-8的程序,当输入的值小于1时,不输出换行符。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
printf("请输入一个整数:"); scanf("%d", &x);
while (--x >= 1)
{
putchar('*'); //putchar 显示一个字符,使用单引号
}
x++;
if (x >= 1)
printf("*\n");
system("pause");
return 0;
}

练习4-9

26

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
/*程序名:lx4-9.c*/
/*
编写一段程序,使之像右边这样交替显示+和-,总个数等于所输入的整数值。
另外,当输入0以下的整数时,则什么也不显示。
正整数:13
+-+-+-+-+-+-+
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
printf("正整数:"); scanf("%d", &x);
while (x >= 1)
{
if (x % 2 == 0)
printf("-");
else
printf("+");
x--;
}
printf("\n");
system("pause");
return 0;
}

练习4-10

27

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
/*程序名:lx4-10.c*/
/*
编写一段程序,使之像右边这样交替显示*,总个数等于所输入的整数值。
另外,当输入0以下的整数时,则什么也不显示。
正整数:3
*
*
*
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
printf("正整数:"); scanf("%d", &x);
while (--x >= 0)
{
printf("*\n");
}
system("pause");
return 0;
}

练习4-11

28

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
/*程序名:lx4-11.c*/
/*
对代码4-10的程序进行修改,使其像右边这样再显示结果的同时显示输入的整数值。
请输入一个正整数:1963
1963逆向显示的结果是3691。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
printf("请输入一个正整数:"); scanf("%d", &x);
printf("%d逆向显示的结果是", x);
while (x > 0)
{
printf("%d", x % 10);
x /= 10;
}
printf("\n");
system("pause");
return 0;
}

练习4-12

29

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
/*程序名:lx4-12.c*/
/*
编写一个程序,读取一个正整数,显示其位数。
注意:代码清单4-10中while语句的循环次数和num的位数一致。
请输入一个正整数:1963
1963的位数是4。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x, tmp, i = 0;
printf("请输入一个正整数:"); scanf("%d", &x);
tmp = x;
while (tmp > 0)
{
tmp /= 10;
i++;
}
printf("%d的位数是%d\n", x,i);
printf("\n");
system("pause");
return 0;
}

练习4-13

30

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
/*程序名:lx4-13.c*/
/*
编写一个程序,求1到n的和。n的值从键盘输入
n的值:
1到5的和为15。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x, sum = 0, num = 0;
printf("整数值:"); scanf("%d", &x);

for (int i = 1; i <= x; ++i)
{
sum += i;
}

printf("1到%d的和为%d\n", x, sum);
system("pause");
return 0;
}

练习4-14

31

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
/*程序名:lx4-14.c*/
/*
编写一个程序,像右面这样根据输入的整数,循环显示1234567890,显示的位数和输入的整数值相同。
请输入一个整数:25
1234567890123456789012345
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int num[11] = { 1,2,3,4,5,6,7,8,9,0 };
int x, flag = 0;
printf("整数值:"); scanf("%d", &x);

for (int i = 0; i < x; ++i&&flag++)
{
if (i % 10 == 0)
flag = 0;
printf("%d", num[flag]);
}
system("pause");
return 0;
}

练习4-15

32

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
/*程序名:lx4-15.c*/
/*
编写一段程序,像右面这样显示出身高和标准体重的对照表。(身高-100)*0.9
显示的身高范围和间隔由输入的整数值进行控制,标准体重精确到小数点后2位。
开始数值(cm):155
结束数值(cm):190
间隔数值(cm):5
155cm 49.50kg
160cm 54.00kg
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int start, end, x;
puts("身高和标准体重对照表");
printf("\n开始数值(cm):"); scanf("%d", &start);
printf("结束数值(cm):"); scanf("%d", &end);
printf("间隔数值(cm):"); scanf("%d", &x);
printf("\n");
for (; start < end; start += x)
{
printf("%dcm %.2fkg\n", start, ((double)start - 100)*0.9);
}
system("pause");
return 0;
}

练习4-16

33

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*程序名:lx4-16.c*/
/*
编写一段程序,输入一个整数值,显示该数值以下的所有奇数。
整数值:15
1 3 5 7 9 11 13 15
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
printf("整数值:"); scanf("%d", &x);
for (int i = 1; i <= x; i++)
{
if (i % 2 != 0)
printf("%d ", i);
}
printf("\n");
system("pause");
return 0;
}

练习4-17

34

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
/*程序名:lx4-17.c*/
/*
编写一段程序,像右边这样显示1到n的整数值的二次方。
n的值:3
1的二次方是1
2的二次方是4
3的二次方是9
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
printf("n的值是:"); scanf("%d", &x);
for (int i = 1; i <= x; i++)
{
printf("%d的二次方是%d\n", i, i*i);
}
printf("\n");
system("pause");
return 0;
}

练习4-18

35

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
/*程序名:lx4-18.c*/
/*
编写一段程序,输入一个整数值,显示该整数值个‘*'。每显示5个就进行换行。
显示多少个*:12
*****
*****
**
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x;
printf("显示多少个*:"); scanf("%d", &x);
for (int i =0; i < x; i++)
{
if (i % 5 == 0 && i != 0)
printf("\n");
printf("*");
}
printf("\n");
system("pause");
return 0;
}

练习4-19

36

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
/*程序名:lx4-19.c*/
/*
编写一段程序,对代码清单4-15进行修改,在显示所输入的整数值的所有约数之后,显示约数的个数。
整数值:4
1
2
4
约数的个数是3个。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x, sum = 0, num = 0;
printf("整数值:"); scanf("%d", &x);
for (int i = 1; i <= x; ++i) //被除数不能是0
{
if (x % i == 0)
{
printf("%d\n", i);
num++;
}
}
printf("约数的个数是%d个\n\n",num);
system("pause");
return 0;
}

练习4-20

37

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
/*程序名:lx4-20.c*/
/*
编写一段程序,像右面这样显示所输入整数为边长的正方形。
生成一个正方形
正方形有几层:3
***
***
***

*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{


//打印行序列
for (int j = 0; j <= 9; j++)
{
if (j == 1)
printf("%3d", j);
else
printf("%4d", j);
}

printf("\n----|--------------------------------------\n");

//打印列序列
for (int k = 1; k <= 9; k++)
{
printf("%4d|", k);
//打印一行结果
for (int n = 1; n <= 9; n++)
{
printf("%2d ", k * n);
}
printf("\n");
}
system("pause");
return 0;
}

练习4-21

38

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
/*程序名:lx4-21.c*/
/*
编写一段程序,像右面这样显示所输入整数为边长的正方形。
生成一个正方形
正方形有几层:3
***
***
***

*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x,b=0;
puts("生成一个正方形。");

printf("正方形有几层:"); scanf("%d", &x);
b = x;
do
{
int a, b=0;
for (a = 0; a < x; ++a)
{
putchar('*');
}
putchar('\n');
} while (--b>0);
system("pause");
return 0;
}

练习4-22

39

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
/*程序名:lx4-22.c*/
/*
对代码4-17中的程序进行修改,显示出一个横向较长的长方形。
读取两个边的边长,以较小的数作为行数,以较大的数作为列数。
让我们来画一个长方形。
一边:7
另一边:3
*******
*******
*******
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x, y, tmp;

puts("让我们来画一个长方形。");
printf("一边:"); scanf("%d", &x);
printf("另一边:"); scanf("%d", &y);

if (x < y)
{
tmp = y;
y = x;
x = tmp;
}
for (int i = 1; i <= y; ++i)
{
for (int j = 1; j <= x; j++)
{
printf("*");
}
printf("\n");
}
system("pause");
return 0;
}

练习4-23

40

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
/*程序名:lx4-23.c*/
/*
对代码4-18和4-19中的程序进行修改,分别显示出直角在左上方和右上方的等腰直角三角形(生成两个程序)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x, y, space;

printf("短边:"); scanf("%d", &x);

for (int i = 1; i <= x; ++i)
{
//打印左上方三角
for (int j = 1; j <= i; j++)
{
//打印第一个字符
printf("* ");
}
//打印n个空格
//printf(" ");

//右上方三角
space = x * 4;
y =(x+space) - (i*4);
for (int k = 1; k <= y; k++)
{
printf(" ");
}
//打印末尾字符
for (int n = 1; n <= i; n++)
{
printf("* ");
}
printf("\n");
}
system("pause");
return 0;
}

练习4-24

41

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
/*程序名:lx4-24.c*/
/*
编写一段程序,输入一个整数,像右面这样显示出输入整数层的金字塔形状。
提示;第i行显示(i-1)*2+1个星
让我们来画一个金字塔。
金字塔有几层:3
*
***
*****
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x=0, y=1, space;

puts("让我们来画一个金字塔。");
printf("金字塔有几层:"); scanf("%d", &x);

//计算一共要打几个*
space = (x - 1) * 1 + x;
//计算第一行要打几个空格
space = (space - 1) / 2;
for (int i = 1; i <= x; i++)
{
if (i >1)
y = y + 2;
for (int k = 1; k <= space; k++)
{
printf(" ");
}
//每次循环空格打印结束,需要打印的空格-1
space--;
for (int j=1; j <= y; j++)
{
printf("*");
}
putchar('\n');
}
system("pause");
return 0;
}

练习4-25

42

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
/*程序名:lx4-25.c*/
/*
编写一段程序,像右面这样显示出输入整数层的向下的金字塔形状。第i行显示i%10的结果。
让我们来画一个金字塔。
金字塔有几层:3
11111
222
3
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int x=0, y, space;

puts("让我们来画一个金字塔。");
printf("金字塔有几层:"); scanf("%d", &x);

//计算一共要打几个*
y = (x - 1) * 1 + x;
//计算第一行要打几个空格
space = (y - 1) / 2;
for (int i = 1; i <= x; i++)
{
if (i >1)
y = y - 2;
for (int k = 1; k <= space; k++)
{
printf(" ");
}
//每次循环空格打印结束,需要打印的空格-1
space++;
for (int j=1; j <= y; j++)
{
printf("%d",i);
}
putchar('\n');
}
system("pause");
return 0;
}
  • 本文标题:C语言语法入门-程序的循环控制
  • 本文作者:9unk
  • 创建时间:2023-05-19 16:54:00
  • 本文链接:https://9unkk.github.io/2023/05/19/c-yu-yan-yu-fa-ru-men-cheng-xu-de-xun-huan-kong-zhi/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!