找回密码
 注册
关于网站域名变更的通知
查看: 370|回复: 2
打印 上一主题 下一主题

单片机C语言If和for等基本语句结构

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-10-28 14:08 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
if和for,这两个从本质上来说,是不是C语言的两个关键字呀。那么我们为什么又把它称之为C语言的基本结构的一部分呢。要回答这个问题,我们是不是首先要搞清楚C语言的基本结构是什么?1 b8 E: M8 H6 O% t& \/ H0 d) V

, O  B6 ~* l8 k0 U4 E6 e" i& [7 l实际上,任何结构化编程语言的基本结构都是相同的,也就是三种基本的程序结构:顺序,分支和循环。由这三者最基本的结构,可以搭建出任何我们想实现的程序结构。在狄杰斯特拉(Edsger W. Dijkstra)反复研究面条式代码(spaghetti code),并在1968年给某位编辑写了一篇著名的简信,题为《Go to语句是有害的》之后,计算机科学家Corrado Bohm和Giuseppe Jacopini证明,使用顺序(sequencing),分支/选择(alternation)和循环(iteration)这三种流程结构就足以表达所有程序的本质。C语言作为结构化编程语言的一种,其程序结构,自然也是由这三种最基本的程序结构组成。
: @( E% I0 ~' `; O: ~+ Y2 J  N1 \! y/ v8 w) {$ F& {
顺序执行程序,这个很好理解,一条语句接着一条语句执行就可以了。那么C语言的分支和循环是如何实现的呢?
& i  Q$ t! p* y1 E* m+ _
1 ?1 _( p& v( ?7 s% n对于分支,我们常见的关键词是不是有if/else和switch/case两种组合呀。if/else翻译过来,是不是就是“如果…,否则…”,是一个条件判断。如果用伪代码的方式来进行表达的话,一般有这两种形式。
/ i( _3 i; q9 z
3 q7 C; H. l9 i- h! s+ R2 u第一种形式如下:$ i' C. ^6 F3 S0 c* L* j, N
if(条件为真)
* k) G' W; p5 C6 d$ D{
+ Q0 v( c* Y: p3 P" P' c) {代码段1;2 f( k  ^+ z" }
}
# k5 r/ s! v- Yelse, ~4 f# M6 t/ `3 |; B! C& C" q& h
{! }) q! @) n- r
代码段2;
; H1 Z8 n( A, a+ n}4 ]: z: P. l: I& q6 z5 T* j2 i
这里else的含义其实就是条件不为真,那么也就是条件为假。
" g+ S% h" I" {2 D3 C
. O2 b! b6 b# I1 ^
第二种形式是这样的:
1 J* @, t+ H& O0 W- R; h! Lif(条件1为真)
  Y/ S2 p" d+ J3 A( j) ?{
