C类型转换

/**
类型转换

1.隐式类型转换(implicit conversion)
当两个操作数类型相同时计算机才能进行二元算数操作
而在二元算术运算中使用不同类型的操作数,编译器会把值域较小的操作数类型转换为另一个操作数类型

隐式类型转换规则
两个操作数类型包含long double,则另一个转换为long double;无且含double,则另一个变为double;又无且含float,另一个变为float
否则,若两个均为整数,把低级别操作数类型变为另一个数类型,无符号整数低到高:char,short,int,long,long long
一个有符号整数与一个无符号整数,把级别低的转换为级别高的;若两者级别相同,有符号转换为无符号   **/

#include <iostream>
using namespace std;
int main() {
    bool a = 3.0;           //非零即真
    float b = -99999.2301;  //double转换为float,丢失精度
    int c = b;              //float转换为int,只保留了整数部分
    unsigned int d = c;     //二进制下进行符号扩展后转换为10进制,就会出错
    short e = d;            //长数据转换为短数据,出错
    double f = b;           //double转换为float,正常
    //值域小精度低的对象赋值给值域大精度高的对象是安全的,若不得不反着做,确保精度损失可接受,且不会溢出

    cout.setf(ios_base::fixed, ios_base::floatfield);
    cout << "a = " << a << "\nb = " << b << "\nc = " << c << "\nd = "
        << d << "\ne = " << e << "\nf = " << f << endl;
    return 0;
}

#include <iostream>
using namespace std;
int main() {
	int i = 3;
	auto a = 10 / i;
	cout << "10/3 = " << a << ",type= " << typeid(a).name() << endl;
	//	整数/整数=整数
	auto b = double(10.0) / i;
	cout << "10.0/3= " << b << ",type= " << typeid(b).name() << endl;
	//	浮点数/整数=浮点数
	auto c = i / double(10.0);
	cout << "3/10.0= " << c << ",type= " << typeid(c).name() << endl;
	//	整数/浮点数=浮点数
	auto d = double(10.0) / 3.0f;
	cout << "10.0/3.0f= " << d << ",type= " << typeid(d).name() << endl;
	//	双精度浮点数/单精度浮点数=双精度浮点数
	auto e = (unsigned int)10 / i;
	cout << "unsigned 10/3= " << e << ",type= " << typeid(d).name() << endl;
	//	无符号整数/有符号整数=无符号整数
	auto f = 10 / (unsigned int)3;
	cout << "10/unsigned 3= " << f << ",type= " << typeid(f).name() << endl;
	//	有符号整数/无符号整数=无符号整数
	return 0;
}   //在上述算数计算中都发生了隐式类型转换,但只是创建了一个被转换对象的副本,不会改变对象自身,比如i仍为int类型

//列表初始化(list initalization)可以不恰当的隐式类型转换带来的差错
//列表初始化不允许收窄(narrowing):当被初始化变量无法准确表达{}内字面量或常量时,编译器报错不编译
#include <iostream>
using namespace std;
int main() {
	char c = 712;	//允许,溢出
	char d{ 66 };	//允许,char范围内
	//char e{ 712 };	//不允许,超出范围不编译
	//unsigned int f{ -1 };	//不允许,unsigned int只存非负整数
	//int g{ 3.12 };	//不允许收窄
}

/***
类型提升
符号扩展&零扩展
    (1)符号扩展:对于扩展量为有符号数,在新的高位字节使用当前最高有效位(符号位)进行填充
    (2)零扩展:对于扩展量为无符号数,在新的高位直接填0    ***/
#include <iostream>
#include <bitset>
using namespace std;
int main() {
    cout << "signed --> signed" << endl;
    char a = 0xff;
    short b = a;
    cout << "a= " << bitset<8>(a) << endl;
    cout << "b= " << bitset<16>(b) << endl;
    char c = 1;
    short d = c;
    cout << "c= " << bitset<8>(c) << endl;
    cout << "d= " << bitset<16>(d) << endl;

    cout << "unsigned --> unsigned" << endl;
    unsigned char e = 0xff;
    unsigned short f = e;
    cout << "e= " << bitset<8>(e) << endl;
    cout << "f= " << bitset<16>(f) << endl;

    cout << "signed --> unsigned" << endl;
    char g = 0xff;
    unsigned short h = g;
    cout << "g= " << bitset<8>(g) << endl;
    cout << "h= " << bitset<16>(h) << endl;

    cout << "unsigned --> signed" << endl;
    unsigned char k = 0xff;
    short m = k;
    cout << "k= " << bitset<8>(k) << endl;
    cout << "m= " << bitset<16>(m) << endl;

    return 0;
}
/***
2.显式类型转换
(1)短数据扩展为长数据
    (i)扩展量为有符号数:符号扩展,即用符号位填高字节位
    (ii)扩展量为无符号数:零扩展,用零填高字节位
    (iii)若为有符号短转无符号长,先进行符号扩展,再按(3)直接赋值
(2)长数据缩短为短类型
    高字节全1或全0,直接截取低字节赋值给短数据;若不全为1或0,出错
(3)同一长度有符号与无符号数相互转化
    直接将内存中的数据赋值给被转化类型      ***/

/***
C风格强制类型转换
格式:Type b = (Type)a;转换目标类型置于对象前方括号中
在C++中,还可以采用类似面向对象中构造函数的格式: Type b = Type(a)
这种强制类型转换直接在二进制位上转换,没有类型检查,出现异常不会报错,容易在程序运行期间产生错误***/

#include <iostream>
using namespace std;
int main() {
	char c = 'K';
	cout << "c= " << c << endl;
	cout << "ASCII code for 'K': " << (int)c << endl;
	cout << "ASCII code for 'K': " << int(c) << endl;
	cout << "ASCII code for 'K': " << static_cast<int>(c) << endl;
	return 0;
}


//C++中4种强制类型转换...续

/*
静态转换
static_cast<new_type>      (expression)
动态转换
dynamic_cast<new_type>     (expression) 
常量转换
const_cast<new_type>       (expression) 
重新解释转换
reinterpret_cast<new_type> (expression)
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值