我是老温,一名热爱学习的嵌入式工程师
) U/ X7 ~! r4 `. P8 K关注我,一起变得更加优秀!& ^/ \! z5 P, R0 ?2 u4 _. X
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。
& {6 @: u' d) y6 k然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。
2 h8 O0 h6 X/ \4 p, V(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)
8 T, L6 W% u1 h/ G) l+ z3 f8 V% w3 ~! x8 ?! `( u0 Q
于是,我通常会写出类似以下的代码:int update_temperature(void){ char temp_value = 0; temp_value = get_temperature_value(); //获取温度值 update_to_cloud(temp_value); //上传到云端}# S$ q( u6 K2 ?8 N/ [# D
上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。! Y$ d# [0 S; T* A; j% r) z
在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。; _' q& i& m9 v; f4 O3 Z
wq3hyj0id4gBroken7361018.png
8 F% B# h9 z/ n" H% s! }$ ~% f9 K2 {& D
百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。
9 q$ V8 u/ b" k* C而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。0 {! t" W6 D. \8 n9 N' Y6 l3 g( w; _
我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~# a. f" W) O! Z& I1 M* w
网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。
$ ^( C% f3 e& t3 H( v6 J9 \
l03hcsxbmlw6407361118.jpg
" E& v% [- _- q4 l) G对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。
" X' w5 j2 _) r$ }9 i( x L就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。
, i" P, ^- D5 i. j看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。0 n4 k+ X: u u
b20jlv5o2fn6407361218.jpg
: B2 v4 o$ x2 z) k* p但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义。
" b1 ~# _$ L+ K$ q3 F* K% f, w而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。! n c) `- H3 y" u5 k8 E! e
基础不牢,又浪费了一个下午。 ) q, p0 r1 Z6 z
cffc4tfv5r3Hurt7361318.png
4 B9 @! C Z9 |4 R0 D" X
-END-7 j/ G8 Q5 V3 S0 k9 u& A# }6 { ?
往期推荐:点击图片即可跳转阅读
) j, H# h4 F4 T( z: i/ A- w
# X3 p J- y# Q$ U2 } " D% Z4 k! A. g1 n1 a/ g
. [# h% d( l2 r3 \$ T$ F
9 e' @. U2 W- F. c: E- L
dqki5ykpp5d6407361418.jpg
1 ]6 V, w9 E9 G
$ N+ d8 V8 m/ Q) t6 Y1 }3 }( n
嵌入式 C 语言知识点,动态变长数组
, }( y8 b3 z u7 B/ M 1 n+ j+ T# o3 b3 b0 | l
7 x+ n1 Y1 [0 T. n
' [ R3 i% d1 U% e0 O( l6 a 2 A4 [7 m' J+ |" o8 I6 V% A' ]
1gdsr04ptim6407361518.jpg
' w) P$ M4 N7 W d% {4 e) Q
. z! ?# x# [, a6 P: k9 R
嵌入式 C 语言特性,指定初始化器1 o8 b- D+ S/ E; v3 q
) y5 r5 e& ~6 v% |) I + ?1 U& P' l( O( O; S
, o. e/ {# F% A% m7 U) |1 W. s( ?
ge3qqpfh00e6407361618.jpg
% }/ ]; K; t. V. k6 L. `# |0 f. z0 T
' Z$ F! z2 ?. |$ O9 i
嵌入式 C 语言知识点,掩码结构体 }2 f( \0 R; H7 d/ L
我是老温,一名热爱学习的嵌入式工程师
0 j; Q( c5 b, |9 f u关注我,一起变得更加优秀! |