电子产业一站式赋能平台

PCB联盟网

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

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

积分
4361
发表于 2024-7-31 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师+ @; 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

    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

    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

    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

    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

    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

    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

    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关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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