电子产业一站式赋能平台

PCB联盟网

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

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

积分
4361
发表于 2024-7-31 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师
* @! s' S: G/ X$ n4 N关注我,一起变得更加优秀!$ W2 S% b- @/ V' ^. \+ t  Z
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。
( `' \$ s$ v2 V) E5 ?9 l/ a8 F然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。
. x  D$ l3 E. N3 |% B2 `& L& u(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)2 X$ i: }1 n# l$ P

* v0 v+ F. U' E! B% W" T于是,我通常会写出类似以下的代码:
  • int update_temperature(void){    char temp_value = 0;        temp_value = get_temperature_value();    //获取温度值      update_to_cloud(temp_value);    //上传到云端}
    / ^. j! i/ S  T2 X" O; E0 G6 I上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。
    9 n: l" f3 e' N- g; b2 k7 y( m8 u在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。9 ^4 s9 ^7 s( P0 S& k$ Q; z. ^/ C

    erfozcxt5pjBroken20408758.png

    erfozcxt5pjBroken20408758.png
    - j  y. M; s; a& p0 W" N
    百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。9 p- d2 a0 P% X; y7 W
    而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。
    8 B3 ?! Z- N. K$ t" a, D我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~
    2 t1 x4 W$ x5 k网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。% T- L6 E7 v3 U0 G, f

    cvh0101rkwx64020408858.jpg

    cvh0101rkwx64020408858.jpg

    $ L6 F& S2 }& t/ L对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。
    , g# K0 N. \) F6 O就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。- O" P% M  _1 i4 Z' I4 Z' U  F4 T
    看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。
    1 C7 ^+ m; }: I, J/ g

    oh1j3a4idye64020408958.jpg

    oh1j3a4idye64020408958.jpg
    1 u1 c/ A  m& X7 P
    但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义$ V0 O- f8 T7 N$ N+ T! o
    而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。
    + p1 K. o; J7 Z* v+ g基础不牢,又浪费了一个下午。
    . \( n) x5 a5 @7 ~

    2zojzjkhbgkHurt20409058.png

    2zojzjkhbgkHurt20409058.png
    5 s! W! [. B9 P5 \1 u' r2 ~- ]8 h
    -END-
    2 e& }, x7 y) H, z0 ]/ e# {8 o往期推荐:点击图片即可跳转阅读) c, z: J( \7 X6 v( r; U
                                                           
    2 o6 ^0 U# E1 S* F: S                                                                ) j9 K. x6 }/ o! @8 T- X
                                                                           
    ! @- ]' i3 a; L% J! Q; p8 v' H7 _                                                                                * w! N5 ^, @: G8 z

    hpsyw2srmkn64020409158.jpg

    hpsyw2srmkn64020409158.jpg

    1 W1 }! X: n! l6 y                                                                                5 y( z1 a3 n; S
                                                                                            嵌入式 C 语言知识点,动态变长数组
    # H# k+ h4 g6 h3 O) w                                                       
    4 L$ S7 g5 e$ j7 c( t5 v& ]                                                               
    2 d# E+ }8 s$ M8 e# o                                                                        ' ^6 N& S  c/ r! ]: B
                                                                                    8 G% x( v. h1 o0 R( r! L, |8 d6 Y

    0ip0qqhixmi64020409258.jpg

    0ip0qqhixmi64020409258.jpg

    4 @' o% }7 u' Z' L9 ]. {. Y                                                                                ; V7 R7 ?7 {7 ]( x
                                                                                            嵌入式 C 语言特性,指定初始化器
    - }  t; F. p. L; l& A  c                                                                7 R% W* l% J1 q/ q; j
                                                                           
    " ~6 |/ K$ h  c                                                                               
    & O: ]9 ]1 X- H; v5 o+ x3 L

    ecl5vnyb2my64020409358.jpg

    ecl5vnyb2my64020409358.jpg
    : k1 `3 Y* J; e& Z
                                                                                   
    ' |# ]5 ^0 F+ c) Q                                                                                        嵌入式 C 语言知识点,掩码结构体# k9 V9 o  m; l$ {7 T
    我是老温,一名热爱学习的嵌入式工程师
    9 O/ u% J! O4 o关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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