电子产业一站式赋能平台

PCB联盟网

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

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

积分
4361
发表于 2024-7-31 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师
- y& K- p' U2 D2 o& i- O' ?/ {- ^关注我,一起变得更加优秀!" \* l8 a; m7 o7 v
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。+ ]" V2 ~! @- A7 D
然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。$ W+ x& x) ]3 _$ R
(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)
. f: {. W  x  N% L& y% M( B: U* D+ U9 h; ?6 h  C
于是,我通常会写出类似以下的代码:
  • int update_temperature(void){    char temp_value = 0;        temp_value = get_temperature_value();    //获取温度值      update_to_cloud(temp_value);    //上传到云端}
    ( b* N6 P: A* H# E. W上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。% _0 S' A8 {5 L
    在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。2 y7 P0 |+ S  r$ y& i3 _4 b

    ctbq4vxj1c4Broken10758041.png

    ctbq4vxj1c4Broken10758041.png

    9 Q; C8 d8 W7 \" P1 o$ o百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。
    6 N, G( J6 _7 P& ?, J而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。5 [) o* Y9 S: E" W: E7 |% `  j+ l
    我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~
    - b! |! l9 g. @5 }( {( K' B* S网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。' ]( ^; M+ N! b2 I/ |

    f5w1dqry3ro64010758141.jpg

    f5w1dqry3ro64010758141.jpg
    9 f; s6 _. T- G5 H
    对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。
    - |+ f7 W+ Q+ q就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。: q& c* O1 H1 v, n" D& B( x
    看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。' S: z& d8 i: ?# O

    jwp0smjh05h64010758241.jpg

    jwp0smjh05h64010758241.jpg
    8 ^( T+ _  g* j$ W2 |
    但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义* q, E0 E7 f# V) w2 ~
    而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。: j* _4 `$ s" Q6 |0 z
    基础不牢,又浪费了一个下午。
    - |% v  H& T; f

    xqg54izalw1Hurt10758341.png

    xqg54izalw1Hurt10758341.png
    0 V( \! f, T' O6 ]: M
    -END-
    1 R# \# ?! G8 A往期推荐:点击图片即可跳转阅读
    3 t) f6 N4 Y; f0 U  O0 {% C% S: ?                                                        : j4 C% M+ x- c, V1 B! Y
                                                                   
    7 A2 v; S, i  [$ c. d                                                                       
    8 J% L# o  c' c7 j! G( d0 x                                                                                + e- _4 }2 O0 S( D2 w7 M2 Q

    wqxohtiewjp64010758441.jpg

    wqxohtiewjp64010758441.jpg

    / L6 {6 J* g& W$ j                                                                                # s* u- a% i2 q
                                                                                            嵌入式 C 语言知识点,动态变长数组1 R0 J" ]! @9 \5 B4 {: K6 o& A
                                                            1 R% s% z8 l6 |- j! W
                                                                    7 }6 |2 c$ a* Y$ x! N! C( f
                                                                           
    1 {$ a  ?* _& j  z; v) U: c                                                                               
    9 Y6 y; @& a! e) R. g* x

    f10fvekbuja64010758541.jpg

    f10fvekbuja64010758541.jpg

    / @5 y# L2 k" Y: Y: T7 P0 h                                                                               
    3 P" V- Q/ J5 N: ]( ~! [                                                                                        嵌入式 C 语言特性,指定初始化器
    " O4 q1 _. h# k0 |+ y  @                                                               
    6 [; v7 X9 }  F$ I* T* l                                                                       
    * W: x5 z4 X: k3 e6 E4 l& Q. d                                                                                + N3 g3 v) e/ v7 ?5 G; M* Y

    xhhfbk54yc564010758641.jpg

    xhhfbk54yc564010758641.jpg

    - o( I" W) u7 W                                                                               
    9 h) x4 U8 K  T. r4 F6 S% H                                                                                        嵌入式 C 语言知识点,掩码结构体
    1 c0 ]2 \. T( j$ r; ?我是老温,一名热爱学习的嵌入式工程师
    # Y3 D  ]  v. Y& w0 f: }关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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