电子产业一站式赋能平台

PCB联盟网

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

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

积分
4361
发表于 2024-7-31 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师
3 u- r8 V! @( k; O- b$ Z关注我,一起变得更加优秀!' r% L/ X- U/ }8 C, Q# W
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。. Z- G* v* G  E6 K7 d
然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。) Y% P. |" d# B5 P! P- [, I; l1 [
(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)
8 \2 q0 }6 C% K- g0 L7 K0 I! G) i! x4 Y- t: M
于是,我通常会写出类似以下的代码:
  • int update_temperature(void){    char temp_value = 0;        temp_value = get_temperature_value();    //获取温度值      update_to_cloud(temp_value);    //上传到云端}
    1 J7 m$ v- `. K0 d, l4 D  i上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。. h" S* T) l6 L; [
    在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。; H/ D2 d4 F, u8 {$ O" X0 }

    qj5mbd3yd2wBroken1506301.png

    qj5mbd3yd2wBroken1506301.png

    $ T1 q6 t$ ]' `7 ~$ I3 Z: B百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。
    , }, P. B6 S3 _  l而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。
    " u: v8 v5 b5 Z% F# h( ~& y( m我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~: Q0 \7 }0 E+ [: [+ q
    网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。6 t+ ~6 g4 G" a7 `/ |

    cuphffbxddz6401506402.jpg

    cuphffbxddz6401506402.jpg
    . A( E+ N4 ~/ ]8 C8 v
    对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。( Y$ c6 F, ?  G5 f( F, O
    就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。
    - z" a6 i0 g8 Y, o看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。8 r& w$ B( y* u" J$ r) G

    zqjy5x0trzh6401506502.jpg

    zqjy5x0trzh6401506502.jpg

    : B# x4 A" L1 @3 D! N& i9 x但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义
    - D  g+ T3 M1 E. r  ^$ G' k而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。
    ; E- m$ _4 [( @, W+ z" t基础不牢,又浪费了一个下午。
    ) c5 w3 M1 y4 ^0 Z

    ev2rxscvp3lHurt1506602.png

    ev2rxscvp3lHurt1506602.png

    ' @5 }- F- U3 M; e-END-
    3 X" [) ?( i; K. W往期推荐:点击图片即可跳转阅读
    * n; E2 \) v, m$ }                                                       
    0 E1 p9 M8 Q9 c6 {. u                                                               
    * T- `7 K9 D% k1 V                                                                       
    $ x. @8 D  g, \                                                                               
    / r1 C9 [! t6 _3 t& L- p

    axhntdw2mje6401506702.jpg

    axhntdw2mje6401506702.jpg
    3 |' j9 @/ E3 |  Y" [
                                                                                    . a% l0 g2 U" v7 e0 t7 m* P
                                                                                            嵌入式 C 语言知识点,动态变长数组
    ( ]/ l! D6 l# K, B7 h. s                                                        $ c, C( X- D1 v/ x/ `
                                                                    6 h. S, C, i) k+ ]" Y
                                                                            % o: ~! S9 ?1 @8 a. c
                                                                                    " ?. G; v- l- Z" _' C

    smnvemrrjgf6401506802.jpg

    smnvemrrjgf6401506802.jpg

    / D: P$ V" H9 v1 \. `9 a2 X                                                                                . B" P- Z8 y; Q* B0 ?8 h
                                                                                            嵌入式 C 语言特性,指定初始化器+ L. M1 I, ~; I
                                                                    & f' Z9 J& g/ O
                                                                           
    * i" u& a2 z; g  }0 ^2 v                                                                                / p! D/ E3 S" {/ [2 A* k

    s14amaeohmd6401506902.jpg

    s14amaeohmd6401506902.jpg

    ; g6 }! v# `# q5 r$ Y% p1 x                                                                               
    8 ^5 D# [3 P# X- s( o5 R: P                                                                                        嵌入式 C 语言知识点,掩码结构体5 f- ]1 h0 `: z) z* A1 ]' E
    我是老温,一名热爱学习的嵌入式工程师8 R" n  x! V0 u( G' d! i+ O
    关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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