|
EDA365欢迎您!
您需要 登录 才可以下载或查看,没有帐号?注册
x
今天写这一篇文章并不是因为已经想好了一篇文章才写下来,而是我要将这一篇文章作为一个长期的笔记来写,我会一直更新。在进行单片机开发时,经常都会出现一些很不起眼的问题,这些问题其实都是很基础的c语言知识点,是一些小细节。但是正是因为很基础,又都是小细节,所以我们往往容易忽视它们。结果有时候我们会花很长的时间纠结一个问题,迟迟找不到问题的所在。当发现原因竟然是这么的简单和不起眼时,我想不单是我,大家都会感到痛不欲生。笔者今天又碰到了这样的问题,实在忍不住了。因为这些问题都是小的知识点,考虑到之前也遇到好多这种问题,于是决定每次遇到问题就记录下来,时刻提醒自己。
" h3 X! N# G" ~$ h m6 `/ Z3 G
2 Z! p* `6 F* d. _5 A1. !和 ~ 不一样9 _' s3 z2 t" `) S$ U
6 {! @, r7 ]" Y+ k! N
+ E/ v3 K+ |) O! ?; y0 j" w! u! 是逻辑非符号,~ 是位取反符号。
1 V$ M7 g a; G3 K( s对IO口某个管脚赋值时不要错用 !,如
# B& w/ E& ?, G% K+ |# V! j% K![]()
& ~! E3 u/ d0 p) J& l8 R! Q6 e1 z; Q. r8 V
4 z& a* O5 D) p( {2.<<和>>的优先级低于+、-; |& j% H5 u" l. V
0 x0 f& e5 O# c" C5 x: b o
8 V( D# W" K; E! N
* U6 `! `. m0 P
比如要实现c=x*2+1,没有加括号会出错
% Y4 h( g9 c, s7 A9 ]; i![]()
3 U' }& I% ^4 [' ]. \. x, k9 b) o( H( w" k: R% c" P1 M
) o% {; T5 i( [+ Y3 V8 |3.移位要防止溢出( d0 @" ]4 Q' r s( H
4 q3 @( c! h. h! A; r2 p2 k
, Z# x% L) v8 ~$ v% h& T
其实用移位代替乘除法是个不错的方法,笔者很喜欢拿到一段代码后用移位代替乘除法来进行优化。不过有时候却会出现问题,比如溢出问题。当很明显可能溢出的话我们是会注意的,比如9 I+ t1 K( d* H: m9 i5 u
![]()
) L% F+ J$ B( W* M但是有时候这个问题是不明显的,比如当移位出现在数组索引或函数参数时,有段用液晶显示字符的代码如下
4 ]( J3 M. s9 W$ I, Z) O& Z4 r " N# J; S* D, t& M7 c3 R2 q
我们可以用左移运算来代替乘法进行优化,如
9 h- j. d4 g& V' D![]()
/ q% T9 x1 m1 U6 d这本是一个好方法,但是事实上上面的代码是错的。当执行c<<4时,因为没有明显的赋值过程,我们可能认为没问题,而事实上c的高位已经丢失了,所以得到错误的结果。一个可行的做法是先进行强制转换,如2 _; Q" |, V# k1 M1 j, A8 b
![]()
5 D7 ~. v6 u+ F) R2 m& u4 _# P) t7 q
3 [7 X. i0 a" [2 T4.无符号数和有符号数混合运算都会被强制转换为无符号数运算
: [) L% B4 K, c# V; X
! j: r! S2 ]5 G2 i/ W. _- G& y- ]+ n& o$ {( r" ^+ X+ x7 V* X6 R
当一个有符号数和一个无符号数进行算术运算时,系统会自动将有符号数强制转换为无符号数再进行运算(即使你使用有符号数强制类型转换),如下面两种写法的运输结果是一样的4 u1 H" p3 F2 [; W
" x8 L: ?1 D* F/ I
$ b# z2 M) d* o+ Z
8 p, W {9 T% d& f2 N4 Y% F$ W3 J
5.局部变量要初始化
* R. a, }7 F4 ~5 U4 d
( q+ m4 j6 S; U( g, Q+ _/ R% [5 n2 z' V+ D; \4 {
局部变量没有初始化的话,因为单片机每次为他分配的是同一个内存区域,当你在函数中是这么使用局部变量时,就可能出问题:
- ?' D" q" L5 c0 d![]()
1 `) W/ T1 H5 {& H! x如果第一次调用fun时,a传递的值为0,那么flag = 0x01;执行if(flag&0x01)后面的代码。以后再调用fun时,即使a不为0,但flag依然使用之前的内存区域,所以其值一直为0x01,一直执行的是if后面的代码,而不是else后面的。3 w( l' m9 {# q9 ?2 n! h
- ]* F" v8 a+ h' T- P* U0 C0 \7 G
如果要避免这个错误,平时要养成对局部变量初始化的习惯。 |
|