大二寒假读书笔记150207

来源:互联网 发布:足球图案含字母js设计 编辑:程序博客网 时间:2024/04/24 12:04

1、类型转换
一点概念性的东西:表达式是否合法取决于操作数的类型,而且合法的表达式其含义也有其操作数类型决定。但是在C++中,某些类型存在相关的依赖关系。若两种类型相关,则可在需要某种类型的操作数位置上,使用该类型的相关类型对象 或值。如果两个类型之间可以相互转换,则称这两种类型相关。

int ival = 0;ival = 3.1415 + ival;//with a warning

转换规则由编译器自动执行,无需程序猿介入,被称为隐式类型转换。
2、何时发生隐式类型转换:
*在混合类型的表达式中,操作数被转换为相同的类型
*用作条件的表达式被转换为bool类型:条件操作符中的第一个操作数、逻辑非、逻辑与和逻辑或的操作数都是条件表达式。还有if,while, for和do while语句中的。
*用一表达式初始化某个变量,或将表达式赋值给某个变量,则该表达式被转换为该变量的类型。
3、算术转换
转换规则要确保计算值的精度。例如一个long double类型的操作数,无论另一个操作数是什么类型,都将被转换为 long double.
最简单的转换为整型转换:对于所有比int小的整型,包括char、signed char、unsigned char、short和unsigned short,如果将该类型的所有可能的值都能包容在int内,它们会被提升为int型,否则将被提升为unsigned int型。

bool flag;char cval;short sval;unsigned usval;int ival; unsigned int uival;long lval;unsigned long ulval;float fval;double dval;3.1415L + 'a';//97dval + ival;//int to doubledval + fval;//float to doubleival = dval;//doule to intflag = dval;//double to boolcval + fval;//char to int,int to floatsval + cval;//short and char to intcval + lval;//char to longival + ulval;//int to unsigned longusval + ival;//?uival + lval;//?

包含short和int类型的表达式,short类型的值转换为int。如果int型足够表示所有的unsigned short型值,就转换为int,否则两个都转换为unsigned int。long和unsigned int型也是一样的。只要机器上的long类型足够表示unsigned int那么就转换为long,否则两个都转换为unsigned long.
3、其他隐式转换
C++自动将枚举类型的对象或枚举成员转换为整型。无论枚举值的最大值是什么,enum对象或枚举成员至少提升为int型。如果int型无法表示枚举成员的最大值,则提升到能表示所有枚举成员值的、大于int型的最小类型(unsigned int,long,unsigned long)

当使用非const对象初始化const对象的引用时,系统将非const对象转换为const对象。此外,还可以将非const对象的地址转换为指向相关const类型的指针:

int i;const int ci = 0;const int &i = i;const int *p = &ci;

还可以由标准库类型的转换,其实很常见:

string s;while(cin>>s)

无论读入是否成功,表达式的结果都是cin.将istream类型转换为bool类型意味着要检验流的状态。如果最后一次读入流的状态是成功的,那么转换为true,否则转换为false.
4、说下非常危险的显式转换
也被称为强制类型转换(cast),包括以下列名字命名的操作符:
static_cast,dynamic_cast,const_cast和reinterpret_cast。

double dval;int ival;ival *= dval;

为了与dval做乘法,ival需要先转换为double型,然后将double型的结果结尾称int型,再赋值给ival.

ival *= static_cast<int>(dval);

这样就省去了ival转换为double型这个步骤。不过两种方式结果不同。一个是先计算再取整,另一个是先取整再计算,如果ival = 2,dval = 3.5。那么结果一个是10,一个是9.
dynamic_cast支持运行时识别指针或引用所指向的对象。
const_cast将转换掉表达式的const性质。不赘述
static_cast编译器隐式执行的任何类型转换都可以由static_cast显式完成:

double d = 97.0;char ch = static_cast<chat>(d);//ch == 'a'

当需要一个较大的算术类型赋值给较小的类型时,使用强制转换非常有用。它告诉编译器,我们知道但是不关心潜在的精度损失。此时没有警告信息。
reinterpret_cast通常为操作数的位模式提供较低层次的重新解释。为了安全使用它,程序猿需要完全理解所所涉及的数据类型,以及编译器实现强制类型转换的细节。

int *pi;char *pc = reinterpret_cast<char *>(ip);string str(pc);//error

pc指向的真实对象永远是int型,而并非字符数组。重要的是,运行这段代码并不会报错,因为编译器默认你已经知道并且忽略了它!所以使用强制类型转换是很危险的!

0 0