设为首页 加入收藏

TOP

C++_系列自学课程_第_11_课_类型转换_《C++ Primer 第四版》(一)
2015-07-20 17:30:58 来源: 作者: 【 】 浏览:5
Tags:系列 自学 课程 _11_ 类型 转换 Primer
一、隐式类型转换
?
  在表达式中,有些操作符可以对多种类型的操作数进行操作, 例如 + 操作符的操作数可以同时有int型,也可以有float型, 这就引入了一个问题到底应该由什么
?
决定表达式的值的类型。 例如:
?
  3.1415926 + 5; ? //double类型 ?+ 整型, 结果为什么类型呢??
?
  3.1415926 * 2 ?* ?3 ; //double类型 * 整型 ?* 整型; 得到的表达式的值为什么类型呢??
?
  2 * 4UL; ? // 整型 * 无符号整型 ?, 得到的表达式的值的类型为什么呢??
  在C++中,为了解决这类问题引入了类型转换的机制。
?
  
?
1、什么时候会发生类型转换
?
  A: ?在具有混合类型的表达式中,会发生类型转换, 如上面的例子。
?
    3.14 * 4; ? 在计算的时候会发生类型转换,会将4转换为 4.0 然后与3.14 相乘。
?
  B:用作条件的表达式会被转换为bool类型
?
    int ?iVar;
    .......
    if(iVar)
      .......
  这里当做if语句的条件表达式的 iVar 会发生类型转换, ?当iVar 非零时转换为 true, ?当 iVar 为0时转换为false。
?
  C: 当bool类型的变量、值不是 !、&&、|| 操作符的操作数时会发生类型转换
?
    bool ?bVar;
?
    .......
    int ?iVar;
    int iResult;
    iResult = iVar + bVar; ?//这里bool量bVar会转换为整型?
  如上所示, ?bool量bVar会发生类型转换, 当bVar为真True时转换为1, 当bVar为假false时会转换0, ?这样就可以参与计算。
?
?
?
  D:当赋值操作符的左右操作数的类型不一致时会发生类型转换
?
    int ? iVar;
?
    iVar =3.1415926; //double类型的3.1415926会被转换为int型赋值给iVar;
  这里讲double类型的值转换为int型赋值给int型
?
  E:当其他类型的值初始化变量时会发生类型转换
?
  int ?iVar = 3.1415926; ?//赋值初始化,
或者
?
  int ?iVar(3.1415926); ? ?//直接初始化
  这里进行初始化时会将3.1415926 转换为int型,然后初始化iVar。
?
?
?
2、算术转换
?
  C++为内置的操作符和数据类型提供了一套默认的数据类型转换机制,其中最为常见的就是算术转换。 算术操作符 + 、- 、* 、/ 两个操作数的类型不一致时
?
就会发生数据类型转换, 在程序执行前,会将算术操作符两边的操作数转换为同一数据类型后才能进行算术操作。算术转换的基本原则就是在转换后要能保证计算的
?
精度。 例如如果算术操作符的操作数有一个为long double 那么就会将另外一个操作数转换为long double类型然后进行计算。
?
  在C语言中,会有如下基本的类型转换特点:
?
?
?
  注意的是float类型不会自动转换为double类型,这一点需要特别的注意。在C++中大体保持了这样一个转换规则,我们可以通过sizeof操作符来看看操作结果。
?
Exp:
?
复制代码
int main()
{
? ? cout<<"sizeof(3.14L * 2) is:"<
? ? cout<<"sizeof(3.14 * 2 ) is:"<
? ? cout<<"sizeof(3.14f * 2) is:"<
? ? cout<
? ? cout<<"sizeof(long int) is"<
? ? cout<<"sizeof('a'*'a') is:"<
? ? cout<<"sizeof(2L * 2) is:"<
?
?
? ? return 0;
}
复制代码
程序的执行结果为:
?
复制代码
[root@localhost cpp_src]# g++ test.cpp?
[root@localhost cpp_src]# ./a.out?
sizeof(3.14L * 2) is:12
sizeof(3.14 * 2 ) is:8
sizeof(3.14f * 2) is:4
?
sizeof(long int) is4
sizeof('a'*'a') is:4
sizeof(2L * 2) is:4
复制代码
  总结一句就是:
?
    1、对于所有比int类型小的整型,在计算的过程中都会转换为int型,如果其值都包含在int内,则会将操作数转换为int型然后进行计算, 如果其值
?
超过了int型的表示范围,则会转换为 unsigned int型进行计算。 如果操作数中有long 型,则会转换为long类型进行计算。
?
    2、对于浮点型,如果有long double则会转换为long double进行计算, 如果有double类型,则会转换为double类型进行计算, 如果有float则
?
会转换为float类型进行计算。
?
  对于这个需要特别注意的就是float类型不会自动提升为double类型,这个是与整型不一样的地方。
?
?
?
3、关于有符号和无符号数之间的转换
?
  讨论的是整型的无符号数和有符号数直接的转换, 这个是C/C++语言当中的一大难点, 前面我有一篇文章讨论过这个问题。这里再重新的描述一下。
?
  A: ?两个操作数为 unsigned short int 和 int
?
    如果int足够保存unsigned short int 的值,那么就会转换int进行计算,如果不能保存,那么就会转换为unsigned int 进行计算。
?
  B: 两个操作数为 unsigned int ?和 long int
?
    如果long int足够保存所有的unsigned int类型的值,那么就会转换为long int进行计算,否则就转换为unsigned long ?int 进行计算。
?
  C: 两个操作数为int 和unsigned int?
?
    这个地方有点需要注意,int会转换为unsigned int 后进行计算, 计算的结果为unsigned int类型,然后如果赋值给int 类型的话,那么可能出现溢出
?
的情况, 通过截断高位部分将unsigned int 类型的值赋值给int类型。
?
  这个地方一般也不太需要特别的注意,但是在一些特殊的地方则需要引起特别的关注。
?
?
?
4、关于指针和数组
?
  在我的以前的一篇随笔中曾经描述过这个问题,那就是在一般的情况下,数组(名)都可以转换为指针。例如:
?
  int ? ?iArray[3];
?
  int ? *pInt = iArray; ? //数组(名)转换为指针类型,然后初始化指针变量pInt
  这种转换基于下面的理念: 数组名一个数组的首地址,并且是个常量,不可改变,不可对数组名进行赋值。
?
  要点: ?
?
    1、sizeof(iArray) ; ?这个地方,不会将数组名转换为指针。
?
    2、定义引用的时候,不会将数组名转换为指针
?
Exp:
?
复制代码
int main()
{
? ? int iArray[5] = {1,2,3,4,5
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++AMP介绍(一) 下一篇UVa 297 Quadtrees(四分树)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C++ Lambda表达式保 (2025-12-26 05:49:45)
·C++ Lambda表达式的 (2025-12-26 05:49:42)
·深入浅出 C++ Lambda (2025-12-26 05:49:40)
·C语言指针从入门到基 (2025-12-26 05:21:36)
·【C语言指针初阶】C (2025-12-26 05:21:33)