zoukankan      html  css  js  c++  java
  • C语言中数据类型转换的学习

    1. 整型和枚举类型数据的转换
    测试代码如下:
    #include <stdio.h>

    typedef enum _E_TYPE_T
    {
        E_TYPE_1 = -1,
        E_TYPE_2,
        E_TYPE_3,
        E_TYPE_END
    }E_TYPE_T;

    int main(int argc, char* argv[])
    {
        unsigned char ui1_value = 0;
        E_TYPE_T e_type = E_TYPE_1;
       
        printf(" ui1_value=%d,e_type=%d,e_type=%x ", ui1_value, e_type, e_type);
       
        ui1_value = e_type;
        e_type = ui1_value;
       
        printf(" ui1_value=%d,e_type=%d,e_type=%x ", ui1_value, e_type, e_type);
       
        return 0;
    }

    [~sh] gcc -o type_conversion_main type_conversion_main.c
    [~sh] ./type_conversion_main

    ui1_value=0,e_type=-1,e_type=ffffffff

    ui1_value=255,e_type=255,e_type=ff

    从实际运行结果来看,经过转换后的e_type的值显然不是程序员所期望的,这就会导致程序出错。
    那应该要如何规避这个问题呢?大概有两种解法,
    第一种就是不要定义unsigned char类型的ui1_value,而是定义一个signed char类型的i1_value,
    第二种方法就是枚举类型中的成员从0开始计算,这样就可以避免有符号数和无符号数操作带来
    的隐式数据转换,经过测试这两种方法均可行。

    2. 整型和指针之间的转换
    测试代码如下:
    #include <stdio.h>

    static int _get_data(int* pui4_value)
    {
        *pui4_value = 0x12345678;
        return 0;
    }

    int main(int argc, char* argv[])
    {
        char ui1_value_0 = 0;
        char ui1_value_1 = 0;
        char ui1_value_2 = 0;
       
        _get_data((int*)&ui1_value_2);
       
        printf("ui1_value_0=%d,ui1_value_1=%d,ui1_value_2=%x ", ui1_value_0, ui1_value_1, ui1_value_2);
       
        return 0;
    }

    [~sh] gcc -o type_conversion_main type_conversion_main.c
    [~sh] ./type_conversion_main

    ui1_value_0=34,ui1_value_1=56,ui1_value_2=78
    [~sh]

    这是怎么回事?明明只是去修改ui1_value_2,但是ui1_value_0,ui1_value_1的值怎么会变?
    仔细的看,这个很有规律,原来是踩内存了。
    原来int类型的数据会占用4个字节的内存,_get_data的参数是int*类型,所以调用_get_data后
    它会回写四个字节的数据到指定的地址。
    而ui1_value_2是char类型的数据,它只占用1个自己的内存空间,所以_get_data就会从ui1_value_2所处的地址
    连续的写入4个字节的数据。
    所以,我们知道,使用指针参数时一定要预留足够的空间以便于存储回传的数据,否则很容易就会踩内存;
    而踩内存造成的后果是会出现大问题的。
    此例的解法就是:定义一个int类型的变量ui4_value来接收_get_data的回传值,
    经测试该方法可行。

    3. signed和unsigned类型数据之间的转换
    测试代码如下:
    #include <stdio.h>

    int main(int argc, char* argv[])
    {
        signed char i1_value = -100;
        unsigned char ui1_value = 10;
        unsigned signed char sum = 0;
       
        sum = i1_value + ui1_value;
       
        printf(" sum=%d ", sum);
       
        return 0;
    }

    [~sh] gcc -o type_conversion_main type_conversion_main.c
    [~sh] ./type_conversion_main

    sum=166
    [~sh]

    这显然不是程序员所期望的结果。之所以出现这样的结果,是因为这涉及到数据转换中的一个隐式自动转换规则。
    因为sum是unsigned char类型的数据,所以在做加法运算时i1_value被自动转换为unsigned char类型,
    从而导致程序出现不预期的结果。
    此例的解法就是定义sum为signed char类型。

    结论:
    1. 不同类型的数据如果需要相互转换,尽量要做到显示的转换,这也会增加代码的可读性;
    2. 不同类型的数据之间的操作一定要特别特别小心;
    3. 我们不是编译器开发者(实际上就算是编译器开发者也不见得了解编译器的所有特性),所以尽量不用编译器所赋予的隐含的技巧.

  • 相关阅读:
    vsftpd安装问题汇总(持续更新。。)
    Office2010安装问题总结
    AM335X 开发板安装vsftpd操作流程
    Source Insight常用快捷键及注释快捷键设置
    小四轴之第二次飞行篇
    linux命令df中df -h和df -i
    Linux tail 命令
    Linux chmod命令用法
    ps -ef |grep java
    jupyter notebook安装、登录
  • 原文地址:https://www.cnblogs.com/riskyer/p/3357856.html
Copyright © 2011-2022 走看看