电子产业一站式赋能平台

PCB联盟网

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

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

积分
4361
发表于 2024-7-31 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师
' S3 m6 J4 p4 }2 O; O% |关注我,一起变得更加优秀!( _. [$ `' F6 `) V3 z" a0 E
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。
. w4 W, M9 b: b7 G3 A, c然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。) V3 o7 n3 l9 R" D% e
(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)
. l& |3 p8 \" Y5 C  E( z3 \
9 D$ V- ^3 @# }( ~- d& ^2 Q于是,我通常会写出类似以下的代码:
  • int update_temperature(void){    char temp_value = 0;        temp_value = get_temperature_value();    //获取温度值      update_to_cloud(temp_value);    //上传到云端}, F5 w- A  R# Y# L4 A) T
    上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。
    . F1 M& ~/ K7 |2 O4 u7 E- e在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。' o6 c" Q, _! H  |! ~! p

    ri4ds5ehjsyBroken12806932.png

    ri4ds5ehjsyBroken12806932.png
    5 z+ y- u) J% i# B
    百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。6 j/ C& K. S6 E- I  U- J3 P. M
    而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。
    6 s; q! z6 T# H; N  H! ^5 u! N我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~
    3 Y5 b: }4 k  u; C# U0 s, W1 }网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。
    % w& R$ L! N+ s: z, ?* {  _- a

    1eeoregu4rp64012807032.jpg

    1eeoregu4rp64012807032.jpg

    + P* N. o1 P* a. l( V0 p对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。
    # ?  z! e" \7 f. A就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。( S$ H: t; \5 L$ U7 K; F
    看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。
    2 [2 b+ c: Y1 D0 f! X# z

    mn005qidyxl64012807132.jpg

    mn005qidyxl64012807132.jpg
    0 S; j8 R1 D. L8 F
    但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义# x+ J) \7 I$ S
    而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。* M. B. d- y5 b3 D
    基础不牢,又浪费了一个下午。 & S. c" }( r  a: o

    qdg0lfuxwmvHurt12807232.png

    qdg0lfuxwmvHurt12807232.png
    1 r2 @! q. x: p1 \* N: @
    -END-  c! `& A$ d/ x. E- N5 S5 t, `
    往期推荐:点击图片即可跳转阅读' P5 U7 h3 v0 x* {
                                                            9 R0 g% j) _7 c
                                                                   
    ' E' g2 x" {# b. i# h: o$ K                                                                       
      [" @: x" M* m' `2 z1 b                                                                               
    6 `1 X) L& Q5 V  \+ O3 x

    y1njbbkt01g64012807332.jpg

    y1njbbkt01g64012807332.jpg

    ! k/ D' d( c+ v  h, M                                                                                $ @, i8 S! @3 |+ P+ h% B1 D( m( ?
                                                                                            嵌入式 C 语言知识点,动态变长数组6 ]8 V8 T. f; G  i9 Q3 T
                                                           
    : R3 _; y3 m$ _' M                                                               
    & I3 {& l  Z0 o! Q                                                                        ( A' f2 [9 b9 J4 ^* g$ V
                                                                                   
    & d" ]% A1 I+ i1 R9 w# B- j

    wpvjhws2r3x64012807432.jpg

    wpvjhws2r3x64012807432.jpg
    " n2 w0 Q5 E& X* f
                                                                                    9 s0 ~1 G" z3 U" {' @  }9 l
                                                                                            嵌入式 C 语言特性,指定初始化器
    % T, E$ F( e% }) h6 a& d6 X0 R1 c/ B                                                               
    + Y% u1 _/ ?6 N1 G( e! c& G" }1 D                                                                        ) Z" L' M: l9 O5 t& L0 o
                                                                                    $ V6 h; E. s: @1 J5 t

    cqyznh1asnw64012807532.jpg

    cqyznh1asnw64012807532.jpg
    % r2 l3 P# I9 L. {- A; e+ v
                                                                                   
    ' a7 X- l9 n/ Z# x1 k* P& ]3 F                                                                                        嵌入式 C 语言知识点,掩码结构体
    ( u' ~4 B8 h2 U  E- [* G+ Y我是老温,一名热爱学习的嵌入式工程师5 G- j- V- _9 n. a3 ]' b- s
    关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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