C——整型提升

一、定义

  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) 类型为charshort或整型位域(带符号或无符号的)的变量,以及枚举类型的对象,都可以放置在表达式中能够使用整型变量的位置。

  2) 如果1)中的变量的类型值能够用int表示,那么原值被转换为int;否则的话,转为unsigned int

二、实例

  1)char整形提升 

#include <stdio.h>  
#include <conio.h>
  
int main(int argc, char *argv[])
{
    unsigned char a = 0xA5;  
    unsigned char b = ~a>>4+1;  
      
    printf("b=%d
",b);  
      
    getch();      
    return 0;  
}

  首先a的二进制表示是:10100101

  然后看表达式~a>>4+1,加法运算优先级比较高,等同于~a>>5,a整形提升为32位:0000 0000 0000 0000 0000 0000 1010 0101

  a按位取反为:1111 1111 1111 1111 1111 1111 0101 1010,右移(算数右移)5位:1111 1111 1111 1111 1111 1111 1111 1010

  赋值给unsig char类型的b:1111 1010 = 250

  2)unsigned int、signed int整型提升

/*整形提升*/
#include <stdio.h>
#include <conio.h>
int array[] = {23, 34, 12, 17, 20, 99, 16};
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int main(int argc, char* argv[])
{
    int d = -1, x;
    int size_of_array = sizeof(array);
    int size_of_int = sizeof(array[0]);

    if(d <= sizeof(array) / sizeof(array[0]) - 2)
    {
        x = array[d+1];
        printf("x = %d
", x);
    }
    getch();
    return 0;
}

  ①首先sizeof()运算符返回的是unsigned int类型的值

  ②所以if里的条件表达式就是两个unsigned int和signed int的比较

  ③根据整型提升规则会发生整型提升,而signed int不足以表达unsigned int的值,所以int类型的值-1会装换为unsigned int

  ④这个signed int的-1转化为unsigned int:

  signed int -1:1111 1111 1111 1111 1111 1111 1111 1111

  转换为unsigned int就是unsigned int所能表示的最大值,所以if里的 条件表达式返回的是0,x不会被赋值,输出语句不会执行.

  3)算数运算类型转换和整形提升:

#include <stdio.h>  
#include <conio.h>

int main(int argc, char *argv[])  
{ 
    unsigned char a,b;  
    unsigned char c;  
      
    a = 0xFF;  
    b = 0x01;  
  
    c = a + b;  
      
    printf("output a+b = %d
",(a+b));  
    printf("sizeof(a+b): %d
", sizeof(a+b));
    printf("output c = %d
",c);  
    printf("sizeof(c): %d
", sizeof(c));
    
    getch();     
    return 0;  
}

  unsigned char a:1111 1111

  unsigned char b:0000 0001

  a + b = 1 0000 0000

  在第一个输出语句中,a+b发生整形提升,a、b均提升为32位,不会发生溢出,输出a + b的值是255 + 1 = 256

  而将1 0000 0000赋值给只有8位的unsigned char c,c为 0000 0000,即0.

三、一个无限循环的例子

#include <stdio.h>
#include <conio.h>

int main(int argc, char* argv[])
{
    unsigned length = 0;
    int i = 0;
    for(; i < length - 1; i++)
    {
        printf("in for
");
    }
    getch();
    return 0;
}

length是unsigned int,所以length - 1的值为2^32-1即为unsigned int的最大值,int类型的i与unsigned int比较时整型提升,但其永远是小于等于2^32-1的。所以造成无限循环

原文地址:https://www.cnblogs.com/crazyrunning/p/3480130.html