C\C++中的整形提升

来源:互联网 发布:高端黑 知乎 编辑:程序博客网 时间:2024/04/20 03:56

1. 什么是整形提升?

首先我们来看看整形提升的概念:

  • From the text K&R, C Programming Language, 2nd Ed. p. 174
  • A.6.1 Integral Promotion
    A character, a short integer, or an integer bit-field, all either signed or not, or an object of enumeration type, may be used in an expression wherever an integer may be used. If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int. This process is called integral promotion.

所谓的整形提升的关键:
* 1.一个char类型、short类型、位域(不论是有符号还是无符号)或是一个枚举体,都可以在int或是unsinged int可以使用的表达式中使用。
* 2. 换句话就是上述的类型可以替换表达式中的int或是unsigned int

整形提升实例:

#include <iostream>enum colorA{redA,blueA,grayA,blackA};void go(unsigned int a){std::cout<<"called"<<std::endl;}int main(){    //枚举类型    colorA ca(redA);    go(ca);    //char 类型    char a('a');    go(a);    std::cin.get();    return 0;}

运行结果:

called
called


在算数运算中整形提升是什么情况?
答:算数中的整形提升有几个特点(这里不考虑浮点):当操作数类型不同时,会发生类型的自动转换,有时,即使在类型相同的情况下也会发生整形提升。

#include <iostream>int main() {    char a('a'), b('0'), c;    c = a + b;    std::cout << "a + b : " << sizeof(a + b) << std::endl;    std::cout << "c : " << sizeof(c) << std::endl;    std::cin.get();    return 0;}

运行结果:

a + b : 4
c : 1

从运行结果来看:

  • 当执行a+b的时候,char类型自动转换为4字节的整形
  • 当执行c=a+b 也就是,将(a+b)的结果赋给c的时候,又发生了从4字节整形到char类型的隐式转换(截断)。
  • 所以说,即使数据类型相同,也可能发生整形提升。

2. 整形提升的原理

当我们从1字节整形向4字节整形提升时,对位的填充可能发生两种情况:

  1. 如果是有符号数据类型:正数填充0,负数填充1
  2. 如果是无符号数据类型:填充0

总的来说,就是填充符号位


在演示之前需要明确:计算机中的数据是以 补码 的形式来存储的
参考这里:http://baike.baidu.com/view/377340.htm

例1: 1字节,有符号 -> 2字节,有符号

15 的二进制(补码)为 0000 1111
0000 1111 -> 0000 0000 0000 1111

例2: 1字节,有符号 -> 2字节,有符号

-15 的二进制(补码)为 1111 0001
0000 1111 -> 1111 1111 1111 0001

例3: 1字节,无符号 -> 2字节,无符号 (相当于正数的规则,看例1)

15 的二进制(补码)为 0000 1111
0000 1111 -> 0000 0000 0000 1111

3. 数据溢出

说到数据类型的提升,就少不了数据的溢出

看个例子:

#include <iostream>int main() {    unsigned char test(255 + 1);    std::cout << static_cast<int>(test) << std::endl;//转换成整形输出,避免以字符输出    std::cin.get();    return 0;}

运行结果:

0

我们来分析看看:

255 二进制:0000 0000 0000 0000 0000 0000 1111 1111
1二进制:0000 0000 0000 0000 0000 0000 0000 0001
256二进制:0000 0000 0000 0000 0000 0001 0000 0000
转换为unsigned char类型:从低位开始(从右边开始)截取8个bit:0000 0000

0 0