C 语言编程 — 逻辑控制语句

举报
云物互联 发表于 2021/08/05 23:36:49 2021/08/05
【摘要】 目录 文章目录 目录前文列表结构化程序设计条件分支语句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 的值。
  2. 然后依次把表达式 1 的值与常量表达式的值进行比较。
  3. 一旦发现表达式 1 的值能够与某个常量表达式配对, 则以此为入口号,由此开始顺序执行语句。
  4. 若表达式 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

条件语句编程风格

  1. 浮点变量与零值比较:无论是 float 还是 double 类型的变量,都有精度限制,所以要避免将浮点变量用 == 或 != 与数字进行比较,应该设法转化成 >= 或 <= 的形式。
    错误:
if(x == 0.0)

  
 
  • 1

正确:

if((x >= -EPSINON) && (x <= EPSINON))  // EPSINON是允许的误差(即精度)。

  
 
  • 1
  1. 空指针判断:指针变量的零值是 NULL。尽管 NULL 的值与 0 相同,但二者的意义不同。所以应当将指针变量用 == 或 != 与 NULL 比较。
    错误:
if(p)
if(!p)
if(p == 0if(p != 0// 容易让人误解 p 是一个整型变量

  
 
  • 1
  • 2
  • 3
  • 4

正确:

if(p == NULL)
if(p != NULL)  

  
 
  • 1
  • 2
  1. 变量与常量进行比较:应该将常量放在 == 或 != 的左侧。
    错误:
if(p = NULL)  // 这是一种笔误,但编译器确认为是合法的。

  
 
  • 1

正确:

if(NULL = p)  // 笔误会被编译器检测出来。

  
 
  • 1
  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
  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
  1. init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
  2. 接下来,会判断 condition。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
  3. 在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
  4. 条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,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

循环语句的编程风格

  1. 在嵌套循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少 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
  1. 如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。这可能需要对执行效率和代码简洁性作出取舍。
    效率低但程序简洁:
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
  1. for 语句的循环控制变量:不可以在 for 循环体内修改循环变量,防止 for 循环失去控制

  2. for 语句的循环控制变量的取值采用 “半开半闭区间” 写法。
    循环变量属于半开半闭区间:

forint x = 0;x < N; x++
 
  • 1

循环变量属于闭区间:

forint x = 0;x <= N-1; x++
 
  • 1

循环控制语句

  • break
    在这里插入图片描述
  • continue
    在这里插入图片描述
  • goto
    在这里插入图片描述

循环控制语句编程风格

  1. switch 语句中,即使程序真的不需要 default 处理,也应该保留 default 语句。
switch variable)
{ case value1: break; case value2: break; default:
		break;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 使用 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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。