找回密码
 注册
查看: 342|回复: 2
打印 上一主题 下一主题

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
if和for,这两个从本质上来说,是不是C语言的两个关键字呀。那么我们为什么又把它称之为C语言的基本结构的一部分呢。要回答这个问题,我们是不是首先要搞清楚C语言的基本结构是什么?8 E. S, E# X# m5 U* N7 V
5 s. r2 H9 k2 R) u3 |
实际上,任何结构化编程语言的基本结构都是相同的,也就是三种基本的程序结构:顺序,分支和循环。由这三者最基本的结构,可以搭建出任何我们想实现的程序结构。在狄杰斯特拉(Edsger W. Dijkstra)反复研究面条式代码(spaghetti code),并在1968年给某位编辑写了一篇著名的简信,题为《Go to语句是有害的》之后,计算机科学家Corrado Bohm和Giuseppe Jacopini证明,使用顺序(sequencing),分支/选择(alternation)和循环(iteration)这三种流程结构就足以表达所有程序的本质。C语言作为结构化编程语言的一种,其程序结构,自然也是由这三种最基本的程序结构组成。
9 n, V4 c$ s2 x& x/ s5 S# S6 p; ]9 v+ a& \$ E
顺序执行程序,这个很好理解,一条语句接着一条语句执行就可以了。那么C语言的分支和循环是如何实现的呢?# x( a: W' ^* T, f$ f  D+ c5 @
1 t. R9 F$ D  S9 U4 `
对于分支,我们常见的关键词是不是有if/else和switch/case两种组合呀。if/else翻译过来,是不是就是“如果…,否则…”,是一个条件判断。如果用伪代码的方式来进行表达的话,一般有这两种形式。1 D( ^$ O$ h8 L& p* g6 v

* d) J/ {: s5 G6 K& o8 Z( m1 j4 _第一种形式如下:
7 `7 b% T3 m7 R4 [& A3 N/ iif(条件为真)
) p" i/ I' ^$ W: M5 G. ~{( A. v1 Y& p, B9 [9 K: J: {
代码段1;. z7 N& I: s$ p3 Y3 J3 s: ]8 Q7 V6 t6 e
}
$ |0 S' s; O! U' y8 ?else
' M0 h) m$ ]0 P+ L: v{1 d5 m7 H; m' X) F
代码段2;; |' S& [2 s  Y, {7 v2 t1 n
}8 M' W: ^0 l% O: L6 J% x! _  y
这里else的含义其实就是条件不为真,那么也就是条件为假。

: E& R8 X, Q# k0 v: n& r
* T) {) s, l7 H0 v. O! e; \第二种形式是这样的:
: l' q  {6 E0 wif(条件1为真)/ i4 S& l; Y- P; C8 J
{
( j# K8 o/ V3 H9 X+ [# t代码段1;! P1 D/ A2 E# G. \0 I! W2 j  g6 U$ D8 V
}
! T+ z2 x& `# v- F. ]else if(条件2为真)
3 {+ p) \& ], s0 V5 T1 R8 b  F2 I{- z" x( J- I% o
代码段2;
5 L& o' v$ o7 S, d0 h8 h. Q}
5 N) ?3 D# h% E' ielse2 v5 h+ I2 u/ g. ~( l, s
{
1 I8 p# ]7 c. B# z8 T1 a: x7 n+ r代码段3;
% [- ~$ [+ J& y' V, z: v- G4 i: Q0 C% C: z% h* r' ]! x4 m1 o
}
; j- `0 L0 F; Y7 |* m
4 ]6 z" k, U. ^% c  o! p
第一种形式和第二种形式本质上的区别,其实就是第一个是双分支,第二个是多分支。两种不同的分支,我们要根据具体情况去使用。某种意义上多分支模式可以由双分支演变而来,比如我们可以在双分支模式里面的else里嵌套一个双分支结构就可以了。$ [4 t: D/ X" e( X
% y$ b5 w+ |; O9 E; D0 Y' Z/ A

( H% x; A5 U) I/ x! |* z1 H& v. Z- Lif(条件1为真)
: q/ ?% }- L2 g) R{: O7 X4 U5 P6 N  _+ p" A2 L& c1 n# ~; `
代码段1;/ Y0 P4 @( r" K! ~' B
}
9 Z1 r5 \; h# Pelse) b, W6 ^- P4 v! {3 ]$ W
{/ O8 t  ]3 }0 \+ ~
if(条件2为真)7 H( d# }: n" v( |# A  H! f
{
" K' v1 y( N* S# w8 O/ v1 B代码段2;
9 A$ ?4 d3 t- d}
; u; B, O, n  J( k  U% \else
2 |2 f  I$ g4 F{
" G, u' Y2 ?. v$ p+ ^# g代码段3;2 w4 j* b' q7 t7 Z) L& G* f
}
7 c$ @# i/ [% Z}
1 ~5 P) E7 K: f" Q3 ^) \' C6 E从这个意义上看,双分支和多分支其实是一回事情,本质上都是分支。分支这个概念,大家应该都是相对容易接受的,任何一件事情总有它的对立面,高对低,胖对瘦,大对小,物质对暗物质等等。分支这个概念应该是反映了事物的一种本源的状态,是描述程序是不可再进行切分的维度,也就是说分支成为了任何程序的三种基本结构之一。. h/ D) j7 K8 {' \& p8 _6 ~
4 P2 r- z- s$ s! l) ?0 b, F
其实对于多分支的情况,C语言有另外一套关键字组合switch/case,写成伪代码的形式,大概是这样的。
5 }0 B2 p7 Z/ J
5 j# n0 L- @. N8 }+ j' Tswitch(变量){
  h4 m% h; X4 V) T+ V7 k: ^case 常数1:
