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. ZOJ 3725 Painting Storages(DP+排列组合)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5048 Sample Input 4 3 Sample Output ...

  2. APACHE 与IIS同时存在的情况下,给APACHE添加反向代理 共用80端口

    一.首先打开IIS,将IIS的端口改成81,不要让IIS占用了80端口 二.打开APACHE的httpd.conf配置文件,将里面的端口配置成80 三.打开APACHE的虚拟目录配置文件,如:http ...

  3. python基础之列表常用操作及知识点小结

    列表(list) List(列表) 是 Python 中使用最频繁的数据类型.列表可以完成大多数集合类的数据结构实现.它支持字符,数字,字符串甚至可以包含列表(所谓嵌套).列表用[ ]标识,是pyth ...

  4. c++中的vector原理

    vectorvector就是动态数组.它也是在堆中分配内存,元素连续存放,有保留内存,如果减少大小后,内存也不会释放.如果新值>当前大小时才会再分配内存. 它拥有一段连续的内存空间,并且起始地址 ...

  5. Android中自定义ListView无法响应OnItemClickListener中的onItemClick方法问题解决方案

    如果你的自定义ListViewItem中有Button或者Checkable的子类控件的话,那么默认focus是交给了子控件,而ListView 的Item能被选中的基础是它能获取Focus,也就是说 ...

  6. 上传XML文件字符编码问题

    1.上传的XML文件的空格的字符编码和倒入到数据库的空格的字符编码不是一种编码格式,导致导入到数据库的数据和XML文件的数据不一致的情况,进而使展示到界面上的数据在进行搜索时不能搜索出来.解决办法: ...

  7. iOS:等待控件

    定义: @interface ViewController () { UIActivityIndicatorView *testActivityIndicator; } 实例化,开始旋转: -(voi ...

  8. HashMap遍历,推荐使用entrySet()

    之前map遍历,偶尔会先去keyset然后再遍历keyset 比如 Map map = new HashMap(); Iterator it = map.keySet().iterator(); wh ...

  9. 完全卸载mysql 停止服务、卸载相关程序、删除注册表

    本节主要介绍了完全卸载mysql的具体步骤包括停止服务.卸载相关程序.删除注册表等等   1. 停止服务MySQL 2. 卸载mysql相关的程序 3. 删除注册表(运行->regedit),m ...

  10. DIV焦点事件

    div本来是没有focus和blur事件的. 如果用div来模拟一个input标签,同时需要它和input一样响应focus和blur事件, 就需要给他加上attribute:tabindex An ...