C/C++强制/自动类型转换

C语言自动类型转换

unsigned 即为 unsigned int ,此时可以省略int 只写unsigned 
隐式的类型转换是安全的,而显示的类型转换是存在风险的。
 
 
 
C语言强制类型转换

C语言中 涉及 地址间强制类型转换  特别要注意 字节对齐 的问题
unsigned int value = 1024;  // 4 个 字节  
cout << hex << &value << endl;
 
bool *p = (bool*)(&value);
cout << hex << p << endl;
 
p++;
cout << p << endl;
 
bool condition = *((bool *)(&value));  //(bool *)(&value);取的是第一位的地址
if (condition)
    printf("condition=1");
else
    printf("condition=0");
 
// 需要从大小端存储方式分析
 
    struct point{
        int a;
        int *b;
    }p;
    p.a = 300;
    p.b = (int*)500; // p.b为地址,地址,地址!!!!
//     ptr指向地址为500的位置,其中的内容是未知的
//    (前提是系统允许用户操作500这个地址)
    printf("%d \n", 10 + p.a  );// 值改变
    printf("%d \n", 100 + p.a );
//    p.b为地址,+表示偏移
    printf("%d \n",  p.b + 1);  // 指针p.b偏移1 * 4,
    printf("%d \n",  p.b + 100); // 指针p.b偏移100 * 4
    printf("%d \n",  p.b + p.a); // 指针p.b偏移p.a * 4
 
 
 
C++ 强制类型转换

static_cast
static_cast<newType> (data) 
 
double a = 19.95
int b = static_cast<int> (a)
 
适用于:
  • 原有的自动类型转换。如:short -> int;
  • void指针和具体类型指针间的转换。如:void * -> int *、 char * -> void *
  • 有转换构造函数或者类型转换函数的类与其它类型之间的转换。如 double 转 Complex(调用转换构造函数)、Complex 转 double(调用类型转换函数)。
不适用于:
  • 两个具体类型指针之间的转换,例如int *转double *、Student *转int *等(不同类型数据存储格式、长度都不一样)
  • 不能用来去掉表达式的 const 修饰和 volatile 修饰。换句话说,不能将 const/volatile 类型转换为非 const/volatile 类型。
 
 
const_cast
const_cast<newType> (data)
 
const int n = 100;
int *p = const_cast<int*>(&n);
*p = 12345;
 
 
const char *p = str1.c_str();
char* pp = const_cast<char*>(p);
它用来去掉表达式的 const 修饰属性或 volatile 修饰属性。换句话说,const_cast 就是用来将 const/volatile 类型转换为非 const/volatile 类型
 
 
 
dynamic_cast( 涉及到RTTI
使用形式如下:
dynamic_cast<type*  >(e);
dynamic_cast<type&  >(e);
dynamic_cast<type&& >(e);
type必须是一个类 类型,type 和 en 必须同时是指针类型或者引用类型或void *
对于指针,如果转换失败将返回 NULL;对于引用,如果转换失败将抛出std::bad_cast异常
dynamic_cast 用于在类的继承类之间进行类型转 换。 它依赖于RTTI(这就要求基类必须拥有虚函数,因为RTTI信息存储在虚函数表中),它允许向上转型也允许向下转型向上转型(派生类指针或引用转基类)是无条件的,不会进行任何检测,所以都能成功;(派转基) 向下转型(基类指针或引用转派生类)的前提必须是安全的,在程序运行期间要借助 RTTI 进行类型转换,这就要求基类必须包含虚函数,而static_cast在编译期间完成类型转换。(基转派)
e能成功转换为type*类型的情况有三种:
1)e的类型就是type的类型时,一定会转换成功(不要求有虚函数的限定)。(本身转换)
2)e的类型是目标type的公有派生类:派生类向基类转换一定会成功(不要求有虚函数的限定)。(派转基)
 
3)e的类型是目标type的基类,(基类必须要有虚函数)(基转派)
   当e是指针指向派生类对象,或者基类引用引用派生类对象时,类型转换才会成功,
   当e指向基类对象,试图转换为派生类对象时,转换失败
 
 
注:上指父类(基类),下指子类(派生类)
 
 
reinterpret_cast
reinterpret_cast<newType> (data)
 
char str[]="abcdefgh";
float *p1 = reinterpret_cast<float*>(str); //用一个 float 指针来操作一个 char 数组是一件多么荒诞和危险的事情
cout<<*p1<<endl;
 
是“重新解释”的意思,顾名思义,reinterpret_cast 这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整, 非常简单粗暴,所以十分危险,不到万不得已时应避免使用
可以用于两个具体类型指针之间的转换、int 和指针之间的转换(有些编译器只允许 int 转指针,不允许反过来)。
 
 
 
 
 
 
 
 
 
 
 
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值