3 {0 d4 Z1 E: H$ o代码段1;& I* O' b* u3 |
break;
/ s9 i2 F8 W( K0 x8 ?9 z* ~; E' scase 常数2:
% y1 I9 z+ a! d' @  D5 P! I: a- l代码段2;: t" d6 V; E5 v( c- n% B
break;
0 W' v9 E3 b5 z9 ^1 Q2 f, t* W$ v! Hcase 常数3:' _/ P5 V$ h3 {
代码段3;
' {" V: I' _9 d0 m& t- c$ Sbreak;' N4 Z: F6 S7 N$ p% V$ p! W
。。。) {/ d. ^) n: ]1 T
default:
' e" E/ C& c2 h5 I代码段n;' D* z# t# }+ E3 V: A$ k
break;
7 j. Q1 m9 ]- `3 L}
$ q. W3 a1 K: ^- G; L6 `, ]: Y2 s  h
大家注意没,对于switch/case组合来说,它的条件一定要是常量,而且要是整数。这个是不是对判断的条件作出了限制呀。这里的default关键字,是和if/else里面的else对应的,表示意外情况。从表面看,switch/case适用于逻辑条件简单,但是分类较多的情况;if/else适用于判断条件复杂,但是分支较少的情况。但是从另外一个层面看来,switch/case所具备的功能,if/else完成起来,完全没有问题呀。那为什么还要搞出来这一个关键字组合呢?
1 y  N, @* z0 W* |! Y我个人的理解是switch/case关键字的执行效率,在某些情况下,要比if/else要高。
6 Q1 U( q3 D+ ~4 Z8 K- y7 E1 a) G$ q# D9 a6 |/ P! p; C
int a = 0;' {- |5 B! j% E* p9 G' p
switch(a)
: |8 N4 V( h* G$ D; C6 x, A5 j) Z) F{1 ]. R  p( O( ]& F9 Y) H% n2 ?
case -1:9 n8 ?* ?) M# ?! P+ h$ |, Q  W
    break;$ D, h3 ]" E& j, Y, z6 M7 A
case -2:0 Y: y& C- }: X8 h9 @" K5 g- u) v
    break;
