C语言语法入门-分支结构程序
9unk Lv5

if语句

几乎没有只会按照预先设计好的流程执行的程序。本章学习条件语句来改变程序流程的方法。

if语句.其1

通过程序来进行判断,如果输入放入整数不能被5整除,就显示相应的信息。

代码清单3-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*程序名:list0301.c*/
/*
输入的整数能被5整除吗?
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int no;

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

if (no % 5)
{
puts("输入的整数不能被5整除");
}
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
63
64
65
00C55260  push        ebp  
00C55261 mov ebp,esp
00C55263 sub esp,0D0h
00C55269 push ebx
00C5526A push esi
00C5526B push edi
00C5526C lea edi,[ebp-10h]
00C5526F mov ecx,4
00C55274 mov eax,0CCCCCCCCh
00C55279 rep stos dword ptr es:[edi]
00C5527B mov eax,dword ptr [__security_cookie (0C5A020h)]
00C55280 xor eax,ebp
00C55282 mov dword ptr [ebp-4],eax
00C55285 mov ecx,offset _FC42537F_mjc@cpp (0C5C008h)
00C5528A call @__CheckForDebuggerJustMyCode@4 (0C51307h)

//printf("请输入一个整数:");
00C5528F push offset string "\xc7\xeb\xca\xe4\xc8\xeb\xd2\xbb\xb8\xf6\xd5\xfb\xca\xfd\xa3\xba" (0C57E28h)
00C55294 call _printf (0C513ACh)
00C55299 add esp,4

//scanf("%d", &no);
00C5529C lea eax,[no]
00C5529F push eax
00C552A0 push offset string "%d" (0C57B30h)
00C552A5 call _scanf (0C513F2h)
00C552AA add esp,8

//if (no % 5)
00C552AD mov eax,dword ptr [no]
00C552B0 cdq
00C552B1 mov ecx,5
00C552B6 idiv eax,ecx
00C552B8 test edx,edx
00C552BA je __$EncStackInitStart+67h (0C552D3h)

//puts("输入的整数不能被5整除");
00C552BC mov esi,esp
00C552BE push offset string "\xca\xe4\xc8\xeb\xb5\xc4\xd5\xfb\xca\xfd\xb2\xbb\xc4\xdc\xb1\xbb5\xd5\xfb\xb3\xfd" (0C57BD8h)
00C552C3 call dword ptr [__imp__puts (0C5B170h)]
00C552C9 add esp,4
00C552CC cmp esi,esp
00C552CE call __RTC_CheckEsp (0C51230h)

//return 0;
00C552D3 xor eax,eax
00C552D5 push edx
00C552D6 mov ecx,ebp
00C552D8 push eax
00C552D9 lea edx,ds:[0C55304h]
00C552DF call @_RTC_CheckStackVars@8 (0C511D1h)
00C552E4 pop eax
00C552E5 pop edx
00C552E6 pop edi
00C552E7 pop esi
00C552E8 pop ebx
00C552E9 mov ecx,dword ptr [ebp-4]
00C552EC xor ecx,ebp
00C552EE call @__security_check_cookie@4 (0C5113Bh)
00C552F3 add esp,0D0h
00C552F9 cmp ebp,esp
00C552FB call __RTC_CheckEsp (0C51230h)
00C55300 mov esp,ebp
00C55302 pop ebp
00C55303 ret

if判断语句使用 JCC 跳转指令来实现。

奇数的判断

通过判断输入的整数是否被2整除,就可以确认该整数是不是奇数了。

代码清单3-2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*程序名:list0302.c*/
/*
输入的整数是奇数吗?
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int no;

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

if (no % 2)
{
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
//printf("请输入一个整数:");
00D9528F push offset string "\xc7\xeb\xca\xe4\xc8\xeb\xd2\xbb\xb8\xf6\xd5\xfb\xca\xfd\xa3\xba" (0D97E28h)
00D95294 call _printf (0D913ACh)
00D95299 add esp,4

//scanf("%d", &no);
00D9529C lea eax,[no]
00D9529F push eax
00D952A0 push offset string "%d" (0D97B30h)
00D952A5 call _scanf (0D913F2h)
00D952AA add esp,8

//if (no % 2)
00D952AD mov eax,dword ptr [no]
00D952B0 and eax,80000001h
00D952B5 jns __$EncStackInitStart+50h (0D952BCh)
00D952B7 dec eax
00D952B8 or eax,0FFFFFFFEh
00D952BB inc eax
00D952BC test eax,eax
00D952BE je __$EncStackInitStart+6Bh (0D952D7h)

//puts("输入的整数是奇数。");
00D952C0 mov esi,esp
00D952C2 push offset string "\xca\xe4\xc8\xeb\xb5\xc4\xd5\xfb\xca\xfd\xca\xc7\xc6\xe6\xca\xfd\xa1\xa3" (0D97BD8h)
00D952C7 call dword ptr [__imp__puts (0D9B170h)]
00D952CD add esp,4
00D952D0 cmp esi,esp
00D952D2 call __RTC_CheckEsp (0D91230h)

//return 0;
00D952D7 xor eax,eax

这里的取余算法有点变动,需要多注意一下。

if语句.其2

代码清单3-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
/*程序名:list0303.c*/
/*
输入的整数是奇数吗?
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int no;

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

if (no % 5)
{
puts("该整数不能被5整除。");
}
else
{
puts("该整数能被5整除。");
}
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
53
54
55
56
57
58
59
60
//printf("请输入一个整数:");
0045528F push offset string "\xc7\xeb\xca\xe4\xc8\xeb\xd2\xbb\xb8\xf6\xd5\xfb\xca\xfd\xa3\xba" (0457E28h)
00455294 call _printf (04513ACh)
00455299 add esp,4

//scanf("%d", &no);
0045529C lea eax,[no]
0045529F push eax
004552A0 push offset string "%d" (0457B30h)
004552A5 call _scanf (04513F2h)
004552AA add esp,8

//if (no % 5)
004552AD mov eax,dword ptr [no]
004552B0 cdq
004552B1 mov ecx,5
004552B6 idiv eax,ecx
004552B8 test edx,edx
004552BA je __$EncStackInitStart+69h (04552D5h)

//puts("输入的整数是奇数。");
004552BC mov esi,esp
004552BE push offset string "\xca\xe4\xc8\xeb\xb5\xc4\xd5\xfb\xca\xfd\xca\xc7\xc6\xe6\xca\xfd\xa1\xa3" (0457BD8h)
004552C3 call dword ptr [__imp__puts (045B170h)]
004552C9 add esp,4
004552CC cmp esi,esp
004552CE call __RTC_CheckEsp (0451230h)
004552D3 jmp __$EncStackInitStart+80h (04552ECh)
//else
//{
// puts("该整数能被5整除。");
004552D5 mov esi,esp
004552D7 push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xc4\xdc\xb1\xbb5\xd5\xfb\xb3\xfd\xa1\xa3" (0457CD8h)
004552DC call dword ptr [__imp__puts (045B170h)]
004552E2 add esp,4
004552E5 cmp esi,esp
004552E7 call __RTC_CheckEsp (0451230h)
}
//return 0;
004552EC xor eax,eax

004552EE push edx
004552EF mov ecx,ebp
004552F1 push eax
004552F2 lea edx,ds:[455320h]
004552F8 call @_RTC_CheckStackVars@8 (04511D1h)
004552FD pop eax
004552FE pop edx
004552FF pop edi
00455300 pop esi
00455301 pop ebx
00455302 mov ecx,dword ptr [ebp-4]
00455305 xor ecx,ebp
00455307 call @__security_check_cookie@4 (045113Bh)
0045530C add esp,0D0h
00455312 cmp ebp,esp
00455314 call __RTC_CheckEsp (0451230h)
00455319 mov esp,ebp
0045531B pop ebp
0045531C ret

IF-ELSE 语句架构

1
2
3
4
5
6
7
test(cmp) reg,reg
jCC L1
语句块1
jmp end
L1:
语句块2
end:

奇数.偶数的判断

代码清单3-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
/*程序名:list0304.c*/
/*
输入的整数是奇数还是偶数。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int no;

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

if (no % 2)
{
puts("该整数是奇数。");
}
else
{
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
//printf("请输入一个整数:");
0094528F push offset string "\xc7\xeb\xca\xe4\xc8\xeb\xd2\xbb\xb8\xf6\xd5\xfb\xca\xfd\xa3\xba" (0947E28h)
00945294 call _printf (09413ACh)
00945299 add esp,4

//scanf("%d", &no);
0094529C lea eax,[no]
0094529F push eax
009452A0 push offset string "%d" (0947B30h)
009452A5 call _scanf (09413F2h)
009452AA add esp,8

//if (no % 2)
009452AD mov eax,dword ptr [no]
009452B0 and eax,80000001h
009452B5 jns __$EncStackInitStart+50h (09452BCh)
009452B7 dec eax
009452B8 or eax,0FFFFFFFEh
009452BB inc eax
009452BC test eax,eax
009452BE je __$EncStackInitStart+6Dh (09452D9h)

//puts("该整数是奇数。");
009452C0 mov esi,esp
009452C2 push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xca\xc7\xc6\xe6\xca\xfd\xa1\xa3" (0947BD8h)
009452C7 call dword ptr [__imp__puts (094B170h)]
009452CD add esp,4
009452D0 cmp esi,esp
009452D2 call __RTC_CheckEsp (0941230h)
009452D7 jmp __$EncStackInitStart+84h (09452F0h)
//else
//puts("该整数是偶数。");
009452D9 mov esi,esp
009452DB push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xca\xc7\xc5\xbc\xca\xfd\xa1\xa3" (0947CD8h)
009452E0 call dword ptr [__imp__puts (094B170h)]
009452E6 add esp,4
009452E9 cmp esi,esp
009452EB call __RTC_CheckEsp (0941230h)

//return 0;
009452F0 xor eax,eax

非0的判断

判断输入的值是否为 0 的程序。

代码清单3-5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*程序名:list0305.c*/
/*
输入的整数是否为0。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int num;

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

if (num)
{
puts("该整数不是0。");
}
else
{
puts("该整数是0。");
}
return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//if (num)
002252AD cmp dword ptr [num],0
002252B1 je __$EncStackInitStart+60h (02252CCh)
//puts("该整数不是0。");
002252B3 mov esi,esp
002252B5 push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xb2\xbb\xca\xc70\xa1\xa3" (0227BD8h)
002252BA call dword ptr [__imp__puts (022B170h)]
002252C0 add esp,4
002252C3 cmp esi,esp
002252C5 call __RTC_CheckEsp (0221230h)
002252CA jmp __$EncStackInitStart+77h (02252E3h)
//else
//puts("该整数是0。");
002252CC mov esi,esp
002252CE push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xca\xc70\xa1\xa3" (0227CD8h)
002252D3 call dword ptr [__imp__puts (022B170h)]
002252D9 add esp,4
002252DC cmp esi,esp
002252DE call __RTC_CheckEsp (0221230h)

//return 0;
002252E3 xor eax,eax

相等运算符

输入两个整数的值,判断他们是否相等。

代码清单3-6

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
/*程序名:list0306.c*/
/*
输入的两个整数相等吗?(1)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int n1, n2;

puts("请输入两个整数:");
printf("整数1:"); scanf("%d", &n1);
printf("整数2:"); scanf("%d", &n2);

if (n1 == n2)
{
puts("它们相等。");
}
else
{
puts("它们不相等。");
}
return 0;
}

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
//if (n1 == n2)
00A552E2 mov eax,dword ptr [n1]
00A552E5 cmp eax,dword ptr [n2]
00A552E8 jne __$EncStackInitStart+97h (0A55303h)

//puts("它们相等。");
00A552EA mov esi,esp
00A552EC push offset string "\xcb\xfc\xc3\xc7\xcf\xe0\xb5\xc8\xa1\xa3" (0A57BDCh)
00A552F1 call dword ptr [__imp__puts (0A5B170h)]
00A552F7 add esp,4
00A552FA cmp esi,esp
00A552FC call __RTC_CheckEsp (0A51230h)
00A55301 jmp __$EncStackInitStart+0AEh (0A5531Ah)
//else
//puts("它们不相等。");
00A55303 mov esi,esp
00A55305 push offset string "\xcb\xfc\xc3\xc7\xb2\xbb\xcf\xe0\xb5\xc8\xa1\xa3" (0A57BE8h)
00A5530A call dword ptr [__imp__puts (0A5B170h)]
00A55310 add esp,4
00A55313 cmp esi,esp
00A55315 call __RTC_CheckEsp (0A51230h)

//return 0;
00A5531A xor eax,eax

代码清单3-7

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
/*程序名:list0307.c*/
/*
输入的两个整数相等吗?(2)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int n1, n2;

puts("请输入两个整数:");
printf("整数1:"); scanf("%d", &n1);
printf("整数2:"); scanf("%d", &n2);

if (n1 != n2)
{
puts("它们不相等。");
}
else
{
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
//if (n1 != n2)
007552E2 mov eax,dword ptr [n1]
007552E5 cmp eax,dword ptr [n2]
007552E8 je __$EncStackInitStart+97h (0755303h)
//puts("它们不相等。");
007552EA mov esi,esp
007552EC push offset string "\xcb\xfc\xc3\xc7\xb2\xbb\xcf\xe0\xb5\xc8\xa1\xa3" (0757CE0h)
007552F1 call dword ptr [__imp__puts (075B170h)]
007552F7 add esp,4
007552FA cmp esi,esp
007552FC call __RTC_CheckEsp (0751230h)
00755301 jmp __$EncStackInitStart+0AEh (075531Ah)
//else
//puts("它们相等。");
00755303 mov esi,esp
00755305 push offset string "\xcb\xfc\xc3\xc7\xcf\xe0\xb5\xc8\xa1\xa3" (0757BE8h)
0075530A call dword ptr [__imp__puts (075B170h)]
00755310 add esp,4
00755313 cmp esi,esp
00755315 call __RTC_CheckEsp (0751230h)

//return 0;
0075531A xor eax,eax

余数的判断

判断所输入的整数的个数是否为5,并显示相应信息的程序。

代码清单3-8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:list0308.c*/
/*
个位数是5吗?
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int num;

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

if (num % 10 == 5)
{
puts("该整数的个位数是5。");
}
else
{
puts("该整数的个位数不是5。");
}
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
//if (num % 10 == 5)
00FD52AD mov eax,dword ptr [num]
00FD52B0 cdq
00FD52B1 mov ecx,0Ah
00FD52B6 idiv eax,ecx
00FD52B8 cmp edx,5
00FD52BB jne __$EncStackInitStart+6Ah (0FD52D6h)

//puts("该整数的个位数是5。");
00FD52BD mov esi,esp
00FD52BF push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xb5\xc4\xb8\xf6\xce\xbb\xca\xfd\xca\xc75\xa1\xa3" (0FD7CF0h)
00FD52C4 call dword ptr [__imp__puts (0FDB170h)]
00FD52CA add esp,4
00FD52CD cmp esi,esp
00FD52CF call __RTC_CheckEsp (0FD1230h)
00FD52D4 jmp __$EncStackInitStart+81h (0FD52EDh)
//else
//puts("该整数的个位数不是5。");
00FD52D6 mov esi,esp
00FD52D8 push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xb5\xc4\xb8\xf6\xce\xbb\xca\xfd\xb2\xbb\xca\xc75\xa1\xa3" (0FD7E3Ch)
00FD52DD call dword ptr [__imp__puts (0FDB170h)]
00FD52E3 add esp,4
00FD52E6 cmp esi,esp
00FD52E8 call __RTC_CheckEsp (0FD1230h)

//return 0;
00FD52ED xor eax,eax

关系运算符

输入一个整数,判断该整数的符号

代码清单3-9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*程序名:list0309.c*/
/*
判断输入整数的符号
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int no;

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

if (no == 0)
puts("该整数为0。");
else if (no > 0)
printf("该整数为正数。");
else
puts("该整数为负数");
return 0;
}

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
32
//if (no == 0)
00BD52AD cmp dword ptr [no],0
00BD52B1 jne __$EncStackInitStart+60h (0BD52CCh)

//puts("该整数为0。");
00BD52B3 mov esi,esp
00BD52B5 push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xce\xaa0\xa1\xa3" (0BD7CF0h)
00BD52BA call dword ptr [__imp__puts (0BDB170h)]
00BD52C0 add esp,4
00BD52C3 cmp esi,esp
00BD52C5 call __RTC_CheckEsp (0BD1230h)
00BD52CA jmp __$EncStackInitStart+8Ch (0BD52F8h)

//else if (no > 0)
00BD52CC cmp dword ptr [no],0
00BD52D0 jle __$EncStackInitStart+75h (0BD52E1h)
//printf("该整数为正数。");
00BD52D2 push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xce\xaa\xd5\xfd\xca\xfd\xa1\xa3" (0BD7E3Ch)
00BD52D7 call _printf (0BD13ACh)
00BD52DC add esp,4
00BD52DF jmp __$EncStackInitStart+8Ch (0BD52F8h)
//else
//puts("该整数为负数");
00BD52E1 mov esi,esp
00BD52E3 push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xce\xaa\xb8\xba\xca\xfd" (0BD7BD8h)
00BD52E8 call dword ptr [__imp__puts (0BDB170h)]
00BD52EE add esp,4
00BD52F1 cmp esi,esp
00BD52F3 call __RTC_CheckEsp (0BD1230h)

//return 0;
00BD52F8 xor eax,eax

else-if 反汇编框架

1
2
3
4
5
6
7
8
9
10
11
12
	cmp xxx,xxx
JCC L1
语句块1
jmp end
L1:
cmp xxx,xxx
JCC L2
语句块2
jmp end
L2:
语句块3
end:

嵌套if语句

5

代码清单3-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
/*程序名:list0310.c*/
/*
如果输入的整数值为正,则判断该值的奇偶性并显示
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int no;

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

if (no > 0)
{
if (no % 2 == 0)
puts("该整数为偶数。");
else
puts("该整数为奇数。");
}
else
{
puts("您输入的不是正数。");
}
return 0;
}

6

反汇编

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
//if (no > 0)
00F452AD cmp dword ptr [no],0
00F452B1 jle __$EncStackInitStart+8Ch (0F452F8h)
//{
//if (no % 2 == 0)
00F452B3 mov eax,dword ptr [no]
00F452B6 and eax,80000001h
00F452BB jns __$EncStackInitStart+56h (0F452C2h)
00F452BD dec eax
00F452BE or eax,0FFFFFFFEh
00F452C1 inc eax
00F452C2 test eax,eax
00F452C4 jne __$EncStackInitStart+73h (0F452DFh)

//puts("该整数为偶数。");
00F452C6 mov esi,esp
00F452C8 push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xce\xaa\xc5\xbc\xca\xfd\xa1\xa3" (0F47CF0h)
00F452CD call dword ptr [__imp__puts (0F4B170h)]
00F452D3 add esp,4
00F452D6 cmp esi,esp
00F452D8 call __RTC_CheckEsp (0F41230h)
00F452DD jmp __$EncStackInitStart+8Ah (0F452F6h)
//else
//puts("该整数为奇数。");
00F452DF mov esi,esp
00F452E1 push offset string "\xb8\xc3\xd5\xfb\xca\xfd\xce\xaa\xc6\xe6\xca\xfd\xa1\xa3" (0F47E3Ch)
00F452E6 call dword ptr [__imp__puts (0F4B170h)]
00F452EC add esp,4
00F452EF cmp esi,esp
00F452F1 call __RTC_CheckEsp (0F41230h)
//}
00F452F6 jmp __$EncStackInitStart+0A3h (0F4530Fh)
//else
//{
//puts("您输入的不是正数。");
00F452F8 mov esi,esp
00F452FA push offset string "\xc4\xfa\xca\xe4\xc8\xeb\xb5\xc4\xb2\xbb\xca\xc7\xd5\xfd\xca\xfd\xa1\xa3" (0F47BD8h)
00F452FF call dword ptr [__imp__puts (0F4B170h)]
00F45305 add esp,4
00F45308 cmp esi,esp
00F4530A call __RTC_CheckEsp (0F41230h)
//}

嵌套 if 语句架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cmp xxx,xxx
JCC if_1
//外层if语句块
{cmp xxx,xxx
JCC if_2

嵌套if语句块
jmp con

if_2:
嵌套else语句块
con:jmp end}

//外层else语句块
{if_1:xxx}

end:

计算较大值

输入两个整数,显示其中较大的值。

代码清单3-11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*程序名:list0311.c*/
/*
显示所输入的两个整数中较大的数。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int n1,n2;

puts("输入两个整数。");
printf("整数1:"); scanf("%d", &n1);
printf("整数2:"); scanf("%d", &n2);

if (n1 > n2)
printf("较大的数是%d。\n", n1);
else
printf("较大的数是%d。 \n", n2);
return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//if (n1 > n2)
00E252E2 mov eax,dword ptr [n1]
00E252E5 cmp eax,dword ptr [n2]
00E252E8 jle __$EncStackInitStart+91h (0E252FDh)
//printf("较大的数是%d。\n", n1);
00E252EA mov eax,dword ptr [n1]
00E252ED push eax
00E252EE push offset string "\xbd\xcf\xb4\xf3\xb5\xc4\xca\xfd\xca\xc7%d\xa1\xa3\n" (0E27BD8h)
00E252F3 call _printf (0E213ACh)
00E252F8 add esp,8
00E252FB jmp __$EncStackInitStart+0A2h (0E2530Eh)

//else
//printf("较大的数是%d。 \n", n2);
00E252FD mov eax,dword ptr [n2]
00E25300 push eax
00E25301 push offset string "\xbd\xcf\xb4\xf3\xb5\xc4\xca\xfd\xca\xc7%d\xa1\xa3 \n" (0E27CD8h)
00E25306 call _printf (0E213ACh)
00E2530B add esp,8

//return 0;
00E2530E xor eax,eax

代码清单3-12

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*程序名:list0312.c*/
/*
显示所输入的两个整数中较大的数。(其2)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int n1,n2,max;

puts("请输入两个整数。");
printf("整数1:"); scanf("%d", &n1);
printf("整数2:"); scanf("%d", &n2);

if (n1 > n2) max = n1; else max = n2;

printf("较大的数是%d。\n", max);
return 0;
}

计算三个数的最大值

这次输入三个整数,显示出其中的最大值。

代码清单3-13

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:list0313.c*/
/*
显示所输入的三个整数中较大的数。(其2)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int n1,n2,n3,max;

puts("请输入三个整数。");
printf("整数1:"); scanf("%d", &n1);
printf("整数2:"); scanf("%d", &n2);
printf("整数3:"); scanf("%d", &n3);

max = n1;
if (n2 > max) max = n2;
if (n3 > max) max = n3;

printf("较大的数是%d。\n", max);
return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
//if (n2 > max) max = n2;
00165306 mov eax,dword ptr [n2]
00165309 cmp eax,dword ptr [max]
0016530C jle __$EncStackInitStart+0A8h (0165314h)
0016530E mov eax,dword ptr [n2]
00165311 mov dword ptr [max],eax

//if (n3 > max) max = n3;
00165314 mov eax,dword ptr [n3]
00165317 cmp eax,dword ptr [max]
0016531A jle __$EncStackInitStart+0B6h (0165322h)
0016531C mov eax,dword ptr [n3]
0016531F mov dword ptr [max],eax

条件运算符

代码清单3-14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*程序名:list03114.c*/
/*
显示所输入的两个整数中较大的数。(其3:条件运算)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int n1,n2,max;

puts("请输入三个整数。");
printf("整数1:"); scanf("%d", &n1);
printf("整数2:"); scanf("%d", &n2);

max = (n1 > n2) ? n1 : n2; /*将较大的值赋给max*/