' f' k5 o( {/ I7 x5 q- V! s, }代码段1;
! j" i# [/ T% Y% V}( A( u0 ?: @5 Z4 A. h, P
else if(条件2为真)$ n( a' U' |2 O: F+ e+ v
{6 t" p3 A$ l0 U5 p0 S+ N5 S
代码段2;3 |" r/ z4 M4 t+ r- ^
}
) A0 ]9 h0 {# ~else
- z% R8 e( O5 T; D2 I, I{
/ `3 B- _$ D! u7 s; a$ S代码段3;6 V" a( Y4 r* p1 i1 B- w& B8 V
$ _- l$ q* P! c% |+ F
}) N- E2 o4 B6 X- G  ?

0 g) B: ?! U5 B' W& x- V. }, t5 @8 t第一种形式和第二种形式本质上的区别,其实就是第一个是双分支,第二个是多分支。两种不同的分支,我们要根据具体情况去使用。某种意义上多分支模式可以由双分支演变而来,比如我们可以在双分支模式里面的else里嵌套一个双分支结构就可以了。# p7 T6 x* l" |1 I' t4 z1 W8 @2 u
8 M2 W) q# z* ~, s( O

, ]; D7 B1 G6 q9 I7 wif(条件1为真)
0 B7 {& c$ a6 T% N& S7 b, ]{
2 x6 C9 |& |+ ]; S0 L+ \1 M3 _代码段1;
5 @" L0 J0 V6 U}
( M: w2 o' e+ V$ g; ~+ helse  {, s% d. G) q0 r) I1 v
{
. o8 t/ j1 V6 H1 Qif(条件2为真)% k  t+ D8 z& V. o% o
{& C/ X* l( k8 T$ D" x
代码段2;2 z* H# ?* O8 ]; c2 t6 U, \) v
}
: U4 O; X  I& U, @0 B2 helse
8 W+ y% }8 H. q+ T{
3 ?$ V/ G7 g3 X! U9 X代码段3;3 n$ ]9 \; ]1 v3 h/ x5 n0 [: [
}2 \; E' O3 [+ D) p( h
}  g& J& P! f$ Y. ?
从这个意义上看,双分支和多分支其实是一回事情,本质上都是分支。分支这个概念,大家应该都是相对容易接受的,任何一件事情总有它的对立面,高对低,胖对瘦,大对小,物质对暗物质等等。分支这个概念应该是反映了事物的一种本源的状态,是描述程序是不可再进行切分的维度,也就是说分支成为了任何程序的三种基本结构之一。
( q1 {, J: r8 m% z8 O$ E# P+ M. \) ~3 S0 m( K6 }4 I' ]2 D1 `
其实对于多分支的情况,C语言有另外一套关键字组合switch/case,写成伪代码的形式,大概是这样的。
5 {! ]* U/ P) B0 ]
8 d( ?. h1 S/ i+ ?switch(变量){7 ?4 [4 t9 F" z- ?& E$ o4 a
case 常数1:
: ?2 g" a1 M# A% K0 n* @* K& ?) Q代码段1;9 z' Z! E8 |/ s* N  k8 u
break;( G, r4 e( s  e: b
case 常数2:) H! L5 |& O8 R# D$ t" Z' q
代码段2;
. H; V' {4 q3 D" N1 }- fbreak;
, j4 `$ _- J. ~( c/ T- m/ Q6 dcase 常数3:1 f4 i6 ]& K1 V7 q* j
代码段3;; e1 W) I2 `) R# a/ y
break;8 `5 G' H+ U  [# ?
。。。+ y7 n. c- K4 M
default:/ ]. {8 `( s9 ~; N) z8 x7 g
代码段n;/ V% j- D  ?# o+ r" }
break;/ A/ k( c1 @) C
}. j( S: ~8 B! U/ p
2 a( q8 Q/ H2 b  g
大家注意没,对于switch/case组合来说,它的条件一定要是常量,而且要是整数。这个是不是对判断的条件作出了限制呀。这里的default关键字,是和if/else里面的else对应的,表示意外情况。从表面看,switch/case适用于逻辑条件简单,但是分类较多的情况;if/else适用于判断条件复杂,但是分支较少的情况。但是从另外一个层面看来,switch/case所具备的功能,if/else完成起来,完全没有问题呀。那为什么还要搞出来这一个关键字组合呢?9 o! S4 P8 O/ |! ?3 p6 r& d
我个人的理解是switch/case关键字的执行效率,在某些情况下,要比if/else要高。
6 V+ n6 I3 ^% W1 p3 Q: A2 y+ U8 k7 o  G' D
int a = 0;
! C, P' C  b% ?6 E1 cswitch(a)' z$ o9 L3 g/ g
{
3 L3 q& k4 A3 R' n% J5 Gcase -1:
5 e/ Y  N& G2 j% o7 J    break;& u$ V2 {0 y8 V' ]% [7 l# o
case -2:
5 n+ o3 |0 B0 B( i1 _( F! S8 C9 N    break;, n6 V( x1 b( h/ f0 B
case -3:
: K7 r1 E- r' ^  o0 M    break;
5 e9 X( Y& [- V' `0 r* jcase -4:
, `  G) R/ v6 X" G) v    break;  v& f2 a' s; N& p
case 0:
: q7 q8 d$ y0 K( D* b    printf("I am in switch case!\n");
) T8 b! A9 ~. s$ e    break;# N8 |- T8 X' D2 N! O) P5 X. j( \
default:/ j0 d( z# n  L8 `
  break;
! @8 \8 C0 m! L2 V! h' ]}2 O2 Z$ y0 L5 w* |
printf("I am between the switch case and if/else if/else!\n");
/ Y" F$ B. Q- g1 m# ]! eif (-1 == a)
) ^) X$ `/ y* a4 H( j4 h3 E{0 u' ?3 D( Z) Y- h! g2 q% l
}" M$ I& i1 M4 _& D9 y! R4 v* c
else if (-2 == a)
0 |) a1 a4 h; r& U4 }{) f# r6 z9 ]$ E  w; v1 \7 t; H7 z! L
}0 E8 I$ O3 e( [8 A) b7 b! P; n
else if (-3 == a)
7 d5 ~. G2 M  c7 m* U5 K{
8 W4 I8 [, ?3 I6 M5 z5 K}
; S- m9 P* V/ v6 z/ u9 pelse if (-4 == a)7 ]$ o& T, I- e, v4 q! b3 Q3 e
{* g  R" l# Z+ a1 B
}+ Y) K0 }# [& h1 ?, @, q
else if (-5 == a)( V0 a1 n1 P7 I) {- S3 ]3 C) u1 x
{6 T; k0 {$ y+ C2 _% v
}# }2 Z5 n: U5 o- |5 {% o
else
/ [& W0 J4 y7 F+ s( H3 b4 D4 s{
4 y3 C. c0 I' x0 x% ^1 V: \/ u+ `     printf("I am in if/else if/else!\n");
4 t- u2 [4 E4 l* `7 \2 ?}- J" A5 `$ r. `& G# J2 l7 E

9 I- [& q' P& v4 K* |  p比如对于上面的代码段,对于switch/case关键词对来说,程序是直接跳到case为0的情况下的;但是对于if/else而言,程序则是一句一句比较之后才达到了“else”这一句,程序执行效率的高低是显而易见的。/ o# r) U; `5 F1 r& c
8 n$ S; I" r1 j* l/ x! x
但是我们说,switch/case的程序执行效率可以比较高,并不是没有条件的。从汇编语言的层面来看,switch/case是建立了一张跳转表,因此需要一定的空间才行。这里某种程度上有以空间换时间的意思。
" n. n( g# k! Y& Q
0 k" c9 }8 x# z6 `) }! h4 |因此,如果程序可以使用switch/case尽量使用这个,以便提高它的执行效率。其实,我们这样比对一番之后,自己也就轻而易举地牢牢记住了它们,这个可能也就是知其然知其所以然的效果,符合人的记忆规律。+ [, [7 C6 N( }& F/ ?5 r: C: |8 a
, c, R+ b/ d7 e
讲完了分支,我们来看一下循环。循环这个基本结构,在C语言里面,一共有两种实现方式,for循环和while循环,其中while循环还可以分为两种,一种是while循环,一种是do/while循环。我们下面分别看一下,这三种结构的程序表达大概是什么模样。& j; x% ?& b/ [
0 @5 F# \- h8 z: n6 Y/ H' x
for(循环控制变量初始化;循环终止条件;循环控制变量增量){循环体;}( C' p& M8 k8 `! h. m% G
for循环的执行步骤是:首先执行循环变量的初始化,然后执行循环终止条件;如果判断条件为假(不符合终止条件),那么就开始执行循环体;然后执行循环控制变量的增量程序,执行完以后,再去判断是不是符合循环终止条件;如何符合条件,那么就退出循环;如果不符合条件,那么就继续执行循环体,并重复执行上述步骤。
& C; A% G. l+ _3 P/ i. Z3 v7 t, f/ V! q5 ^( F9 `4 O# p
感觉用第二种方式来描述这个循环体的执行过程,更为清晰。第一,先进行循环控制变量初始化;第二,执行循环终止条件,如果判断结果为假,则进入第三步;如果为假则循环终止并退出;第三,执行循环体;第四,执行循环控制变量增量,转入第二步;4 K' _3 l+ j6 I) m* p1 j. @
9 i: e1 E3 s( x1 B" M$ ~
注意,其实for循环括号中的三部分其实都可以省略,如果全部省略了,就变成了一个无限循环的死循环,跳不出来了。无限循环在操作系统中使用的是非常多的,每一个任务都是一个无限循环体,包括main函数也是一个无限循环体。
3 p4 h6 z' d: A5 X6 u: i8 [1 j7 G! `( O9 q; q: G, g  _+ U8 x8 W

' }* U1 J/ ^6 ~- [+ X) @

8 F* F: O& `5 r0 U+ H- J8 e8 u  n$ w, D7 W/ t& |

该用户从未签到

2#
发表于 2021-10-28 14:15 | 只看该作者
任何结构化编程语言的基本结构都是相同的

该用户从未签到

3#
发表于 2021-10-28 16:50 | 只看该作者
两种不同的分支,我们要根据具体情况去使用
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-8-31 20:58 , Processed in 0.125000 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表