官术网_书友最值得收藏!

建議4-1:整數(shù)轉(zhuǎn)換為新類型時必須做范圍檢查

關(guān)于整數(shù)類型數(shù)據(jù)的轉(zhuǎn)換原則,在C99的6.3.1.3節(jié)中做了非常重要的闡述,其表達的主要意思如下:

當我們將一個整數(shù)類型的數(shù)據(jù)轉(zhuǎn)換成除_Bool類型之外的另一個整數(shù)類型時,如果這個值可以被新的整數(shù)類型所表示,那么它就不會被修改,可以正確轉(zhuǎn)換;如果所轉(zhuǎn)換的新類型是無符號的,那么這個值就會反復(fù)加上或減去這個新類型可以表示的最大值加1,直到這個值位于這種新類型的范圍之內(nèi);如果所轉(zhuǎn)換的新類型是有符號的,并且這個值無法用新類型表示,那么它的結(jié)果是由編譯器定義的。

因此,為了保證整型數(shù)據(jù)轉(zhuǎn)換時不會發(fā)生丟失或錯誤解釋數(shù)據(jù)的情況,我們必須做一定的范圍檢查,以保證要轉(zhuǎn)換的數(shù)據(jù)的值在新類型的取值范圍之內(nèi)。而在頭文件limits.h中就定義了相關(guān)整型數(shù)據(jù)的取值范圍,例如,在VC++2010中定義的limits.h部分代碼如下所示:


#define CHAR_BIT      8                 /* number of bits in a char */
#define SCHAR_MIN   (-128)              /* minimum signed char value */
#define SCHAR_MAX     127              /* maximum signed char value */
#define UCHAR_MAX     0xff             /* maximum unsigned char value */
#ifndef _CHAR_UNSIGNED
#define CHAR_MIN    SCHAR_MIN            /* mimimum char value */
#define CHAR_MAX    SCHAR_MAX            /* maximum char value */
#else
#define CHAR_MIN      0
#define CHAR_MAX    UCHAR_MAX
#endif  /* _CHAR_UNSIGNED */
#define MB_LEN_MAX   5                   /* max. # bytes in multibyte char */
#define SHRT_MIN    (-32768)            /* minimum (signed) short value */
#define SHRT_MAX      32767            /* maximum (signed) short value */
#define USHRT_MAX     0xffff            /* maximum unsigned short value */
#define INT_MIN (-2147483647 - 1)      /* minimum (signed) int value */
#define INT_MAX     2147483647            /* maximum (signed) int value */
#define UINT_MAX    0xffffffff            /* maximum unsigned int value */
#define LONG_MIN (-2147483647L - 1)      /*minimum(signed) long value */
#define LONG_MAX    2147483647L            /* maximum (signed) long value */
#define ULONG_MAX   0xffffffffUL            /* maximum unsigned long value */
#define LLONG_MAX   9223372036854775807i64      /* maximum signed
                                                  long long int value */
#define LLONG_MIN  (-9223372036854775807i64 - 1) /* minimum
                                                     signed long long int value */
#define ULLONG_MAX  0xffffffffffffffffui64      /* maximum unsigned
                                                  long long int value */
#define _I8_MIN    (-127i8 - 1)            /* minimum signed 8 bit value */
#define _I8_MAX    127i8                 /* maximum signed 8 bit value */
#define _UI8_MAX   0xffui8                /* maximum unsigned 8 bit value */
#define _I16_MIN  (-32767i16 - 1)      /* minimum signed 16 bit value */
#define _I16_MAX   32767i16             /* maximum signed 16 bit value */
#define _UI16_MAX  0xffffui16             /* maximum unsigned 16 bit value */
#define _I32_MIN  (-2147483647i32 - 1)      /* minimum signed 32
                                           bit value */
#define _I32_MAX   2147483647i32            /* maximum signed 32 bit value */
#define _UI32_MAX  0xffffffffui32      /*maximum unsigned 32 bit value*/
/* minimum signed 64 bit value */
#define _I64_MIN    (-9223372036854775807i64 - 1)
/* maximum signed 64 bit value */
#define _I64_MAX      9223372036854775807i64
/* maximum unsigned 64 bit value */
#define _UI64_MAX     0xffffffffffffffffui64
#if     _INTEGRAL_MAX_BITS >= 128
/* minimum signed 128 bit value */
#define _I128_MIN(-170141183460469231731687303715884105727i128 - 1)
/* maximum signed 128 bit value */
#define _I128_MAX
170141183460469231731687303715884105727i128
/* maximum unsigned 128 bit value */
#define _UI128_MAX    0xffffffffffffffffffffffffffffffffui128
#endif

舉個例子,從一種無符號類型轉(zhuǎn)換為一種有符號類型時,就可能發(fā)生數(shù)據(jù)的高位被截斷而導(dǎo)致數(shù)據(jù)丟失,或者符號位丟失,所以在轉(zhuǎn)換之前要對取值范圍進行驗證。下面的示例代碼演示了如何從unsigned int類型轉(zhuǎn)換為signed char類型:


unsigned int ui1=12345;
signed char sc1;
if(ui1>SCHAR_MAX)
{
}
else
{
    sc1=(signed)ui1;
}

同樣,如果將有符號類型轉(zhuǎn)換為無符號類型,也必須進行取值范圍的驗證,示例代碼如下所示:


signed int si1=-12345;
unsigned int ui1= 0;
if(si1<0||si1>UINT_MAX)
{
}
else
{
    ui1=(unsigned int)si1;
}

在數(shù)據(jù)類型由“高級向低級”轉(zhuǎn)換的時候,同樣必須進行取值范圍驗證,示例代碼如下所示:


long long int lli1=LLONG_MAX;
int i1= 0;
if(lli1<INT_MIN||lli1>INT_MAX)
{
}
else
{
    i1=(int)lli1;
}

主站蜘蛛池模板: 习水县| 长丰县| 青海省| 霞浦县| 唐海县| 博罗县| 雅安市| 泽普县| 海丰县| 呼伦贝尔市| 交城县| 龙南县| 乌兰县| 黄梅县| 孙吴县| 阿城市| 大石桥市| 青冈县| 海门市| 分宜县| 沙洋县| 隆子县| 合作市| 襄汾县| 延川县| 年辖:市辖区| 琼中| 繁峙县| 红河县| 肃北| 忻城县| 平舆县| 申扎县| 江达县| 同江市| 万盛区| 玛纳斯县| 米易县| 博客| 西华县| 思茅市|