电子产业一站式赋能平台

PCB联盟网

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

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

积分
4361
发表于 2024-7-31 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师/ w, R8 n( P/ e6 ]; S1 I* O
关注我,一起变得更加优秀!: D/ f' R8 d: G9 x1 i. f# k- `
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。
( e3 {2 U3 k+ G# d然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。
7 `( J% @+ i7 j3 W% h! v(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)
8 Q5 p' c4 W  h9 l: F! `2 z- l6 ?' t8 W" O9 a& `; q8 b* J
于是,我通常会写出类似以下的代码:
  • int update_temperature(void){    char temp_value = 0;        temp_value = get_temperature_value();    //获取温度值      update_to_cloud(temp_value);    //上传到云端}
    : B: N+ P/ p+ s5 O* W; O上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。
    , `1 Q; e7 M' J1 t: w$ p在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。" _( a/ y7 `8 j# }! d% G

    fdxgzc0l0vpBroken5228646.png

    fdxgzc0l0vpBroken5228646.png

    # Z, v5 a2 |0 w* I7 O9 n百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。3 `, l5 Z: e( Q& Q
    而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。
    ) h7 k& J( ~( u9 J1 [我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~
    9 M5 A$ z+ A, }! V& o网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。% T; Q7 x: s$ _  S* L

    1vhiqqhazcm6405228746.jpg

    1vhiqqhazcm6405228746.jpg

    % K/ L! ^0 D' p% u  Z0 X8 `对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。& J8 I/ z* b( q; h( L  g8 R: _
    就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。
    + H7 C. e* b% O3 ~" K看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。) ]& I( ^: M, d5 P( h

    subvrfbdq4y6405228846.jpg

    subvrfbdq4y6405228846.jpg

    1 Q9 {* M& g6 x9 ?; Q  L8 c但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义! i! c- A; f- X; l5 f
    而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。! v) a6 P5 R. G5 t! j! a
    基础不牢,又浪费了一个下午。 & l2 a& y8 C2 J0 s7 Y

    txx1csrdh3iHurt5228946.png

    txx1csrdh3iHurt5228946.png
    ! k- {0 ?, F! |# b: X
    -END-
    & z/ u* f! s- s! `  }( l往期推荐:点击图片即可跳转阅读( j4 c6 F& X$ m/ r
                                                            % Y1 l  a4 c6 q4 F' j0 P2 t/ w5 X1 H
                                                                    , v2 I7 H# F; _$ r' _
                                                                           
    + P0 {# g) v# B1 I                                                                               
    4 A* n( i( u$ v1 [3 j6 P% G

    jooazkbj0g16405229046.jpg

    jooazkbj0g16405229046.jpg

    . d. l& p* H$ I+ K* s! L* w; E                                                                               
    # Y% O; N6 n3 M                                                                                        嵌入式 C 语言知识点,动态变长数组. P8 X. S' X- a7 B
                                                            * x0 R: U2 V" x5 x6 t) F* ^
                                                                   
    7 @: O( D% D1 W$ f+ l9 j* P0 X                                                                        & o3 X  j, {7 s! u5 ~2 ^
                                                                                    ; O/ j; U& {: w3 J% ?8 s

    aqkt23ra5sn6405229146.jpg

    aqkt23ra5sn6405229146.jpg

    4 S) |! c* l2 {                                                                               
    0 J; _9 e+ X& \7 A% _                                                                                        嵌入式 C 语言特性,指定初始化器+ C9 S+ W- l7 B/ d+ n* _8 m$ \
                                                                    8 A" k  D! J8 ?) l
                                                                           
    6 ~4 [. k5 K! P0 s" \                                                                               
    " E. T) a0 q& h* e6 ~( ^4 s

    jevyi3bredp6405229246.jpg

    jevyi3bredp6405229246.jpg
    7 v. ]; {4 w# ~( N' r
                                                                                    " \3 J* O2 _' S1 t+ N
                                                                                            嵌入式 C 语言知识点,掩码结构体
    9 O& R! m6 w4 F1 G* b- x; Q我是老温,一名热爱学习的嵌入式工程师
    . n$ p# c, m( E2 |6 a. }. S" {( m关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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