複製鏈接
請複製以下鏈接發送給好友

類型提升

鎖定
類型提升有點類似於不同數據類型的轉換,當兩個數據之間類型不同時,若直接進行比較或賦值運算時會自動先將兩個不同類型的數據均轉化為其中的某種類型再進行操作,因此發生了類型提升。導致一些意外性讓人茫然的錯誤。
中文名
類型提升
外文名
Type Promotions
類似於
不同數據類型的轉換
出現於
程序的編譯期
導    致
一些意外性讓人茫然的錯誤

類型提升C語言中的整型提升規則

如果運算的操作數是同一類型則不進行類型提升,如果操作數之間的類型不一致且都為整型,當操作數都為無符號整型或者都為無符號整型時,較短的操作數將轉換為較長的操作數再進行運算(即sizeof的值較小的向sizeof較大的轉換),當操作數中即有有符號整型又有無符號整型時,若有符號整型的操作數的長度小於等於無符號整型的操作數那麼其將轉換為無符號整型的操作數,若有符號整型的操作數的長度大於無符號整型的操作數,那麼有符號整型轉換為無符號整型參與運算後的結果再轉換為有符號整型。 [1] 
#include <inttypes.h>  //這裏面定義了一些輸入輸出函數的格式字符串的宏用以保證程序在移植不需要做相應的修改需要至少支持C99的編譯器
#include <stdint.h>     //可移植類型,需要至少支持C99的編譯器
#include <stdio.h>
#include <stdlib.h>

//本例在某些編譯器的某些參數下某些樣例無法看出整型類型提升規則的表現

int main ( void )
{
    uint16_t unsigned_test = 0; 
    int16_t  signed_test = -1;
    int64_t test = 0;
    //測試同長signed轉換為unsigned
    unsigned_test = unsigned_test + signed_test; //這裏的signed_test被提升為unsigned類型
    printf( "%"PRIu16"\n" , unsigned_test );
    test = unsigned_test;
    printf( "%"PRId64"\n" , test );
    //測試同類型不提升
    printf( "int size = %zd int + int size = %zd\n" , sizeof( int ) , sizeof( 1 + 1 ) ); //%zd C99新增,用以輸出size_t類型
    //測試不同長,signed短類型提升為unsigned長類型
    printf( "unsigned long int size = %zd int + unsigned long int size = %zd\n" , sizeof(  unsigned long int  ) , sizeof( 1LU + 1 ) );
    //測試同長,短類型提升為長類型
    printf( "long long int size = %zd int + long long int size = %zd\n" , sizeof( long long int ) , sizeof( 1LL + 1 ) );
    return EXIT_SUCCESS;     //定義與stdlib.h的宏,用以表示返回成功
}

類型提升C語言中的浮點類型提升規則

當操作數中最長的一個類型為long double類型則,其他操作數類型提升至long double類型再進行運算,當最長類型為double則其他操作數提升至double類型,當最長類型為float則其他操作數提升至float類型,在這個過程中整型操作數全部轉換為對應操作數的浮點類型,浮點數進行運算時的結果可能會用範圍與精度更大的浮點類型表示。 [1] 
#include <inttypes.h>  //這裏面定義了一些輸入輸出函數的格式字符串的宏用以保證程序在移植不需要做相應的修改需要至少支持C99的編譯器
#include <stdint.h>     //可移植類型,需要至少支持C99的編譯器
#include <stdio.h>
#include <stdlib.h>

//本例在某些編譯器的某些參數下某些樣例無法看出上述浮點類型提升規則的表現

int main ( void )
{
    //測試浮點相加的規則,%zd C99新增,用以輸出size_t類型
    printf( "long double size = %zd , long double + float size = %zd\n" , sizeof( long double ) , sizeof( ( long double )1 + ( float )1 ) );
    printf( "long double size = %zd , long double + double size = %zd\n" , sizeof( long double ) , sizeof( ( long double )1 + ( double )1 ) );
    printf( "double size = %zd , double + float size = %zd\n" , sizeof( double ) , sizeof( ( double )1 + ( float )1 ) );
    //測試整型與浮點相加的類型提升
    printf( "float size = %zd , long long size = %zd , float + long long int size = %zd\n" , sizeof( float ) , sizeof( long long int ) , sizeof( ( float )1 + 1LL ) );
    return EXIT_SUCCESS; //定義與stdlib.h的宏,用以表示返回成功
}

參考資料