电子产业一站式赋能平台

PCB联盟网

搜索
查看: 142|回复: 0
收起左侧

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

积分
4361
发表于 2024-7-31 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师$ _9 W  V6 V* Y4 G6 C2 J
关注我,一起变得更加优秀!' R3 ~5 f5 h& w% ^9 d
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。. j" ~( L& d" K: j3 d7 t0 p0 R% S( R
然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。# F( t1 d0 Z  a/ r1 E( T0 h4 L# X2 j
(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)
0 A2 S# c0 H# N7 G4 d& k% t& [
7 p4 R' `" J3 w' K+ r# c+ Z于是,我通常会写出类似以下的代码:
  • int update_temperature(void){    char temp_value = 0;        temp_value = get_temperature_value();    //获取温度值      update_to_cloud(temp_value);    //上传到云端}
    7 B, X% x- `& O: {: U9 ~# }上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。9 D: ~2 G5 D. y! Z7 a' [- d
    在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。4 O- G2 y# i  T: Y1 h- m

    22f24525j3eBroken14425227.png

    22f24525j3eBroken14425227.png

    ) g" V$ a8 P" a1 d百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。/ |# Q4 ]& j! Z2 C
    而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。6 i( H& P: h% t' O6 k
    我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~
    ( E+ A; g. h+ H' x! D1 |  L网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。
    & `+ K; g0 V6 o, H

    uo4cwlutcvi64014425328.jpg

    uo4cwlutcvi64014425328.jpg

    0 ?( X# f: K0 |  T& h对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。, N3 c. c  Q8 U' z3 ~
    就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。% T4 ^- l: \$ p  t8 z9 v
    看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。. a2 f/ B0 B/ V% L

    ua3as01odza64014425429.jpg

    ua3as01odza64014425429.jpg

    4 R5 P* v% e+ W% m. b7 Q但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义* t3 |3 D; X/ k  p, L8 F
    而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。
    & M% I1 ?4 n: f; G2 U! `基础不牢,又浪费了一个下午。
    9 ]' q) Z) R  f7 s

    4rxfcrbyz1jHurt14425529.png

    4rxfcrbyz1jHurt14425529.png

    1 `. \3 C  W4 E-END-
    ( V8 q( r7 B! ]! R1 m往期推荐:点击图片即可跳转阅读1 y- x' E% [5 ~7 J: c
                                                            7 P9 l9 [- m- P. \
                                                                   
    / w% \( Y: y9 ]                                                                        ! S, o( Q+ U5 O9 X( ~
                                                                                   
    , l6 ?1 B5 r: h7 k

    axg4it5kiif64014425629.jpg

    axg4it5kiif64014425629.jpg
    % q* |# B/ P5 J/ k7 q8 q- v9 ?
                                                                                    8 F0 i. k5 h- y
                                                                                            嵌入式 C 语言知识点,动态变长数组/ i& K* C$ Y. I3 L4 O  j9 s# }1 h
                                                           
    6 g/ R0 `3 l- u/ i% C* j1 p                                                                ' y- y. }! J% k! @, t5 W
                                                                            + R- T% q1 {8 {$ r
                                                                                    * `8 h! j) x/ o9 X) V

    wavuulrglgw64014425729.jpg

    wavuulrglgw64014425729.jpg
    2 c$ `8 r$ |3 z8 T- z3 _6 }
                                                                                   
    ( s8 f, Z" t3 F8 t6 `                                                                                        嵌入式 C 语言特性,指定初始化器
    % a8 s% U! a8 j6 A                                                                / p: r8 A- b" ]( k* y
                                                                            6 t9 z8 r0 i7 s0 J( `: a
                                                                                   
    " x- J2 l' @% o# L# w

    xa4b245xxl064014425829.jpg

    xa4b245xxl064014425829.jpg

    2 w- I/ R, S0 i                                                                               
    & f0 Y( a' T! L0 M2 O: v0 P                                                                                        嵌入式 C 语言知识点,掩码结构体
    $ ~) p* S% U% a- e我是老温,一名热爱学习的嵌入式工程师/ w$ [9 |0 M* p9 R
    关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表