我是老温,一名热爱学习的嵌入式工程师+ @; O1 \" y/ _4 U [
关注我,一起变得更加优秀!
/ I0 Z$ Y/ D, p' V情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。
" X$ E' X7 }& k5 K- R/ L8 }然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。+ |* h. A7 H1 w% E; ^* V9 `, [
(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)% H( W: r5 A" J" x% y
x( I8 C, k7 Z9 d
于是,我通常会写出类似以下的代码:int update_temperature(void){ char temp_value = 0; temp_value = get_temperature_value(); //获取温度值 update_to_cloud(temp_value); //上传到云端}3 `8 [3 H4 E/ Q+ L+ P
上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。5 S2 q9 D6 c5 \7 U( n: ?& S
在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。
2 ~& |4 z/ g, S. y2 w, s
qttjvnfwp5gBroken12774220.png
: L$ U4 n6 _$ b: ~百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。" _5 u5 v" E2 T, q' h, P2 N* [/ r" M
而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。3 q# j) }. `. f/ Q
我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~
! _$ O6 L/ g; M2 `, O5 M网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。
" z8 d7 K* U2 P* l" R
cibn5qjf4uy64012774321.jpg
$ r8 |* T: @( u对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。
: N( s: C6 S7 Q( c* o就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。
" v) Z: R, M7 f! V, A看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。
" U, z) S3 k$ h2 ^+ H7 v# }/ I
rqotoh25egj64012774421.jpg
% w2 C7 E5 L) ~3 f但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义。
: J8 s7 S+ d7 k1 h* B( Q, Y! {而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。
+ Q) B9 i2 ]2 n5 Y0 x* M基础不牢,又浪费了一个下午。
8 t/ f) A5 g8 }; E# ~) |
dnum2uexd2kHurt12774521.png
5 q5 e$ [( v4 g9 ?
-END-
( L: R3 ~( ^$ o) W) q6 g1 |往期推荐:点击图片即可跳转阅读
$ V$ i9 ^6 V( z/ P3 Q9 ~- t- W 9 F: W7 e( ?1 v% ?2 f t
& j4 C) E% a* o, C5 N5 Q4 ~) ~& }) x
. p2 N' y+ T+ o! v9 I 5 J( c( C+ \, H. \
niha4k4p5oy64012774621.jpg
; S# h1 s" ?. W. ^* ~- H2 U
2 a1 [: @ C3 z
嵌入式 C 语言知识点,动态变长数组
# j2 U# A- q, }
0 R0 D1 W7 R" s4 D. p
& u* E1 Q8 p4 n
9 d- r. B: o) O% g4 z* I( a 7 q1 E( v% w+ Q; [
3ijlrfqbm1u64012774721.jpg
/ }" n5 A) n7 f & U# X! ]4 n# p t& L6 _, r
嵌入式 C 语言特性,指定初始化器
( {' ~7 U( U: f7 [ x' p U6 D" t- u; E
M ^6 ?) H( ^! p' E. S
4 U7 B6 c) i0 L9 N. x7 j: B
2d0gbiqbaa564012774821.jpg
* F/ z, G# `7 D' B
+ ^ _: ~0 t3 D N
嵌入式 C 语言知识点,掩码结构体
0 Z( t2 L6 W5 D+ @3 m/ N我是老温,一名热爱学习的嵌入式工程师
2 Y+ X: D1 e- g2 E9 }% ?$ q) p关注我,一起变得更加优秀! |