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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
if和for,这两个从本质上来说,是不是C语言的两个关键字呀。那么我们为什么又把它称之为C语言的基本结构的一部分呢。要回答这个问题,我们是不是首先要搞清楚C语言的基本结构是什么?
+ @7 z. G8 x- [* f. ^
: E5 w) f, u' m实际上,任何结构化编程语言的基本结构都是相同的,也就是三种基本的程序结构:顺序,分支和循环。由这三者最基本的结构,可以搭建出任何我们想实现的程序结构。在狄杰斯特拉(Edsger W. Dijkstra)反复研究面条式代码(spaghetti code),并在1968年给某位编辑写了一篇著名的简信,题为《Go to语句是有害的》之后,计算机科学家Corrado Bohm和Giuseppe Jacopini证明,使用顺序(sequencing),分支/选择(alternation)和循环(iteration)这三种流程结构就足以表达所有程序的本质。C语言作为结构化编程语言的一种,其程序结构,自然也是由这三种最基本的程序结构组成。
  u4 ^7 p! Q/ O# S) |8 i) j
( a+ [( l) w. Y$ ]( R$ C0 `0 Z7 n' J顺序执行程序,这个很好理解,一条语句接着一条语句执行就可以了。那么C语言的分支和循环是如何实现的呢?: ~, }4 R9 v2 z/ s

  \1 T3 D2 i, @. r; F; Q  S对于分支,我们常见的关键词是不是有if/else和switch/case两种组合呀。if/else翻译过来,是不是就是“如果…,否则…”,是一个条件判断。如果用伪代码的方式来进行表达的话,一般有这两种形式。
  n9 D1 H" p/ a# @( e% J! l( |5 {* n: y( l1 j: T; @6 m0 t
第一种形式如下:
$ p* T0 H4 y0 X1 D, _if(条件为真)
# J$ B5 @$ w5 e# a; B- Y{* o$ \0 \* w2 Y2 H. C/ p
代码段1;% R- J/ G' A" n" H$ g) A$ O$ S
}
: ^* Q6 v1 t" selse
! b0 Q; B2 _2 R3 j: U  }{
0 D4 x( Q! Y7 G  N7 [5 Q% y代码段2;! N1 O4 u0 {: N. r2 z9 M9 c8 w
}
6 [8 A- ]4 a. F1 k这里else的含义其实就是条件不为真,那么也就是条件为假。

' Z$ M( \, L6 O$ v* ^. P. \6 S
9 ]/ w) c$ |7 `, [+ p, T8 p; R第二种形式是这样的:' j" H1 f' O; A$ s7 a8 L$ h
if(条件1为真)/ b) P# T0 @( U
{
3 p+ Q, ]1 C; z" ]  I0 Z3 v; t5 I: @代码段1;# m; ]8 W. J* A, F, q' h; T3 `
}/ ~3 p/ W3 _% r6 v
else if(条件2为真)- S2 ^& G1 a6 D/ O6 b% i7 {9 D# `
{
! @7 m, x1 }5 p代码段2;
, F  Q- G9 g. p}
2 T9 M; R- s4 x' m9 ~; g: Y! k0 velse/ S4 N4 X& q5 F' E! ]3 s, U
{
. a: I( T6 h3 d1 S( o代码段3;
$ U: k9 b( I+ D( |! c* I9 n. G5 A! l2 O: d, i. a# L* H. Q! j( D
}
. t5 ?$ A- j4 G/ w" Y

8 M7 R( d0 d/ r4 U7 r第一种形式和第二种形式本质上的区别,其实就是第一个是双分支,第二个是多分支。两种不同的分支,我们要根据具体情况去使用。某种意义上多分支模式可以由双分支演变而来,比如我们可以在双分支模式里面的else里嵌套一个双分支结构就可以了。9 `/ e: w' w& D$ |9 D

* C  S) U+ b! v( H
, O8 F* c$ C. I$ H/ E9 Fif(条件1为真)( ]) `; E% r, \( g
{/ D# J8 O' D3 E8 Z' A6 l
代码段1;( u7 w, A2 o- f
}, j+ X% @0 u" q+ _5 b9 b; w
else3 e1 w3 n5 U9 }( I  I$ ~2 B
{
, |3 e0 e% H" f/ Nif(条件2为真)
+ _$ |- u4 @5 I" F; U8 E$ l{
' I( H" G& ]; v/ M" j代码段2;
4 j# D) c0 [+ j/ s8 M}. f/ x! T+ }8 g, l) w; D% ^
else
! p# p. K  |: y' c6 L{( ?; s8 {; p. K* c4 l, e
代码段3;  w) l8 k* m! O0 N, L& v
}
( E6 K$ \, a- u+ i! `- r" L/ o}; }# o2 d6 a" z8 h: {7 ^
从这个意义上看,双分支和多分支其实是一回事情,本质上都是分支。分支这个概念,大家应该都是相对容易接受的,任何一件事情总有它的对立面,高对低,胖对瘦,大对小,物质对暗物质等等。分支这个概念应该是反映了事物的一种本源的状态,是描述程序是不可再进行切分的维度,也就是说分支成为了任何程序的三种基本结构之一。1 b- O9 r. _; J& O0 K
0 N7 ?8 s. z8 @% ^. T" ?  Y5 E
其实对于多分支的情况,C语言有另外一套关键字组合switch/case,写成伪代码的形式,大概是这样的。
7 ]8 n/ T# X% _
0 q( p8 V2 }. ~  ]switch(变量){
- h& L2 m/ \2 `case 常数1:
) @) \+ T* K0 a8 ^8 S代码段1;* U( n: l8 u5 D/ d6 F
break;
5 N, _* h. Y/ y2 `case 常数2:
- {- {% {: Q+ O代码段2;
" i& V" x1 o/ U0 Q; ebreak;
$ J3 e6 }2 I, v) P' r3 Acase 常数3:& m, b9 [& t2 [
代码段3;
3 M1 ^4 r/ {& h5 vbreak;1 v9 D: P/ e8 g- p; Z7 U8 k
。。。
: v; K* `& V6 R/ g- F' R7 M4 `' vdefault:
) d9 H; m/ s: h; U+ i* E% e代码段n;
% a: K4 U. o- w  zbreak;
  [- y# X8 x- r  R' g' k, [}, t' ^9 X, |# I" O- ^9 _, F

; v& }# p; n) X; j, D大家注意没,对于switch/case组合来说,它的条件一定要是常量,而且要是整数。这个是不是对判断的条件作出了限制呀。这里的default关键字,是和if/else里面的else对应的,表示意外情况。从表面看,switch/case适用于逻辑条件简单,但是分类较多的情况;if/else适用于判断条件复杂,但是分支较少的情况。但是从另外一个层面看来,switch/case所具备的功能,if/else完成起来,完全没有问题呀。那为什么还要搞出来这一个关键字组合呢?
" I2 @4 F" J7 ^0 {我个人的理解是switch/case关键字的执行效率,在某些情况下,要比if/else要高。) i+ A/ y: M# G" U* _/ l5 F) j6 s2 I8 ~

( M' U- |7 f; H6 O5 aint a = 0;. k% {+ H% x3 A1 t8 F0 a3 F; C/ P& N) s
switch(a); y0 J% b- g9 F  K2 T
{; t9 W) ~, R* E0 G7 q5 H& |
case -1:
& t# g) ?" T5 p% r) B; T9 }! }    break;, f1 t* U7 R) U7 K6 I5 X
case -2:. P5 p# T6 G; L- x9 l6 d
    break;6 x+ ^9 H) t; k9 l: M  D8 m7 L
case -3:$ R( k4 U/ z, k& u- O  c7 M2 \
    break;. n0 z5 @9 U) p; n
case -4:( o4 B  L( E1 M% N
    break;
! @7 y9 }3 e& }" z$ W4 hcase 0:
) a+ L# K. I+ [. J2 h4 K! u, ]3 ]# b    printf("I am in switch case!\n");6 \# ]/ Y/ {4 c$ c: w4 d$ _
    break;( W" z( `* ?$ V% u5 G8 M
default:
! V4 O* `+ k; N7 x- o  break;
' x+ v& W- t. j; Z3 c; `4 T}3 U( y- m. P- W  w# P
printf("I am between the switch case and if/else if/else!\n");" _& R8 _6 a0 V  o5 {
if (-1 == a)3 u1 q* x) [! e1 _
{
, t& |" r6 X0 o- q' x% U# z}
" j# _: c/ N+ ?7 V$ t: [else if (-2 == a)" Y; v* ~5 H2 C: J" o. H4 f
{6 Y& U( R* h$ N2 ^
}& }8 L* ?: ^/ [' r( M* d* P* y8 S
else if (-3 == a)
5 b" Z6 F7 I: ?, L{
4 n  ^9 k' D% p4 O  p. H}* z; \/ @6 Q* R) ~" A; D( G- ?% C
else if (-4 == a)
. d) Y- K# d; Z! ]: y# }{
! }2 U$ J, k" Q' h$ g2 p0 x( l}/ ~' I2 o0 h+ _- c. P- W
else if (-5 == a)" u$ \" k# C# P- {% N
{' W+ z8 I" {6 J' ]6 Z
}
" P( J' x3 ^' h$ C$ ?6 }else, f1 k& S% G/ _
{
5 V; H" k/ _2 Z6 [0 E     printf("I am in if/else if/else!\n");
$ v+ w0 W  Y8 |1 S8 ]5 m}  r4 P' P2 N3 z2 O

# V( ?5 t9 H) z, C% m1 g4 a. M4 c0 q比如对于上面的代码段,对于switch/case关键词对来说,程序是直接跳到case为0的情况下的;但是对于if/else而言,程序则是一句一句比较之后才达到了“else”这一句,程序执行效率的高低是显而易见的。8 {, U3 R, l/ }  P. P. D

( V9 B) V1 S& j0 V1 K* b. q& r但是我们说,switch/case的程序执行效率可以比较高,并不是没有条件的。从汇编语言的层面来看,switch/case是建立了一张跳转表,因此需要一定的空间才行。这里某种程度上有以空间换时间的意思。, e- x. F7 {; h) n

! W. l% f& c# A4 J3 D4 v' v) n( v因此,如果程序可以使用switch/case尽量使用这个,以便提高它的执行效率。其实,我们这样比对一番之后,自己也就轻而易举地牢牢记住了它们,这个可能也就是知其然知其所以然的效果,符合人的记忆规律。( P2 t& z  h6 x
6 e7 l! x; ~" H# ?/ M( c" f' ?
讲完了分支,我们来看一下循环。循环这个基本结构,在C语言里面,一共有两种实现方式,for循环和while循环,其中while循环还可以分为两种,一种是while循环,一种是do/while循环。我们下面分别看一下,这三种结构的程序表达大概是什么模样。5 U* t  V' m5 d2 r

' h8 ]: c* [8 D" afor(循环控制变量初始化;循环终止条件;循环控制变量增量){循环体;}8 G2 k& |: V6 V
for循环的执行步骤是:首先执行循环变量的初始化,然后执行循环终止条件;如果判断条件为假(不符合终止条件),那么就开始执行循环体;然后执行循环控制变量的增量程序,执行完以后,再去判断是不是符合循环终止条件;如何符合条件,那么就退出循环;如果不符合条件,那么就继续执行循环体,并重复执行上述步骤。
3 ]( n/ {) |( B3 t) b7 b
# f5 x# K# P( W感觉用第二种方式来描述这个循环体的执行过程,更为清晰。第一,先进行循环控制变量初始化;第二,执行循环终止条件,如果判断结果为假,则进入第三步;如果为假则循环终止并退出;第三,执行循环体;第四,执行循环控制变量增量,转入第二步;. J" f5 t- F# i  A4 ]
. w( b7 d, z1 `% v. X
注意,其实for循环括号中的三部分其实都可以省略,如果全部省略了,就变成了一个无限循环的死循环,跳不出来了。无限循环在操作系统中使用的是非常多的,每一个任务都是一个无限循环体,包括main函数也是一个无限循环体。1 P6 W! F( v5 V1 I

* j1 |- W4 D; U' F  g4 k% B# I

8 K6 w1 k# I3 Y' D2 G

& L2 m" E3 ?5 u& U" c$ s5 A, {/ M& d3 l8 e# o9 l

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-19 13:49 , Processed in 0.078125 second(s), 26 queries , Gzip On.

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

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

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