电子产业一站式赋能平台

PCB联盟网

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

被 char 类型的变量坑惨了!

[复制链接]

572

主题

572

帖子

4361

积分

四级会员

Rank: 4

积分
4361
发表于 2024-7-31 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师  \4 I; |% ?- m( a" b+ S2 c& f
关注我,一起变得更加优秀!  h% N7 K& K0 m2 T/ M! H! o6 p
情况是这样的,我之前在开发一个物联网产品的时候,这款产品里面有涉及到温度数据的采集,需要把环境温度上报到服务器,然后同步到其他终端进行显示。& `' t( ?6 e& t  k* c2 |0 W
然后我心里面想,通常环境温度一般在负几十度到正几十度的区间,采用 char 类型的变量,其取值范围在 -127 ~ 127,一般都是足够的。7 B! X/ |2 h5 k% e$ P6 \; Y
(原谅我的不严谨,对于整型值,一般建议用 int,为了省字节空间,所以用了char 类型)
/ a% }/ D" D6 _6 R
3 ~# h" h8 q! P: S3 r于是,我通常会写出类似以下的代码:
  • int update_temperature(void){    char temp_value = 0;        temp_value = get_temperature_value();    //获取温度值      update_to_cloud(temp_value);    //上传到云端}$ @  c7 s# f" s, B& j- a
    上述代码,采集完温度之后用char类型的变量保存起来,然后上传到云端服务器里面。& M  F4 y" Y1 L  X5 w4 m9 {, B
    在进行低温环境(-10℃)测试的时候,我发现了一种非常奇怪的现象,其他终端里面显示的温度值,居然是246摄氏度,好家伙,直接就收到了温度过高的告警信息。" c- z* q1 f8 k3 K; T* C8 C4 L

    yvos3z00nifBroken6504513.png

    yvos3z00nifBroken6504513.png

    0 m0 F/ Q% q; d# ]& B百思不得其解,我明明用 char 类型的变量去定义一个温度值,并且也没有超过无符号数的取值范围,按理来说应该是正确的才对。( R5 B( F( J6 ^2 V
    而且这现象有一个规律,当温度是-10时,显示246,当温度是-20时,显示236,这些现象的绝对值相加,等于256。/ L- U" r! @' z9 i  f; A5 B, `
    我突然意识到,关于 char 类型变量的取值范围,应该有一些知识点是我还没有了解清楚的。~* y5 p3 `( v9 F
    网上一搜 “c 语言 char 类型变量的取值范围”,果然,答案马上就出来了。: m7 L0 f$ \! {. ~4 L8 [. S

    re3j4dnhlbq6406504613.jpg

    re3j4dnhlbq6406504613.jpg

    2 e0 A2 ]: S; d9 e对于 char 类型定义的变量是有符号数还是无符号数,其实是由编译器和平台来指定的,也就是说,当我们直接用 char 来定义变量的时候,它有可能是一个无符号数。4 Y; u+ {( R6 W! W, _
    就是因为我当时用的编译器和平台,把 char 类型的变量指定为无符号类型了,当我对一个无符号类型的变量赋予一个负数值的时候,问题就出现了。6 M0 p) }0 I6 f
    看了一下 MDK 编译器里面的选项,可以强制指定 char 类型的变量为有符号类型,对于 GCC编译器,可以使用 -fsigned-char 选项。) {' L* w/ p4 _4 J, z, i

    i4pnhmqlo0j6406504713.jpg

    i4pnhmqlo0j6406504713.jpg
    * G; G: h' x, O* h# f. i3 e
    但是,为了代码有比较好的可移植性,一般建议我们对字符变量进行显式定义,比如:有符号使用 signed char 进行定义,无符号使用 unsigned char 进行定义
    - d+ }$ K; x1 x9 e而对于其他数据类型,比如 int , short , long , float , double 等等,则不存在类似于 char 之类的情况,这些数据类型的符号位通常都是确定好的。9 }- l# G, A7 ]$ [  o1 n+ \
    基础不牢,又浪费了一个下午。
    0 n$ ?) M% F, S) H

    sk0fy4njh54Hurt6504813.png

    sk0fy4njh54Hurt6504813.png
    % ^2 v, [$ R# x( z& S/ o8 \
    -END-
    ! y# Z! j5 ]+ G; I' x  ~往期推荐:点击图片即可跳转阅读7 ^5 |" E; K% f  m0 h
                                                            & `; T5 o" O3 p1 m
                                                                    9 B. y, l3 a7 V/ {
                                                                           
    ( }$ n1 }  O  r1 ~                                                                                , P5 G1 [. N* R) ~% E- Z! c

    cttowrc4hf56406504913.jpg

    cttowrc4hf56406504913.jpg

      X/ m- R9 t: y9 @/ q* A                                                                                ! h2 D2 c* t  E: z) h( }
                                                                                            嵌入式 C 语言知识点,动态变长数组
    . W; h+ c* W7 S5 }! y' P                                                        + v# I$ A9 E, @' n" }
                                                                    1 M* ~  z# f0 ?( |' k
                                                                           
    * J9 O. ^- i9 O. {. Y, H  b                                                                               
    . t2 G$ W" O' @7 _: l7 Q9 n

    ejhvsn1g1dg6406505013.jpg

    ejhvsn1g1dg6406505013.jpg
    # B% I4 q7 J) U' B
                                                                                    5 w+ ^; O# x0 g, Q; N
                                                                                            嵌入式 C 语言特性,指定初始化器7 {' a0 C% }( s0 K, l4 z( W6 e8 x0 E
                                                                   
    ' R8 F; \( F" U' z                                                                        ) D: a' ~( }, ~  q$ i  s
                                                                                   
    5 s3 m) B- o  x. F7 r

    p55h0pk0ucg6406505113.jpg

    p55h0pk0ucg6406505113.jpg
    & [: i% W% a1 W
                                                                                    # f) c8 x- T; N1 Z
                                                                                            嵌入式 C 语言知识点,掩码结构体
    4 y( ~* c' s$ e6 r: e' I/ q8 v& @. m我是老温,一名热爱学习的嵌入式工程师
      N6 Q& d, k+ g4 i; z关注我,一起变得更加优秀!
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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