电子产业一站式赋能平台

PCB联盟网

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

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

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

    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

    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

    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

    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

    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

    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

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

    使用道具 举报

    发表回复

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

    本版积分规则


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