谈谈C++的类型转换。
来源:互联网 发布:中石油风险矩阵 编辑:程序博客网 时间:2024/06/05 21:12
学习C++已经很久了,由于工作原因,很长一段时间没有用了,再加上经常用一些脚本语言,使得对C++的一些概念,反而有些混乱。所以这里我跟大家一起讨论一下C++的类型转换。如文章中有任何纰漏,还请指正。
众所周知,在PYTHON和其他一些脚本语言中,声明变量是不需要指定类型的。
a=5
b="hello"但是在C++中这样声明变量,显然是不能通过编译的。需要指定变量的类型:
int a=5;char b[]="hello"如果经常用脚本语言你想要a+b
那么在PYTHON中你直接这样就行了
c=chr(a)+bprint(c)解释器会自动根据你指定的类型转换函数 ,直接操作并得出结果,下面是PYTHON中的一些类型转换函数:
[python]
<span style="white-space:pre"></span>int a = 5;<span style="white-space:pre"></span>char b[] = "hello";<span style="white-space:pre"></span>char c[10];<span style="white-space:pre"></span>_itoa_s(a, c, 10);<span style="white-space:pre"></span>strcat_s(c, b);<span style="white-space:pre"></span>printf("%s", c);
这样看来是相当的复杂了。所以我们还是有必要学习一下C++的类型转换。也是为了方便以后的应用。我们在实际应用中一般很少对对象直接进行类型转换。而且这样也经常是不合法的。
例如
struct m {int a;char b;};struct r {float a;double b;};void printm(r* c){printf("%f,%f",c->a,c->b) }int main(int argc, char* argv[]){m mystruct;mystruct.a = 5;mystruct.b = 'a';printm(&mystruct);
return 0;
}编译器会提示不存在用户定义的类型转换。那么我们怎么才能让程序顺利的运行呢。只能用一些类型转换的技巧。
struct m {int a;char b;};struct r {float a;double b;};void printm(r* c){printf("%f,%f", c->a, c->b);}int main(int argc, char* argv[]){m mystruct;mystruct.a = 6;mystruct.b = 'b';LPVOID t = &mystruct;printm((r*)t);system("pause");}这样就可以顺利的编译通过,虽然打印的值跟自己想要的结果大相径庭。我们这里用到一个概念就是 VOID LPVOID的指针。通过转换指针类型,来强制满足编译器对类型的要求。我们之所以这样做,还是因为C++中的各种数据类型所占的内存空间是不一样的。
16位编译器
char :1个字节
char*(即指针变量): 2个字节
short int : 2个字节
int: 2个字节
unsigned int : 2个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节
32位编译器
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节
64位编译器
char :1个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节
正是因为如此,所以我们想要直接转换数据类型是行不通的。只能通过一些技巧才能进行转换。尤其是在用户自定义的数据类型中。特别重要。很多时候我们会被各种各样的类型转换弄得晕头转向。下面这段代码说明了为什么指针之间的类型转换会被编译器所接受。
struct m {int a;char b;};int main(int argc, char* argv[]){int a = sizeof(int*);int b = sizeof(double*);int c = sizeof(char*);int d = sizeof(m*);
<span style="font-family: Arial, Helvetica, sans-serif;"> int f = sizeof(LPVOID);</span>
printf("%d,%d,%d,%d,%d",a, b, c, d,f);system("pause");return 0;}用好C++的关键除了OOP之外,就是我们能够正确的把一个数据类型传递给函数。有时候我们编写了自己的类/结构体。但是需要传递的函数参数的类型却与我们的大相径庭。如何才能把自己的数据结构正确的传递给函数的参数。决定了我们对C++数据类型的掌握程度。有些时候我们的转换虽然通过了编译器,但是却隐藏了致命的错误,使得程序在发布之后出现各种BUG,因此我觉得这个类型转换真的需要好好的学习,理解。
当然我们还需要知道C++中的4种强制类型转换。
1、static_cast
用法:static_cast (expression)
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
(1)用于类层次结构中基类和派生类之间指针或引用的转换
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的
进行下行转换(把基类的指针或引用转换为派生类表示),由于没有动态类型检查,所以是不安全的
(2)用于基本数据类型之间的转换,如把int转换成char。这种转换的安全也要开发人员来保证
(3)把空指针转换成目标类型的空指针
(4)把任何类型的表达式转换为void类型
注意:static_cast不能转换掉expression的const、volitale或者__unaligned属性。
2、dynamic_cast
用法:dynamic_cast (expression)
该运算符把expression转换成type_id类型的对象。type_id必须是类的指针、引用或者void*;
如果type_id是类指针类型,那么expression也必须是一个指针,如果type_id是一个引用,那么expression也必须是一个引用。
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
3、reinterpret_cast
用法:reinterpret_cast (expression)
type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。
它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,
在把该整数转换成原类型的指针,还可以得到原先的指针值)。
该运算符的用法比较多。
(static_cast .与. reinterpret_cast比较,见下面 )
该运算符平台移植性比价差。
4、const_cast
用法:const_cast (expression)
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。
为什么都说C++是一个复杂的语言,我觉得不是他的OOP特性,而是这些基于底层的细节导致的。在敏捷型语言快速发展遍地开花的今天。我们要想把C++学好,只能通过不断的反复学习,总结经验才能掌握好它的本质。
- 神奇的C语言二十:谈谈类型转换
- 谈谈C++的类型转换。
- 谈谈Nullable<T>的类型转换问题
- 谈谈强制类型转换
- 谈谈强制类型转换
- 谈谈C++的类型转换符 static_cast、dynamic_cast、const_cast、reinterpret_cast
- C#.NET 的 类型转换
- C语言的类型转换
- C语言的类型转换
- C语言的类型转换
- c语言的类型转换
- C++/C指针的类型转换
- 谈谈MySQL隐式类型转换
- 谈谈MySQL显式类型转换
- <C/C++> 类型转换
- C/C++:类型转换
- C语言里的指针类型转换
- C#问题--如何转换数组的类型
- SQL Server判断对象是否存在 (if exists (select * from sysobjects )(转)
- GPUImage setInputRotation
- Postman测试大全
- 免费的聚合数据新闻头条API接口调用
- Ubuntu下为AndroidStudio编译并使用x264(一)ndk部分
- 谈谈C++的类型转换。
- Spring Mybatis 返回 List<String> 和List<Map<String,Object>>
- Deep learning:四十一(Dropout简单理解)
- 四轴飞行前检查及解锁
- 第十周项目1-二叉树算法库
- 创建用户
- 一些正则表达式
- Ubuntu 秘笈之命令行下管理浏览器书签
- 第五周项目2-建立顺序栈算法库