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("\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语言中数据类型转换的学习的更多相关文章
- C语言中强制类型转换总结
C语言中强制类型转换总结 ● 字符型变量的值实质上是一个8位的整数值,因此取值范围一般是-128-127,char型变量也可以加修饰符unsigned,则unsigned char 型变量的取值范围 ...
- JavaScript中数据类型转换总结
JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...
- HQL语句中数据类型转换,及hibernate中createQuery执行hql报错
一.HQL语句中数据类型转换: 我们需要从数据库中取出序号最大的记录,想到的方法就是使用order by子句进行排序(desc倒序),然后取出第一个对象,可是当初设计数据库时(我们是在原来的数据库的基 ...
- Java中数据类型转换&基本类型变量和对象型变量
1.Java的数据类型分为三大类 布尔型,字符型和数值型 其中数值型又分为整型和浮点型 2.Java的变量类型 布尔型 boolean 字符型 char 整型 byte,short,int,lo ...
- PHP中数据类型转换的三种方式
PHP中数据类型转换的三种方式 PHP的数据类型转换属于强制转换,允许转换的PHP数据类型有: 1.(int).(integer):转换成整形2.(float).(double).(real):转换成 ...
- JS中数据类型转换
JS中数据类型转换汇总 JS中的数据类型分为 [基本数据类型] 数字 number 字符串 string 布尔 boolean 空 null 未定义 undefined [引用数据类型] 对象 obj ...
- Arduino中数据类型转换 int转换为char 亲测好使,itoa()函数
由于博主最近在做一个项目,需要采集不同传感器的数据,包括float型的HCHO,以及int型的PM2.5数据.但是最终向服务器上传的数据都得转换为char型才能发送,这是借鉴了一个github上面的实 ...
- C语言关于数据类型转换
自动类型转换 自动类型转换就是编译器默默地.隐式地.偷偷地进行的数据类型转换,这种转换不需要程序员干预,会自动发生. 1) 将一种类型的数据赋值给另外一种类型的变量时就会发生自动类型转换,例如: ; ...
- C语言:数据类型转换 自动转换 强制转换
数据类型转换就是将数据(变量.数值.表达式的结果等)从一种类型转换为另一种类型. 自动类型转换 自动类型转换就是编译器默默地.隐式地.偷偷地进行的数据类型转换,这种转换不需要程序员干预,会自动发生.1 ...
随机推荐
- OC - 15.NSURLSession与NSURLSessionTask
简介 NSURLSession也能完成网络请求 NSURLConnection在iOS9中不推荐使用,NSURLSession是iOS9中推荐使用的网络请求方式 NSURLSession需要与NSUR ...
- C# 反射 表达式树 模糊搜索
反射实体T,非datetime字段反射获取表达式树 public static Expression<Func<T, bool>> GetSearchExpression& ...
- 关于java中for和foreach循环
for循环中的循环条件中的变量只求一次值!具体看最后的图片 foreach语句是java5新增,在遍历数组.集合的时候,foreach拥有不错的性能. foreach是for语句的简化,但是forea ...
- 视频处理简单实例 [OpenCV 笔记2]
VideoCapture是OpenCV 2.X中新增的类,提供从摄像机或视频文件捕获视频的C++接口.利用它读入视频的方法一般有两种: // method 1 VideoCapture capture ...
- 【工具篇】source Insight
不多说,阅读代码利器. 一.修改背景颜色 使用淡绿色更护眼(听说而已),菜单“选项”>>“属性”,使用自己喜欢的颜色吧.我的淡绿色RGB是181,236,207 二.行号,空格替换tabs ...
- mws文件中的tab文件改为相对路径
用mapinfo将现有的多个图层(tab)文件保存成一个mws工作空间后,将此mws文件发到另一台电脑上后,打开mws,提示无法打开各个tab文件,文件不存在,显示的路径是当时原电脑添加时的绝对路径. ...
- PHPCMS实现文章置顶功能的方法
我个人喜欢把PHPCMS当作博客来用,而作为一个博客,怎能少了文章置顶功能呢?其中用PHPCMS实现置顶功能非常简单,无非是修改下推荐位的名称为置顶,然后在文章列表中推送需要置顶的文章罢了. 不过博客 ...
- 从文章"避免复制与粘贴"到文章"Extract Method"的反思(3)
在牛人的博客中提到了..如果你的代码可以copy-past的时候,那么久证明你的代码出现了重复.而这种重复仅仅是虚假的代码行的增加而不是像其他的代码复用那样降级成本. copy-pase代码意味着你违 ...
- 关于Keil的安装与注册
由于前一段时间一直在做关于stm32f407的相关内容,于是安装的Keil是MDK5,最近一阵子想再看看51单片机以前没有做过的内容,就要再安装一个Keil C51,结果就不可避免的遇到了两个软件必须 ...
- resolvconf: Error: /etc/resolv.conf isn't a symlink, not doing anything.
一.问题出现的原因 resolv.conf默认是个软链接,resolvconf默认会检查resolv.conf不是软链接就报错 默认的情况是这样的: #ls -l /etc/resolv.conflr ...