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("\nui1_value=%d,e_type=%d,e_type=%x\n", ui1_value, e_type, e_type);
   
    ui1_value = e_type;
    e_type = ui1_value;
   
    printf("\nui1_value=%d,e_type=%d,e_type=%x\n", 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\n", 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("\nsum=%d\n", 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. 我们不是编译器开发者(实际上就算是编译器开发者也不见得了解编译器的所有特性),所以尽量不用编译器所赋予的隐含的技巧.

C语言中数据类型转换的学习的更多相关文章

  1. C语言中强制类型转换总结

    C语言中强制类型转换总结  ● 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围 ...

  2. JavaScript中数据类型转换总结

    JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...

  3. HQL语句中数据类型转换,及hibernate中createQuery执行hql报错

    一.HQL语句中数据类型转换: 我们需要从数据库中取出序号最大的记录,想到的方法就是使用order by子句进行排序(desc倒序),然后取出第一个对象,可是当初设计数据库时(我们是在原来的数据库的基 ...

  4. Java中数据类型转换&基本类型变量和对象型变量

    1.Java的数据类型分为三大类 布尔型,字符型和数值型 其中数值型又分为整型和浮点型 2.Java的变量类型 布尔型 boolean 字符型 char 整型    byte,short,int,lo ...

  5. PHP中数据类型转换的三种方式

    PHP中数据类型转换的三种方式 PHP的数据类型转换属于强制转换,允许转换的PHP数据类型有: 1.(int).(integer):转换成整形2.(float).(double).(real):转换成 ...

  6. JS中数据类型转换

    JS中数据类型转换汇总 JS中的数据类型分为 [基本数据类型] 数字 number 字符串 string 布尔 boolean 空 null 未定义 undefined [引用数据类型] 对象 obj ...

  7. Arduino中数据类型转换 int转换为char 亲测好使,itoa()函数

    由于博主最近在做一个项目,需要采集不同传感器的数据,包括float型的HCHO,以及int型的PM2.5数据.但是最终向服务器上传的数据都得转换为char型才能发送,这是借鉴了一个github上面的实 ...

  8. C语言关于数据类型转换

    自动类型转换 自动类型转换就是编译器默默地.隐式地.偷偷地进行的数据类型转换,这种转换不需要程序员干预,会自动发生. 1) 将一种类型的数据赋值给另外一种类型的变量时就会发生自动类型转换,例如: ; ...

  9. C语言:数据类型转换 自动转换 强制转换

    数据类型转换就是将数据(变量.数值.表达式的结果等)从一种类型转换为另一种类型. 自动类型转换 自动类型转换就是编译器默默地.隐式地.偷偷地进行的数据类型转换,这种转换不需要程序员干预,会自动发生.1 ...

随机推荐

  1. Mysql中explain命令查看语句执行概况

    Mysql中可以使用explain命令查看查询语句的执行方式,使用方法举例:explain + 查询语句 例如:explain select * from user_info 几个重要的字段说明: t ...

  2. Windows phone 之样式的关联

    建议大家做界面要用Blend. 做过web的都知道DIV+CSS,给页面元素关联样式有三种方式: 1.内联样式表:就是在每个元素里面写style.优点就是灵活,给指定的元素添加样式.缺点是重用性很差, ...

  3. linux 的一个防火墙策略

    #警告:在运行脚本后,勿必单独运行 iptables -F#因为脚本包含的默认规则为“禁止所有访问”#当其它规则被清除后,系统表现为无法访问状态,需要重启系统恢复#iptables -L 查看当前已应 ...

  4. js隔行变色

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. php多线程即时通讯

    即时通讯:推送消息http://www.workerman.net/

  6. mysql基本介绍和优化技巧

    一. mysql框架和基本介绍 1. 框架图 更详细: 2. 存储引擎 MYISAM与INNODB对比: MYISAM:mysql5.1及以前版本的默认存储引擎.支持全文检索,压缩,表级锁等,但不支持 ...

  7. smarty 模板 数字自动添加

    section: section的产生是为解决foreach的不足的,与foreach一样,它用于设计模板内的循环块,它较为复杂,可极大程序上满足程序需要,所以在程序中我习惯使用它而不使用foreac ...

  8. General Purpose Hash Function Algorithms

    General Purpose Hash Function Algorithms post@: http://www.partow.net/programming/hashfunctions/inde ...

  9. android ListView 多次调用 getView方法

    <ListView            android:layout_width="match_parent"            android:layout_heig ...

  10. 如何通过数据库修改WordPress后台登录密码

    大家是否有过因为忘记WordPress后台登陆密码的时候?其实WordPress后台登陆密码的找回或修改的方法有多种,比如通过邮箱重启密码,又或者通过主机控制面板进入数据库修改等等.本篇教程以GoDd ...