电子产业一站式赋能平台

PCB联盟网

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

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

积分
4361
发表于 2024-7-31 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师
- L& W. j5 J+ G) D9 T关注我,一起变得更加优秀!8 X/ {- U8 X: N
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。
/ @5 F" ~- F9 t6 N9 m4 P然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。' k$ t' q) c4 L& C7 U* S+ m
(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)0 f% {8 B) M* }
: ?% C& ~- C- {: M* G" i
于是,我通常会写出类似以下的代码:
  • int update_temperature(void){    char temp_value = 0;        temp_value = get_temperature_value();    //获取温度值      update_to_cloud(temp_value);    //上传到云端}( s( |" C$ m. J: h# t
    上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。
    : n3 A- [* C& o1 l在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。
    ' [+ t, U7 q5 p+ w# d

    qktqtox1bwxBroken2853717.png

    qktqtox1bwxBroken2853717.png

    * E0 z& R9 W! m- a- d百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。! T6 N, q) {! l( K1 x) R& I
    而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。5 O/ d0 x& |+ v; T% Z8 I9 E  S; A
    我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~
    & B+ N  e3 F  _: W  a$ K8 i: V. d网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。
    $ Y8 y4 ^; [- G

    jsvii2mkuvm6402853817.jpg

    jsvii2mkuvm6402853817.jpg

    % Q' x/ ~3 f2 d对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。
    0 X) f/ i" Q9 M5 f& ?3 i8 I就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。
    / L* T/ w+ h; @2 e$ E! K7 S看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。! P* c1 q. D' d8 e$ x

    vvmmnutcb1t6402853917.jpg

    vvmmnutcb1t6402853917.jpg

    % S+ ]0 C8 s( k: o3 `. E& v# n  x但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义
    # A3 V( b" m- {" T8 F9 c1 P而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。
    7 t" I: n9 y* |% d. C基础不牢,又浪费了一个下午。
    ' Z  ~, B  Z5 a4 S

    gvc1w002owdHurt2854017.png

    gvc1w002owdHurt2854017.png

    + D& k) S6 O9 `-END-
    ! N3 u" J7 X  W6 t0 `往期推荐:点击图片即可跳转阅读* Q+ m- [* @8 X0 _/ m
                                                            3 H9 u: ^3 y) N; F
                                                                   
    $ u! W8 b# n* {8 W/ e9 \1 q: j3 \                                                                        1 G# S5 F4 J  y- O% C+ O
                                                                                   
    * D7 s2 x4 M* G$ e& |8 {/ A2 m

    lnjmn51pw056402854117.jpg

    lnjmn51pw056402854117.jpg
    $ |& X  i6 [; n. t* n! |
                                                                                   
    ; u1 @- }: \2 K) }+ V                                                                                        嵌入式 C 语言知识点,动态变长数组5 z& H- o3 @9 S5 W- u2 o
                                                            " O2 [4 D+ J2 \4 A: x6 M- j. D
                                                                   
    0 e0 `, D7 ]* @8 M                                                                        : L3 x/ u4 [& f4 a
                                                                                    % h% S% S3 P- k+ g: f1 o2 u7 c3 s2 _

    ht50xb1cr5i6402854217.jpg

    ht50xb1cr5i6402854217.jpg
    ; B- z1 j/ g% o% N
                                                                                    / K1 M1 }/ P9 M
                                                                                            嵌入式 C 语言特性,指定初始化器5 W# r, j5 f. H" T
                                                                    4 e) p* Y0 R3 k8 W1 l" i1 ^5 w
                                                                            : u' ^0 a+ U% x7 D  h5 D
                                                                                    & Y+ n3 m. Z6 F& h1 u* P. f( G

    o0zyweiiwka6402854317.jpg

    o0zyweiiwka6402854317.jpg
    7 Q1 F, U( e: z+ R8 A6 J% l! W
                                                                                    " _$ P/ l3 s' x' J6 T( B7 F( i
                                                                                            嵌入式 C 语言知识点,掩码结构体
    7 {" R' C/ d( H  ^  P/ D3 S我是老温,一名热爱学习的嵌入式工程师
    * N" l1 P1 {. v  p7 P6 z关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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