* [5 @! J) s9 \% H8 Lcase -3:$ T( a  i2 b: q/ z7 B
    break;- m3 d; r8 z  M9 O
case -4:2 Y/ j* S$ b0 U. ~$ d# k" d" L
    break;
3 M6 X8 `5 E! ]) Zcase 0:
1 q# I4 i  ]( y+ h( W8 t8 k+ X    printf("I am in switch case!\n");; P) v! m  b& S8 u1 ^  B# H3 _- H
    break;% C4 ]3 Z) k% t0 M0 p: n) f/ {6 Y
default:2 g" W  i0 \( t+ x
  break;
) W6 S- I# v" w9 q8 b0 N}' l, l- o' T, ^2 `; V! S
printf("I am between the switch case and if/else if/else!\n");
" n5 O, h4 l9 [' C% j+ ~if (-1 == a)
7 D6 ]9 v  S% S7 @% {{3 L" }5 @9 }7 O: k- i! P7 F
}, o3 a6 z0 ~, C4 i$ ]
else if (-2 == a)
; G: N$ s) ^+ A{, U5 _3 q7 i) ?& |' F" E+ y
}, F: `' |1 E6 d1 G5 S9 f$ L8 \
else if (-3 == a)
, _5 A+ a. c# E- z$ l( s{& i! p1 f+ q6 `
}1 e0 C, t) z3 B) H. y$ U
else if (-4 == a)& c! ]! {! u; n2 z' K
{
: ?; P% `& Q, ~  H# k$ W& o}0 C4 q$ c  w9 p: B0 L6 d, D! v
else if (-5 == a)
' f4 f6 R6 ^# i( A) G8 D3 F5 \{
% i: x" I: |% d2 ^+ B; r2 P( {}
4 H* z9 I" L0 R+ v4 B- lelse2 I5 I% d3 j$ v, }; V
{
9 E: V! L" C1 s  t, T     printf("I am in if/else if/else!\n");
" }+ A- m3 a. @) {}9 X7 \  e0 t; L) }5 U% P) J* R
3 y) C& i. v* A& p6 i
比如对于上面的代码段,对于switch/case关键词对来说,程序是直接跳到case为0的情况下的;但是对于if/else而言,程序则是一句一句比较之后才达到了“else”这一句,程序执行效率的高低是显而易见的。1 R. k. b& m4 r$ m0 M( x. E

( y0 W, g, V! v0 k+ k/ x. u但是我们说,switch/case的程序执行效率可以比较高,并不是没有条件的。从汇编语言的层面来看,switch/case是建立了一张跳转表,因此需要一定的空间才行。这里某种程度上有以空间换时间的意思。" Y7 Z2 I% ^6 y, Q3 G

  w8 }8 C2 F* l因此,如果程序可以使用switch/case尽量使用这个,以便提高它的执行效率。其实,我们这样比对一番之后,自己也就轻而易举地牢牢记住了它们,这个可能也就是知其然知其所以然的效果,符合人的记忆规律。
- U' c) z: C! l  f9 S; b
5 v4 L. s& |  X讲完了分支,我们来看一下循环。循环这个基本结构,在C语言里面,一共有两种实现方式,for循环和while循环,其中while循环还可以分为两种,一种是while循环,一种是do/while循环。我们下面分别看一下,这三种结构的程序表达大概是什么模样。
0 w; Y6 D1 q( _" h* b, j, o8 F& X2 m- G. f) e9 [
for(循环控制变量初始化;循环终止条件;循环控制变量增量){循环体;}5 w0 F  z( ]: B& H6 e5 j
for循环的执行步骤是:首先执行循环变量的初始化,然后执行循环终止条件;如果判断条件为假(不符合终止条件),那么就开始执行循环体;然后执行循环控制变量的增量程序,执行完以后,再去判断是不是符合循环终止条件;如何符合条件,那么就退出循环;如果不符合条件,那么就继续执行循环体,并重复执行上述步骤。. N4 t& p: S9 O5 L/ U) T4 z

& G4 S0 m0 ^# {9 \6 c感觉用第二种方式来描述这个循环体的执行过程,更为清晰。第一,先进行循环控制变量初始化;第二,执行循环终止条件,如果判断结果为假,则进入第三步;如果为假则循环终止并退出;第三,执行循环体;第四,执行循环控制变量增量,转入第二步;( V; [3 p5 g) @

3 ~: g* W7 E/ c  h- k% f注意,其实for循环括号中的三部分其实都可以省略,如果全部省略了,就变成了一个无限循环的死循环,跳不出来了。无限循环在操作系统中使用的是非常多的,每一个任务都是一个无限循环体,包括main函数也是一个无限循环体。  ]% v4 Q! _$ c  ]* N  Y1 ~7 n
9 x- E- B" G% f: w
5 e( Z& E$ }: C

7 I( i/ q6 D% U8 x" r9 d4 x8 F4 [$ H6 R' g- }/ q6 Z

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-5-24 07:04 , Processed in 0.109375 second(s), 26 queries , Gzip On.

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

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

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