printf("较大的数是%d。\n", max);
return 0;
}

7

反汇编

1
2
3
4
5
6
7
8
9
10
11
max = (n1 > n2) ? n1 : n2;	/*将较大的值赋给max*/
00C352E2 mov eax,dword ptr [n1]
00C352E5 cmp eax,dword ptr [n2]
00C352E8 jle __$EncStackInitStart+89h (0C352F5h)
00C352EA mov ecx,dword ptr [n1]
00C352ED mov dword ptr [ebp-0ECh],ecx
00C352F3 jmp __$EncStackInitStart+92h (0C352FEh)
00C352F5 mov edx,dword ptr [n2]
00C352F8 mov dword ptr [ebp-0ECh],edx
00C352FE mov eax,dword ptr [ebp-0ECh]
00C35304 mov dword ptr [max],eax

差值运算

使用条件运算符计算输入的两个整数差值的程序。

代码清单3-15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*程序名:list0315.c*/
/*
计算输入的两个整数的差并显示(条件运算符)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int n1,n2;

puts("请输入两个整数。");
printf("整数1:"); scanf("%d", &n1);
printf("整数2:"); scanf("%d", &n2);

printf("较大的数是%d。\n", (n1 > n2) ? n1 - n2 : n2 - n1);
return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//printf("较大的数是%d。\n", (n1 > n2) ? n1 - n2 : n2 - n1);
00A152E2 mov eax,dword ptr [n1]
00A152E5 cmp eax,dword ptr [n2]
00A152E8 jle __$EncStackInitStart+8Ch (0A152F8h)
00A152EA mov ecx,dword ptr [n1]
00A152ED sub ecx,dword ptr [n2]
00A152F0 mov dword ptr [ebp-0E0h],ecx
00A152F6 jmp __$EncStackInitStart+98h (0A15304h)
00A152F8 mov edx,dword ptr [n2]
00A152FB sub edx,dword ptr [n1]
00A152FE mov dword ptr [ebp-0E0h],edx
00A15304 mov eax,dword ptr [ebp-0E0h]
00A1530A push eax
00A1530B push offset string "\xbd\xcf\xb4\xf3\xb5\xc4\xca\xfd\xca\xc7%d\xa1\xa3\n" (0A17CD8h)
00A15310 call _printf (0A113ACh)
00A15315 add esp,8

复合语句

计算输入的两个整数中的较大值和较小值的程序。

代码清单3-16

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
/*程序名:list0316.c*/
/*
计算所输入的两个整数中的较大数和较小数并显示
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int n1,n2,max,min;

puts("请输入两个整数。");
printf("整数1:"); scanf("%d", &n1);
printf("整数2:"); scanf("%d", &n2);

if (n1 > n2)
{
max = n1;
min = n2;
}
else
{
max = n2;
min = n1;
}


printf("较大的数是%d。\n", max);
printf("较小的数是%d。\n", min);
return 0;
}

反汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//if (n1 > n2)
001B52E2 mov eax,dword ptr [n1]
001B52E5 cmp eax,dword ptr [n2]
001B52E8 jle __$EncStackInitStart+8Ch (01B52F8h)
//max = n1;
001B52EA mov eax,dword ptr [n1]
001B52ED mov dword ptr [max],eax
//min = n2;
001B52F0 mov eax,dword ptr [n2]
001B52F3 mov dword ptr [min],eax
001B52F6 jmp __$EncStackInitStart+98h (01B5304h)

//else
//max = n2;
001B52F8 mov eax,dword ptr [n2]
001B52FB mov dword ptr [max],eax
//min = n1;
001B52FE mov eax,dword ptr [n1]
001B5301 mov dword ptr [min],eax

逻辑运算符

代码清单3-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
/*程序名:list0317.c*/
/*
显示所输入的月份所处的季节
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int month;

printf("请输入月份:");
scanf("%d", &month);

if (month >= 3 && month <= 5)
printf("%d月是春季。\n", month);
else if (month >= 6 && month <= 8)
printf("%d月是夏季。\n", month);
else if (month >= 9 && month <= 11)
printf("%d月是秋季。\n", month);
else if (month == 1 || month == 2)
printf("%d月是冬季。\n", month);
else
printf("%d月不存在!!\a\n", month);
return 0;
}

8

反汇编

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
//if (month >= 3 && month <= 5)
007052AD cmp dword ptr [month],3
007052B1 jl __$EncStackInitStart+60h (07052CCh)
007052B3 cmp dword ptr [month],5
007052B7 jg __$EncStackInitStart+60h (07052CCh)
//printf("%月是春季。\n", month);
007052B9 mov eax,dword ptr [month]
007052BC push eax
007052BD push offset string "%\xd4\xc2\xca\xc7\xb4\xba\xbc\xbe\xa1\xa3\n" (0707CF0h)
007052C2 call _printf (07013ACh)
007052C7 add esp,8
007052CA jmp __$EncStackInitStart+0CEh (070533Ah)

//else if (month >= 6 && month <= 8)
007052CC cmp dword ptr [month],6
007052D0 jl __$EncStackInitStart+7Fh (07052EBh)
007052D2 cmp dword ptr [month],8
007052D6 jg __$EncStackInitStart+7Fh (07052EBh)
//printf("%d月是夏季。\n", month);
007052D8 mov eax,dword ptr [month]
007052DB push eax
007052DC push offset string "%d\xd4\xc2\xca\xc7\xcf\xc4\xbc\xbe\xa1\xa3\n" (0707E3Ch)
007052E1 call _printf (07013ACh)
007052E6 add esp,8
007052E9 jmp __$EncStackInitStart+0CEh (070533Ah)
//else if (month >= 9 && month <= 11)
007052EB cmp dword ptr [month],9
007052EF jl __$EncStackInitStart+9Eh (070530Ah)
007052F1 cmp dword ptr [month],0Bh
007052F5 jg __$EncStackInitStart+9Eh (070530Ah)
//printf("%d月是秋季。\n", month);
007052F7 mov eax,dword ptr [month]
007052FA push eax
007052FB push offset string "%d\xd4\xc2\xca\xc7\xc7\xef\xbc\xbe\xa1\xa3\n" (0707CD8h)
00705300 call _printf (07013ACh)
00705305 add esp,8
00705308 jmp __$EncStackInitStart+0CEh (070533Ah)

//else if (month == 1 || month == 2)
0070530A cmp dword ptr [month],1
0070530E je __$EncStackInitStart+0AAh (0705316h)
00705310 cmp dword ptr [month],2
00705314 jne __$EncStackInitStart+0BDh (0705329h)
//printf("%d月是冬季。\n", month);
00705316 mov eax,dword ptr [month]
00705319 push eax
0070531A push offset string "%d\xd4\xc2\xca\xc7\xb6\xac\xbc\xbe\xa1\xa3\n" (0707BD8h)
0070531F call _printf (07013ACh)
00705324 add esp,8
00705327 jmp __$EncStackInitStart+0CEh (070533Ah)
//else
//printf("%d月不存在!!\a\n", month);
00705329 mov eax,dword ptr [month]
0070532C push eax
0070532D push offset string "%d\xd4\xc2\xb2\xbb\xb4\xe6\xd4\xda!!\x07\n" (0707BE8h)
00705332 call _printf (07013ACh)
00705337 add esp,8

//return 0;
0070533A xor eax,eax

短路求值

9
10

在《80386汇编-条件处理》这篇笔记中有演示使用短路求值优化代码,这里也是一个意思。我们优先判断重要的表达式,如果该表达式不成立,那么后续就不需要再去判断;如果表达式成立,再去判断第二个表达式。

switch语句

if语句是将程序分成两个分支,switch 语句,则会将程序分为多个分支。

switch 语句和break语句

显示输入的整数除以3所得余数的程序

代码清单3-18

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:list0318.c*/
/*
显示所输入的整数除以3的余数(if语句)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int no;

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

if (no % 3 == 0)
puts("该数能被3整除。");
else if (no % 3 == 1)
puts("该数除以3的余数是1。");
else
puts("该数除以3的余数是2。");

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
//if (no % 3 == 0)
005A52AD mov eax,dword ptr [no]
005A52B0 cdq
005A52B1 mov ecx,3
005A52B6 idiv eax,ecx
005A52B8 test edx,edx
005A52BA jne __$EncStackInitStart+69h (05A52D5h)
//puts("该数能被3整除。");
005A52BC mov esi,esp
005A52BE push offset string "\xb8\xc3\xca\xfd\xc4\xdc\xb1\xbb3\xd5\xfb\xb3\xfd\xa1\xa3" (05A7CF0h)
005A52C3 call dword ptr [__imp__puts (05AB170h)]
005A52C9 add esp,4
005A52CC cmp esi,esp
005A52CE call __RTC_CheckEsp (05A1230h)
005A52D3 jmp __$EncStackInitStart+0A9h (05A5315h)

//else if (no % 3 == 1)
005A52D5 mov eax,dword ptr [no]
005A52D8 cdq
005A52D9 mov ecx,3
005A52DE idiv eax,ecx
005A52E0 cmp edx,1
005A52E3 jne __$EncStackInitStart+92h (05A52FEh)
//puts("该数除以3的余数是1。");
005A52E5 mov esi,esp
005A52E7 push offset string "\xb8\xc3\xca\xfd\xb3\xfd\xd2\xd43\xb5\xc4\xd3\xe0\xca\xfd\xca\xc71\xa1\xa3" (05A7E3Ch)
005A52EC call dword ptr [__imp__puts (05AB170h)]
005A52F2 add esp,4
005A52F5 cmp esi,esp
005A52F7 call __RTC_CheckEsp (05A1230h)
005A52FC jmp __$EncStackInitStart+0A9h (05A5315h)
//else
//puts("该数除以3的余数是2。");
005A52FE mov esi,esp
005A5300 push offset string "\xb8\xc3\xca\xfd\xb3\xfd\xd2\xd43\xb5\xc4\xd3\xe0\xca\xfd\xca\xc72\xa1\xa3" (05A7CD8h)
005A5305 call dword ptr [__imp__puts (05AB170h)]
005A530B add esp,4
005A530E cmp esi,esp
005A5310 call __RTC_CheckEsp (05A1230h)

代码清单3-19

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:list0319.c*/
/*
显示所输入的整数除以3的余数(switch语句)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int no;

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

switch (no % 3)
{
case 0: puts("该数能被3整除。"); break;
case 1: puts("该数除以3的余数是1。"); break;
case 2: puts("该数除以3的余数是2。"); break;
}

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
//switch (no % 3)
007D52AD mov eax,dword ptr [no]
007D52B0 cdq
007D52B1 mov ecx,3
007D52B6 idiv eax,ecx
007D52B8 mov dword ptr [ebp-0D4h],edx
007D52BE cmp dword ptr [ebp-0D4h],0
007D52C5 je __$EncStackInitStart+6Fh (07D52DBh)
007D52C7 cmp dword ptr [ebp-0D4h],1
007D52CE je __$EncStackInitStart+88h (07D52F4h)
007D52D0 cmp dword ptr [ebp-0D4h],2
007D52D7 je __$EncStackInitStart+0A1h (07D530Dh)
007D52D9 jmp __$EncStackInitStart+0B8h (07D5324h)
//{
//case 0: puts("该数能被3整除。"); break;
007D52DB mov esi,esp
007D52DD push offset string "\xb8\xc3\xca\xfd\xc4\xdc\xb1\xbb3\xd5\xfb\xb3\xfd\xa1\xa3" (07D7CF0h)
007D52E2 call dword ptr [__imp__puts (07DB170h)]
007D52E8 add esp,4
007D52EB cmp esi,esp
007D52ED call __RTC_CheckEsp (07D1230h)
007D52F2 jmp __$EncStackInitStart+0B8h (07D5324h)

//case 1: puts("该数除以3的余数是1。"); break;
007D52F4 mov esi,esp
007D52F6 push offset string "\xb8\xc3\xca\xfd\xb3\xfd\xd2\xd43\xb5\xc4\xd3\xe0\xca\xfd\xca\xc71\xa1\xa3" (07D7E3Ch)
007D52FB call dword ptr [__imp__puts (07DB170h)]
007D5301 add esp,4
007D5304 cmp esi,esp
007D5306 call __RTC_CheckEsp (07D1230h)
007D530B jmp __$EncStackInitStart+0B8h (07D5324h)

//case 2: puts("该数除以3的余数是2。"); break;
007D530D mov esi,esp
007D530F push offset string "\xb8\xc3\xca\xfd\xb3\xfd\xd2\xd43\xb5\xc4\xd3\xe0\xca\xfd\xca\xc72\xa1\xa3" (07D7CD8h)
007D5314 call dword ptr [__imp__puts (07DB170h)]
007D531A add esp,4
007D531D cmp esi,esp
007D531F call __RTC_CheckEsp (07D1230h)
// }

//return 0;
007D5324 xor eax,eax

当case判断语句小于等于3个时:switch语句是将 case 后面的整数作为判断值进行判断并跳转到相应位置。break 语句就是使用jmp 指令跳出switch语句。关键特征:会有连续的cmp和JCC指令。

代码清单3-19-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
/*程序名:list0319_1.c*/
/*
确认switch语句动作的程序(连续的4个case语句)。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int sw;

printf("整数:");
scanf("%d", &sw);

switch (sw%3)
{
case 0: puts("A"); break;
case 1: puts("C");
case 2: puts("D"); break;
case 3: puts("B");
}

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
//switch (sw%3)
00F152AD mov eax,dword ptr [sw]
00F152B0 cdq
00F152B1 mov ecx,3
00F152B6 idiv eax,ecx
00F152B8 mov dword ptr [ebp-0D4h],edx
00F152BE cmp dword ptr [ebp-0D4h],3
00F152C5 ja $LN7+17h (0F15334h)
00F152C7 mov edx,dword ptr [ebp-0D4h]
00F152CD jmp dword ptr [edx*4+0F15380h]
//{
//case 0: puts("A"); break;
00F152D4 mov esi,esp
00F152D6 push offset string "A" (0F17CF0h)
00F152DB call dword ptr [__imp__puts (0F1B170h)]
00F152E1 add esp,4
00F152E4 cmp esi,esp
00F152E6 call __RTC_CheckEsp (0F11230h)
00F152EB jmp $LN7+17h (0F15334h)

//case 1: puts("C");
00F152ED mov esi,esp
00F152EF push offset string "C" (0F17E3Ch)
00F152F4 call dword ptr [__imp__puts (0F1B170h)]
00F152FA add esp,4
00F152FD cmp esi,esp
00F152FF call __RTC_CheckEsp (0F11230h)

//case 2: puts("D"); break;
00F15304 mov esi,esp
00F15306 push offset string "D" (0F17CD8h)
00F1530B call dword ptr [__imp__puts (0F1B170h)]
00F15311 add esp,4
00F15314 cmp esi,esp
00F15316 call __RTC_CheckEsp (0F11230h)
00F1531B jmp $LN7+17h (0F15334h)

//case 3: puts("B");
00F1531D mov esi,esp
00F1531F push offset string "B" (0F17B34h)
00F15324 call dword ptr [__imp__puts (0F1B170h)]
00F1532A add esp,4
00F1532D cmp esi,esp
00F1532F call __RTC_CheckEsp (0F11230h)
//}

//return 0;
00F15334 xor eax,eax

11

当case判断语句大于3个,且判断的整数是连续时,switch 语句会生成一个地址表。switch 语句会先去判断当前整数是否大于 case 语句中【最大的整数-最小整数】的值(因此是指令 cmp xxx,[3-0]),如果大于就退出switch语句,如果不大于,switch 就会将【switch的整数*4+地址表的偏移地址】,以此来跳转到相应的case语句。

代码清单3-19-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
/*程序名:list0319_2.c*/
/*
确认switch语句动作的程序(当case语句不是从0开始)。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int sw;

printf("整数:");
scanf("%d", &sw);

switch (sw%3)
{
case 1: puts("A"); break;
case 2: puts("C");
case 3: puts("D"); break;
case 4: puts("B");
}

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
//switch (sw%3)
008652AD mov eax,dword ptr [sw]
008652B0 cdq
008652B1 mov ecx,3
008652B6 idiv eax,ecx
008652B8 mov dword ptr [ebp-0D4h],edx
008652BE mov edx,dword ptr [ebp-0D4h]
008652C4 sub edx,1
008652C7 mov dword ptr [ebp-0D4h],edx
008652CD cmp dword ptr [ebp-0D4h],3
008652D4 ja $LN7+17h (0865343h)
008652D6 mov eax,dword ptr [ebp-0D4h]
008652DC jmp dword ptr [eax*4+86538Ch]
//{
//case 1: puts("A"); break;
008652E3 mov esi,esp
008652E5 push offset string "A" (0867CF0h)
008652EA call dword ptr [__imp__puts (086B170h)]
008652F0 add esp,4
008652F3 cmp esi,esp
008652F5 call __RTC_CheckEsp (0861230h)
008652FA jmp $LN7+17h (0865343h)
//case 2: puts("C");
008652FC mov esi,esp
008652FE push offset string "C" (0867E3Ch)
00865303 call dword ptr [__imp__puts (086B170h)]
00865309 add esp,4
0086530C cmp esi,esp
0086530E call __RTC_CheckEsp (0861230h)
//case 3: puts("D"); break;
00865313 mov esi,esp
00865315 push offset string "D" (0867CD8h)
0086531A call dword ptr [__imp__puts (086B170h)]
00865320 add esp,4
00865323 cmp esi,esp
00865325 call __RTC_CheckEsp (0861230h)
0086532A jmp $LN7+17h (0865343h)
//case 4: puts("B");
0086532C mov esi,esp
0086532E push offset string "B" (0867B34h)
00865333 call dword ptr [__imp__puts (086B170h)]
00865339 add esp,4
0086533C cmp esi,esp
0086533E call __RTC_CheckEsp (0861230h)
//}

//return 0;
00865343 xor eax,eax

代码清单3-19-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
/*程序名:list0319_3.c*/
/*
确认switch语句动作的程序(当case语句不是从0开始)。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int sw;

printf("整数:");
scanf("%d", &sw);

switch (sw%3)
{
case 2: puts("A"); break;
case 3: puts("C");
case 4: puts("D"); break;
case 5: puts("B");
}

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
//switch (sw%3)
000A52AD mov eax,dword ptr [sw]
000A52B0 cdq
000A52B1 mov ecx,3
000A52B6 idiv eax,ecx
000A52B8 mov dword ptr [ebp-0D4h],edx
000A52BE mov edx,dword ptr [ebp-0D4h]
000A52C4 sub edx,2
000A52C7 mov dword ptr [ebp-0D4h],edx
000A52CD cmp dword ptr [ebp-0D4h],3
000A52D4 ja $LN7+17h (0A5343h)
000A52D6 mov eax,dword ptr [ebp-0D4h]
000A52DC jmp dword ptr [eax*4+0A538Ch]
//{
//case 2: puts("A"); break;
000A52E3 mov esi,esp
000A52E5 push offset string "A" (0A7CF0h)
000A52EA call dword ptr [__imp__puts (0AB170h)]
000A52F0 add esp,4
000A52F3 cmp esi,esp
000A52F5 call __RTC_CheckEsp (0A1230h)
000A52FA jmp $LN7+17h (0A5343h)
//case 3: puts("C");
000A52FC mov esi,esp
000A52FE push offset string "C" (0A7E3Ch)
000A5303 call dword ptr [__imp__puts (0AB170h)]
000A5309 add esp,4
000A530C cmp esi,esp
000A530E call __RTC_CheckEsp (0A1230h)
//case 4: puts("D"); break;
000A5313 mov esi,esp
000A5315 push offset string "D" (0A7CD8h)
000A531A call dword ptr [__imp__puts (0AB170h)]
000A5320 add esp,4
000A5323 cmp esi,esp
000A5325 call __RTC_CheckEsp (0A1230h)
000A532A jmp $LN7+17h (0A5343h)
//case 5: puts("B");
000A532C mov esi,esp
000A532E push offset string "B" (0A7B34h)
000A5333 call dword ptr [__imp__puts (0AB170h)]
000A5339 add esp,4
000A533C cmp esi,esp
000A533E call __RTC_CheckEsp (0A1230h)
//}

//return 0;
000A5343 xor eax,eax

当case判断不是从0开始,switch 语句会增加指令 【sub switch的整数,case最小的整数】

代码清单3-19-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
/*程序名:list0319_4.c*/
/*
确认switch语句动作的程序。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int sw;

printf("整数:");
scanf("%d", &sw);

switch (sw%3)
{
case 1: puts("A"); break;
case 2: puts("C");
case 5: puts("D"); break;
case 6: puts("B");
case 7: puts("E"); break;
}

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
//switch (sw%3)
003052AD mov eax,dword ptr [sw]
003052B0 cdq
003052B1 mov ecx,3
003052B6 idiv eax,ecx
003052B8 mov dword ptr [ebp-0D4h],edx
003052BE mov edx,dword ptr [ebp-0D4h]
003052C4 sub edx,1
003052C7 mov dword ptr [ebp-0D4h],edx
003052CD cmp dword ptr [ebp-0D4h],6
003052D4 ja $LN8+17h (030535Eh)
003052DA mov eax,dword ptr [ebp-0D4h]
003052E0 jmp dword ptr [eax*4+3053A8h]
//{
//case 1: puts("A"); break;
003052E7 mov esi,esp
003052E9 push offset string "A" (0307CF0h)
003052EE call dword ptr [__imp__puts (030B170h)]
003052F4 add esp,4
003052F7 cmp esi,esp
003052F9 call __RTC_CheckEsp (0301230h)
003052FE jmp $LN8+17h (030535Eh)
//case 2: puts("C");
00305300 mov esi,esp
00305302 push offset string "C" (0307E3Ch)
00305307 call dword ptr [__imp__puts (030B170h)]
0030530D add esp,4
00305310 cmp esi,esp
00305312 call __RTC_CheckEsp (0301230h)
//case 5: puts("D"); break;
00305317 mov esi,esp
00305319 push offset string "D" (0307CD8h)
0030531E call dword ptr [__imp__puts (030B170h)]
00305324 add esp,4
00305327 cmp esi,esp
00305329 call __RTC_CheckEsp (0301230h)
0030532E jmp $LN8+17h (030535Eh)
//case 6: puts("B");
00305330 mov esi,esp
00305332 push offset string "B" (0307B34h)
00305337 call dword ptr [__imp__puts (030B170h)]
0030533D add esp,4
00305340 cmp esi,esp
00305342 call __RTC_CheckEsp (0301230h)
//case 7: puts("E"); break;
00305347 mov esi,esp
00305349 push offset string "E" (0307B38h)
0030534E call dword ptr [__imp__puts (030B170h)]
00305354 add esp,4
00305357 cmp esi,esp
00305359 call __RTC_CheckEsp (0301230h)
//}

//return 0;
0030535E xor eax,eax

12
13

如果case语句判断值不是连续的整数,那么switch地址表空出来的位置都会用 switch 语句后的地址作为填充。特征:填充的地址与break语句(jmp)跳转的地址是一样的。

代码清单3-19-5

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
/*程序名:list0319_5.c*/
/*
确认switch语句动作的程序。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int sw;

printf("整数:");
scanf("%d", &sw);

switch (sw)
{
case 1: puts("A"); break;
case 2: puts("C");
case 5: puts("D"); break;
case 6:
case 7: puts("E"); break;
}

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
//switch (sw)
010152AD mov eax,dword ptr [sw]
010152B0 mov dword ptr [ebp-0D4h],eax
010152B6 mov ecx,dword ptr [ebp-0D4h]
010152BC sub ecx,1
010152BF mov dword ptr [ebp-0D4h],ecx
010152C5 cmp dword ptr [ebp-0D4h],6
010152CC ja $LN8+17h (0101533Bh)
010152CE mov edx,dword ptr [ebp-0D4h]
010152D4 jmp dword ptr [edx*4+1015384h]
//{
//case 1: puts("A"); break;
010152DB mov esi,esp
010152DD push offset string "A" (01017CF0h)
010152E2 call dword ptr [__imp__puts (0101B170h)]
010152E8 add esp,4
010152EB cmp esi,esp
010152ED call __RTC_CheckEsp (01011230h)
010152F2 jmp $LN8+17h (0101533Bh)
//case 2: puts("C");
010152F4 mov esi,esp
010152F6 push offset string "C" (01017E3Ch)
010152FB call dword ptr [__imp__puts (0101B170h)]
01015301 add esp,4
01015304 cmp esi,esp
01015306 call __RTC_CheckEsp (01011230h)
//case 5: puts("D"); break;
0101530B mov esi,esp
0101530D push offset string "D" (01017CD8h)
01015312 call dword ptr [__imp__puts (0101B170h)]
01015318 add esp,4
0101531B cmp esi,esp
0101531D call __RTC_CheckEsp (01011230h)
01015322 jmp $LN8+17h (0101533Bh)
//case 6:
//case 7: puts("E"); break;
01015324 mov esi,esp
01015326 push offset string "E" (01017B34h)
0101532B call dword ptr [__imp__puts (0101B170h)]
01015331 add esp,4
01015334 cmp esi,esp
01015336 call __RTC_CheckEsp (01011230h)
//}

//return 0;
0101533B xor eax,eax

1414

如果有case判断中没有语句块,那么switch地址表中填充相邻的下一个case语句的地址。

例如:

1
2
case 5:
case 6: xxxx

此时switch表中就会填充 case 6 的地址。

代码清单3-19-6

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
/*程序名:list0319_5.c*/
/*
确认switch语句动作的程序。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int sw;

printf("整数:");
scanf("%d", &sw);

switch (sw)
{
case 1: puts("A"); break;
case 2: puts("C");
case 5: break;
case 6:
case 7: puts("E"); break;
}

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
//switch (sw)
009552AD mov eax,dword ptr [sw]
009552B0 mov dword ptr [ebp-0D4h],eax
009552B6 mov ecx,dword ptr [ebp-0D4h]
009552BC sub ecx,1
009552BF mov dword ptr [ebp-0D4h],ecx
009552C5 cmp dword ptr [ebp-0D4h],6
009552CC ja $LN8+17h (0955324h)
009552CE mov edx,dword ptr [ebp-0D4h]
009552D4 jmp dword ptr [edx*4+955370h]
//{
//case 1: puts("A"); break;
009552DB mov esi,esp
009552DD push offset string "A" (0957CF0h)
009552E2 call dword ptr [__imp__puts (095B170h)]
009552E8 add esp,4
009552EB cmp esi,esp
009552ED call __RTC_CheckEsp (0951230h)
009552F2 jmp $LN8+17h (0955324h)
//case 2: puts("C");
009552F4 mov esi,esp
009552F6 push offset string "C" (0957E3Ch)
009552FB call dword ptr [__imp__puts (095B170h)]
00955301 add esp,4
00955304 cmp esi,esp
00955306 call __RTC_CheckEsp (0951230h)
//case 5: break;
0095530B jmp $LN8+17h (0955324h)
//case 6:
//case 7: puts("E"); break;
0095530D mov esi,esp
0095530F push offset string "E" (0957CD8h)
00955314 call dword ptr [__imp__puts (095B170h)]
0095531A add esp,4
0095531D cmp esi,esp
0095531F call __RTC_CheckEsp (0951230h)
//}

//return 0;
00955324 xor eax,eax

15

如果case没有语句块,且下面相邻的case也没有语句块,那么 switch 表中填充switch语句后的地址。

复杂的 switch 语句

通过复杂的switch语句来加深对该语句的理解。

代码清单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
/*程序名:list0320.c*/
/*
确认switch语句动作的程序。
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int sw;

printf("整数:");
scanf("%d", &sw);

switch (sw)
{
case 1: puts("A"); break;
case 2: puts("C");
case 5: puts("D"); break;
case 6:
case 7: puts("E"); break;
default:puts("F"); break;
}

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
//switch (sw)
00F552AD mov eax,dword ptr [sw]
00F552B0 mov dword ptr [ebp-0D4h],eax
00F552B6 mov ecx,dword ptr [ebp-0D4h]
00F552BC sub ecx,1
00F552BF mov dword ptr [ebp-0D4h],ecx
00F552C5 cmp dword ptr [ebp-0D4h],6
00F552CC ja $LN8+19h (0F5533Dh)
00F552CE mov edx,dword ptr [ebp-0D4h]
00F552D4 jmp dword ptr [edx*4+0F553A0h]
//{
//case 1: puts("A"); break;
00F552DB mov esi,esp
00F552DD push offset string "A" (0F57CF0h)
00F552E2 call dword ptr [__imp__puts (0F5B170h)]
00F552E8 add esp,4
00F552EB cmp esi,esp
00F552ED call __RTC_CheckEsp (0F51230h)
00F552F2 jmp $LN8+30h (0F55354h)
//case 2: puts("C");
00F552F4 mov esi,esp
00F552F6 push offset string "C" (0F57E3Ch)
00F552FB call dword ptr [__imp__puts (0F5B170h)]
00F55301 add esp,4
00F55304 cmp esi,esp
00F55306 call __RTC_CheckEsp (0F51230h)
//case 5: puts("D"); break;
00F5530B mov esi,esp
00F5530D push offset string "D" (0F57CD8h)
00F55312 call dword ptr [__imp__puts (0F5B170h)]
00F55318 add esp,4
00F5531B cmp esi,esp
00F5531D call __RTC_CheckEsp (0F51230h)
00F55322 jmp $LN8+30h (0F55354h)
//case 6:
//case 7: puts("E"); break;
00F55324 mov esi,esp
00F55326 push offset string "E" (0F57B34h)
00F5532B call dword ptr [__imp__puts (0F5B170h)]
00F55331 add esp,4
00F55334 cmp esi,esp
00F55336 call __RTC_CheckEsp (0F51230h)
00F5533B jmp $LN8+30h (0F55354h)
//default:puts("F"); break;
00F5533D mov esi,esp
00F5533F push offset string "F" (0F57B38h)
00F55344 call dword ptr [__imp__puts (0F5B170h)]
00F5534A add esp,4
00F5534D cmp esi,esp
00F5534F call __RTC_CheckEsp (0F51230h)
//}

//return 0;
00F55354 xor eax,eax

16

添加default语句后,switch地址表中空出来的位置都会插入 default 语句的地址。

switch 语句和if语句

17

选择语句: 本章学习的 if 语句和 switch 语句,都是用来实现程序流程的选择性分支的,因此统称为选择语句。

总结

summary1.c

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
/*程序名:summary1.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int month;

printf("请输入月份:");
scanf("%d", &month);

if (month < 1 || month>12)
printf("%d月不存在!!\a\n", month);
else if (month <= 2 || month == 12)
printf("%d月是冬季。\n", month);
else if (month >= 9)
printf("%d月是秋季。\n", month);
else if (month >= 6)
printf("%d月是夏季。\n", month);
else
printf("%d月是春季。\n", month);

return 0;
}

summary2.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*程序名:summary2.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int sw;

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

switch (sw)
{
case 1: printf("红色"); break;
case 2: printf("蓝色"); break;
case 3: printf("白色"); break;
}

return 0;
}

summary3.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*程序名:summary3.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

int main(void)
{
int n1, n2;
printf("请输入两个整数;");
scanf("%d%d", &n1,&n2);

if (n1 > n2)
{
printf("较大的数是n1。\n");
printf("它们的差是%d。\n", n1 - n2);
}
else
{
printf("较大的数是n2。\n");
printf("它们的差是%d。\n", n2 - n1);
}

return 0;
}

课后练习

练习3-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
/*程序名:lx3-1.c*/
/*
编写一段程序,像下面这样输入两个整数值,如何后者是前者的约数,
则显示“B是A的约数”。如果不是,则显示“B不是A的约数”。
请输入两个整数。
整数A:
整数B:
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

if (x % y)
{
printf("%d不是%d的约数。\n", y, x);
}
else
{
printf("%d是%d的约数。", y, x);
}
return 0;
}

练习3-2

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
/*程序名:lx3-2.c*/
/*
将 T3-9.c 中的 else 改为 else if 结果正确
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

if (x > 0)
{
puts("输入的值是正数");
}
else if (x < 0)
{
puts("输入的值是负数");
}
else if (x == 0)
{
puts("输入的值是0");
}
return 0;
}

练习3-3

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
/*程序名:lx3-3.c*/
/*
编写一个程序,像下面这样输入一个整数值,然后显示出它的绝对值

请输入一个整数:-8
绝对值是8.
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

if (x > 0)
{
printf("绝对值是%d.\n", x);
}
else if (x == 0)
{
puts("绝对值是0.");
}
else
{
printf("绝对值是%d.\n", -x); //负数+符号得正数
}
return 0;
}

练习3-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
26
27
28
29
30
/*程序名:lx3-4.c*/
/*
编写一个程序,像下面这样输入两个整数,
如果两个数值相等,则显示 "A和B相等。"
如果A大于B,显示"A大于B。"
如果A小于B,显示"A小于B。"
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

if (x > y)
{
printf("%d大于%d.\n", x, y);
}
else if (x == y)
{
printf("%d等于%d.\n", x, y);
}
else
{
printf("%d小于%d.\n", x, y);
}
return 0;
}

练习3-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
27
28
/*程序名:lx3-5.c*/
/*
编写一段程序,确认相等运算符和关系运算符的运算结果是1和0
用逻辑运算得结果 1 和 0 ,判断输入的值是正数、负数还是0
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

if ((x > 0) == 1)
{
printf("%d是正数.\n", x);
}
else if ((x == 0) == 1)
{
printf("输入的值是0.\n");
}
else
{
printf("%d是负数.\n", x);
}
return 0;
}

练习3-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
/*程序名:lx3-6.c*/
/*
使用 if 语句
编写一段程序,计算输入的三个整数中最小的值,并显示
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

min = x;
if (x > y)
min = y;
if (x > z)
min = z;
printf("三个整数中最小的是%d.\n", min);

return 0;
}

练习3-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
/*程序名:lx3-7.c*/
/*
使用 if 语句
编写一段程序,计算输入的四个整数中最大的值,并显示
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int x, y, z, o, max;
printf("请输入四个整数:"); scanf("%d%d%d%d", &x, &y, &z, &o);

max = x;
if (x < y)
max = y;
if (x < z)
max = z;
if (x < o)
max = o;
printf("四个整数中最大的是%d.\n", max);

return 0;
}

练习3-8

25

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*程序名:lx3-8.c*/
/*
使用if语句替换代码清单3-15程序中的条件运算符,实现同样的功能。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

if (x > y)
z = x - y;
else
z = y - x;

printf("两个整数的差为%d.\n", z);

return 0;
}

练习3-9

26

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*程序名:lx3-9.c*/
/*
使用条件运算符替换练习3-6的程序中的if语句,实现同样的功能
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

(x == y) ? printf("输入的两个值相等\n") : printf("输入的两个值不相等\n");

return 0;
}

练习3-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
26
27
28
29
30
31
32
33
34
35
36
37
38
/*程序名:lx3-10.c*/
/*
编写一段程序,像下面这样输入三个整数,
如果三个数都相等,则显示“三个值都相等。”
如果其中任意两个值相等,则显示“有两个值相等”。
如果上述情况都不满足,则显示“三个值各不相同。”
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

if (x == y == z)
{
puts("三个值都相等。");
}
else if ((x != z) && (x == y))
{
puts("有两个值相等。");
}
else if ((x != y) && (x == z))
{
puts("有两个值相等。");
}
else if ((y != x) && (y == z))
{
puts("有两个值相等。");
}
else
{
puts("三个值各不相同。");
}
return 0;
}

练习3-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
26
/*程序名:lx3-11.c*/
/*
编写一个程序,像右面这样输入两个整数,
如果它们的差值小于等于10,则显示“它们的差小于等于10。
”否则,显示“它们的差大于等于11”。
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

int main(void)
{
int x, y, z;
printf("请输入两个整数:"); scanf("%d%d", &x, &y);
z = (x > y) ? (x - y) : (y - x);

if (z <= 10)
{
puts("它们的差小于等于10");
}
else
{
puts("它们的差大于等于 11 。");
}
return 0;
}

练习 3-12

29

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*程序名:lx3-12.c*/
/*
输入的整数是奇数吗
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

(x % 3 == 0) ? printf("输入的整数是奇数。\n") : printf("输入的整数是偶数\n");

return 0;
}

练习3-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
26
27
28
29
30
31
32
33
/*程序名:lx3-13.c*/
/*
判断输入的月份是哪个季节
对代码清单3-17中的程序进行修改,不使用if语句,改用switch语句
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>

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

switch (x)
{
case 1: printf("%d月份是冬季。\n", x); break;
case 2: printf("%d月份是冬季。\n", x); break;
case 3: printf("%d月份是冬季。\n", x); break;
case 4: printf("%d月份是春季。\n", x); break;
case 5: printf("%d月份是春季。\n", x); break;
case 6: printf("%d月份是春季。\n", x); break;
case 7: printf("%d月份是夏季。\n", x); break;
case 8: printf("%d月份是夏季。\n", x); break;
case 9: printf("%d月份是夏季。\n", x); break;
case 10: printf("%d月份是秋季。\n", x); break;
case 11: printf("%d月份是秋季。\n", x); break;
case 12: printf("%d月份是秋季。\n", x); break;
default: printf("输入错误。\n");
}

return 0;
}
  • 本文标题:C语言语法入门-分支结构程序
  • 本文作者:9unk
  • 创建时间:2023-05-11 11:00:00
  • 本文链接:https://9unkk.github.io/2023/05/11/c-yu-yan-yu-fa-ru-men-fen-zhi-jie-gou-cheng-xu/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!