我是老温,一名热爱学习的嵌入式工程师
' S3 m6 J4 p4 }2 O; O% |关注我,一起变得更加优秀!( _. [$ `' F6 `) V3 z" a0 E
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。
. w4 W, M9 b: b7 G3 A, c然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。) V3 o7 n3 l9 R" D% e
(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)
. l& |3 p8 \" Y5 C E( z3 \
9 D$ V- ^3 @# }( ~- d& ^2 Q于是,我通常会写出类似以下的代码:int update_temperature(void){ char temp_value = 0; temp_value = get_temperature_value(); //获取温度值 update_to_cloud(temp_value); //上传到云端}, F5 w- A R# Y# L4 A) T
上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。
. F1 M& ~/ K7 |2 O4 u7 E- e在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。' o6 c" Q, _! H |! ~! p
ri4ds5ehjsyBroken12806932.png
5 z+ y- u) J% i# B
百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。6 j/ C& K. S6 E- I U- J3 P. M
而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。
6 s; q! z6 T# H; N H! ^5 u! N我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~
3 Y5 b: }4 k u; C# U0 s, W1 }网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。
% w& R$ L! N+ s: z, ?* { _- a
1eeoregu4rp64012807032.jpg
+ P* N. o1 P* a. l( V0 p对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。
# ? z! e" \7 f. A就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。( S$ H: t; \5 L$ U7 K; F
看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。
2 [2 b+ c: Y1 D0 f! X# z
mn005qidyxl64012807132.jpg
0 S; j8 R1 D. L8 F
但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义。# x+ J) \7 I$ S
而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。* M. B. d- y5 b3 D
基础不牢,又浪费了一个下午。 & S. c" }( r a: o
qdg0lfuxwmvHurt12807232.png
1 r2 @! q. x: p1 \* N: @
-END- c! `& A$ d/ x. E- N5 S5 t, `
往期推荐:点击图片即可跳转阅读' P5 U7 h3 v0 x* {
9 R0 g% j) _7 c
' E' g2 x" {# b. i# h: o$ K
[" @: x" M* m' `2 z1 b
6 `1 X) L& Q5 V \+ O3 x
y1njbbkt01g64012807332.jpg
! k/ D' d( c+ v h, M $ @, i8 S! @3 |+ P+ h% B1 D( m( ?
嵌入式 C 语言知识点,动态变长数组6 ]8 V8 T. f; G i9 Q3 T
: R3 _; y3 m$ _' M
& I3 {& l Z0 o! Q ( A' f2 [9 b9 J4 ^* g$ V
& d" ]% A1 I+ i1 R9 w# B- j
wpvjhws2r3x64012807432.jpg
" n2 w0 Q5 E& X* f
9 s0 ~1 G" z3 U" {' @ }9 l
嵌入式 C 语言特性,指定初始化器
% T, E$ F( e% }) h6 a& d6 X0 R1 c/ B
+ Y% u1 _/ ?6 N1 G( e! c& G" }1 D ) Z" L' M: l9 O5 t& L0 o
$ V6 h; E. s: @1 J5 t
cqyznh1asnw64012807532.jpg
% r2 l3 P# I9 L. {- A; e+ v
' a7 X- l9 n/ Z# x1 k* P& ]3 F 嵌入式 C 语言知识点,掩码结构体
( u' ~4 B8 h2 U E- [* G+ Y我是老温,一名热爱学习的嵌入式工程师5 G- j- V- _9 n. a3 ]' b- s
关注我,一起变得更加优秀! |