C 语言编程 — 逻辑控制语句
【摘要】 目录
文章目录
目录前文列表结构化程序设计条件分支语句if/else 语句if 语句if/else 语句if/else-if/else 语句嵌套 if 语句 switch 语句switch 语句嵌套 switch 语句 三元运算符条件语句编程风格
循环语句for 循环嵌套 for 循环while 循环嵌套 while 循环do/while 循环嵌套 do/...
目录
前文列表
《程序编译流程与 GCC 编译器》
《C 语言编程 — 基本语法》
《C 语言编程 — 基本数据类型》
《C 语言编程 — 变量与常量》
《C 语言编程 — 运算符》
结构化程序设计
结构化程序:采用结构化算法化繁为简地把一个复杂问题的求解过程分成可控、易理解和易处理的阶段进行,实现一个便于编写、阅读、修改和维护的程序。
三种基本结构:1966 年,Bohra 和 Jacopini 提出顺序结构、选择结构和循环结构三种基本结构,用这三种基本结构作为表示一个良好算法的基本单元。
- 顺序结构:是由一组顺序执行的程序块组成。程序按照语句书写的顺序一步一步顺序执行,没有任何的跳转。
- 选择结构:依据不同的条件选择执行不同的处理块。可以采用 if/else 语句、switch 语句,还有条件运算符来实现选择结构。
- 循环结构:又称重复结构,反复执行某一部分的操作。
条件分支语句
条件分支语句可以让程序在只有条件为真的时候才去执行一段代码。
if/else 语句
if 语句
#include <stdio.h>
int main ()
{ /* 局部变量定义 */ int a = 10; /* 使用 if 语句检查布尔条件 */ if( a < 20 ) { /* 如果条件为真,则输出下面的语句 */ printf("a 小于 20\n" ); } printf("a 的值是 %d\n", a); return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
if/else 语句
#include <stdio.h>
int main ()
{ /* 局部变量定义 */ int a = 100; /* 检查布尔条件 */ if( a < 20 ) { /* 如果条件为真,则输出下面的语句 */ printf("a 小于 20\n" ); } else { /* 如果条件为假,则输出下面的语句 */ printf("a 大于 20\n" ); } printf("a 的值是 %d\n", a); 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/else-if/else 语句
#include <stdio.h>
int main ()
{ /* 局部变量定义 */ int a = 100; /* 检查布尔条件 */ if( a == 10 ) { /* 如果 if 条件为真,则输出下面的语句 */ printf("a 的值是 10\n" ); } else if( a == 20 ) { /* 如果 else if 条件为真,则输出下面的语句 */ printf("a 的值是 20\n" ); } else if( a == 30 ) { /* 如果 else if 条件为真,则输出下面的语句 */ printf("a 的值是 30\n" ); } else { /* 如果上面条件都不为真,则输出下面的语句 */ printf("没有匹配的值\n" ); } printf("a 的准确值是 %d\n", a ); 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
嵌套 if 语句
#include <stdio.h>
int main ()
{ /* 局部变量定义 */ int a = 100; int b = 200; /* 检查布尔条件 */ if( a == 100 ) { /* 如果条件为真,则检查下面的条件 */ if( b == 200 ) { /* 如果条件为真,则输出下面的语句 */ printf("a 的值是 100,且 b 的值是 200\n" ); } } printf("a 的准确值是 %d\n", a ); printf("b 的准确值是 %d\n", 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
switch 语句
switch(表达式 1)
{ case 常量表达式 1 : 语句组 1; case 常量表达式 2 : 语句组 2; ... case 常量表达式 n : 语句组 n; default : 语句组 n + 1;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
执行过程:
- 先计算表达式 1 的值。
- 然后依次把表达式 1 的值与常量表达式的值进行比较。
- 一旦发现表达式 1 的值能够与某个常量表达式配对, 则以此为入口号,由此开始顺序执行语句。
- 若表达式 1 的值与所有的 case 中的常量表达式均无法匹配, 则执行 default 后的语句组 n + 1。
NOTE:
- default 是个可选项,如果 switch 语句中没有 default 分支,则当 switch 后的表达式与所有的常量表达式都不匹配时,将不执行任何操作。
- 每当表达式 oper 找到匹配的常量表达式时,会把顺序执行剩余的语句组。如果目的只是需要特定的运算结果,这时,可以采用 break 语句退出 switch 结构。
switch 语句
#include <stdio.h>
int main ()
{ /* 局部变量定义 */ char grade = 'B'; switch(grade) { case 'A' : printf("很棒!\n" ); break; case 'B' : case 'C' : printf("做得好\n" ); break; case 'D' : printf("您通过了\n" ); break; case 'F' : printf("最好再试一下\n" ); break; default : printf("无效的成绩\n" ); } printf("您的成绩是 %c\n", grade ); 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
嵌套 switch 语句
switch(ch1) { case 'A': printf("这个 A 是外部 switch 的一部分" ); switch(ch2) { case 'A': printf("这个 A 是内部 switch 的一部分" ); break; case 'B': /* 内部 B case 代码 */ } break; case 'B': /* 外部 B case 代码 */
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
三元运算符
Exp1 ? Exp2 : Exp3;
- 1
#include<stdio.h>
int main()
{ int num; printf("输入一个数字 : "); scanf("%d",&num); (num%2==0)?printf("偶数"):printf("奇数");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
条件语句编程风格
- 浮点变量与零值比较:无论是 float 还是 double 类型的变量,都有精度限制,所以要避免将浮点变量用 == 或 != 与数字进行比较,应该设法转化成 >= 或 <= 的形式。
错误:
if(x == 0.0)
- 1
正确:
if((x >= -EPSINON) && (x <= EPSINON)) // EPSINON是允许的误差(即精度)。
- 1
- 空指针判断:指针变量的零值是 NULL。尽管 NULL 的值与 0 相同,但二者的意义不同。所以应当将指针变量用 == 或 != 与 NULL 比较。
错误:
if(p)
if(!p)
if(p == 0)
if(p != 0) // 容易让人误解 p 是一个整型变量
- 1
- 2
- 3
- 4
正确:
if(p == NULL)
if(p != NULL)
- 1
- 2
- 变量与常量进行比较:应该将常量放在 == 或 != 的左侧。
错误:
if(p = NULL) // 这是一种笔误,但编译器确认为是合法的。
- 1
正确:
if(NULL = p) // 笔误会被编译器检测出来。
- 1
- 始终使用 {}:
错误:
if(condition) return x;
return y;
- 1
- 2
- 3
正确:
if(condition)
{ return x;
}
else
{ return y;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
或者改成更加简练的:
return(condition ?x:y);
- 1
- switch/case 比 if/else 的执行效率更高:因为 switch/case 语句在编译的时候创建了一个 map 存储于 .rodata 只读数据区中,运行的时候直接根据输入的 c 值进行查表,并直接跳转。
#include <stdio.h>
static int
foo_ifelse(char c)
{ if (c == '0' || c == '1') { c += 1; } else if (c == 'a' || c == 'b') { c += 2; } else if (c == 'A' || c == 'B') { c += 3; } else { c += 4; } return (c);
}
static int
foo_switch(char c)
{ switch (c) { case '1': case '0': c += 1; break; case 'b': case 'a': c += 2; break; case 'B': case 'A': c += 3; break; default: c += 4; break; } return (c);
}
int
main(int argc, char **argv)
{ int m1 = foo_ifelse('0'); int m2 = foo_ifelse('1'); int n1 = foo_switch('a'); int n2 = foo_switch('b'); (void) printf("%c %c %c %c\n", m1, m2, n1, 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
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
循环语句
循环可以不断的执行一段代码,直到条件变为假,或者计数完成。
for 循环
for ( init; condition; increment )
{ statement(s);
}
- 1
- 2
- 3
- 4
- init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
- 接下来,会判断 condition。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
- 在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
- 条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,for 循环终止。
#include <stdio.h>
int main ()
{ /* for 循环执行 */ for( int a = 10; a < 20; a = a + 1 ) { printf("a 的值: %d\n", a); } return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
嵌套 for 循环
for (initialization; condition; increment/decrement)
{ statement(s); for (initialization; condition; increment/decrement) { statement(s); ... ... ... } ... ... ...
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
while 循环
#include <stdio.h>
int main ()
{ /* 局部变量定义 */ int a = 10; /* while 循环执行 */ while( a < 20 ) { printf("a 的值: %d\n", a); a++; } return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
嵌套 while 循环
while (condition1)
{ statement(s); while (condition2) { statement(s); ... ... ... } ... ... ...
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
do/while 循环
#include <stdio.h>
int main ()
{ /* 局部变量定义 */ int a = 10; /* do 循环执行 */ do { printf("a 的值: %d\n", a); a = a + 1; }while( a < 20 ); return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
嵌套 do/while 循环
do
{ statement(s); do { statement(s); ... ... ... }while (condition2); ... ... ...
}while (condition1);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
循环语句的编程风格
- 在嵌套循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少 CPU 跨切循环层的次数。
低效率(长循环在最外层):
for(row=0; row<100; row++)
{ for(col=0; col<5;c ol++) { sum = sum + a[row][col]; }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
高效率(长循环在最内层):
for(col=0; col<5; col++)
{ for(row=0; row<100; row++) { sum = sum + a[row][col]; }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。这可能需要对执行效率和代码简洁性作出取舍。
效率低但程序简洁:
for(i = 0; i < N; i++)
{
if(condition) DoSomthing();
else DoSomthing();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
效率高但程序不简洁:
if (condition)
{ for (i=0; i<N; i++) DoSomething();
}
else
{ for (i=0; i<N; i++) DoSomething();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
-
for 语句的循环控制变量:不可以在 for 循环体内修改循环变量,防止 for 循环失去控制。
-
for 语句的循环控制变量的取值采用 “半开半闭区间” 写法。
循环变量属于半开半闭区间:
for(int x = 0;x < N; x++)
- 1
循环变量属于闭区间:
for(int x = 0;x <= N-1; x++)
- 1
循环控制语句
- break
- continue
- goto
循环控制语句编程风格
- switch 语句中,即使程序真的不需要 default 处理,也应该保留 default 语句。
switch variable)
{ case value1: break; case value2: break; default:
break;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 使用 goto 语句从多重循环体中一下子跳到外面,用不着写很多次的 break 语句。
{
{ { goto error; }
}
}
error:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
文章来源: is-cloud.blog.csdn.net,作者:范桂飓,版权归原作者所有,如需转载,请联系作者。
原文链接:is-cloud.blog.csdn.net/article/details/105279461
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)