一道关于signed和unsigned的微软面试题

来源:互联网 发布:教英语发音的软件 编辑:程序博客网 时间:2024/04/29 20:04

题目:

unsigned int i = 3;cout << i * -1;

问输出结果是多少?

我觉得大部分人的第一反应是-3。但是结果却不是这样的,写了个程序,运行了一下,输出结果是:4294967293。很诡异的一个数字,为什么会是这么个奇怪的数字呢?当你发现这数的十六进制数是FFFFFFFD时,你就离答案很近了...

 这个涉及到了混合着不同数据类型的表达式中的数据类型的转换问题。在总结转换问题之前,先说明一下各种数据类型(只说明numeric类型的),下表来自MSDN:

Type Name

Bytes

Other Names

Range of Values

int

*

signed,
signed int

System dependent

unsigned int

*

unsigned

System dependent

__int8

1

char,
signed char

–128 to 127

__int16

2

short,
short int,
signed short int

–32,768 to 32,767

__int32

4

signed,
signed int

–2,147,483,648 to 2,147,483,647

__int64

8

none

–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

char

1

signed char

–128 to 127

unsigned char

1

none

0 to 255

short

2

short int,
signed short int

–32,768 to 32,767

unsigned short

2

unsigned short int

0 to 65,535

long

4

long int,
signed long int

–2,147,483,648 to 2,147,483,647

unsigned long

4

unsigned long int

0 to 4,294,967,295

enum

*

none

Same as int

float

4

none

3.4E +/- 38 (7 digits)

double

8

none

1.7E +/- 308 (15 digits)

long double

10

none

1.2E +/- 4932 (19 digits)


对上表补充说明一下:

1)在32位机上,int型和unsignedint型都是32位的(4个字节),一个机器字长。

2)enum会跟据最大值来决定类型,一般来说为int型,如果超出int型所能表示的范围,则用比int型大的最小类型来表示(unsigned int, long 或者unsigned long)

3)关于类型的大小。一般用所能表示的数据范围来比较类型的大小,如char型<unsigned char型<short型...在表达式中,一般都是由小的类型向大的类型转换(强制类型转换除外)。

 

下面结合自己查的资料,加上自己不断地举各种情况编程,总结一下关于类型转换(仅限于算术表达式中关于整数类型的转换)的一些问题(如有缺漏,欢迎补充,感激不尽)

1、所有比int型小的数据类型(包括char,signedchar,unsigned char,short,signed short,unsigned short)转换为int型。如果转换后的数据会超出int型所能表示的范围的话,则转换为unsigned int型;

2、bool型转化为int型时,false转化为0,true转换为1;反过来所有的整数类型转化为bool时,0转化为false,其它非零值都转为true;

3、如果表达式中混有unsignedshort和int型时,如果int型数据可以表示所有的unsigned short型的话,则将unsigned short类型的数据转换为int型,否则,unsigned short类型及int型都转换为unsigned int类型。举个例子,在32位机上,int是32位,范围–2,147,483,648 to 2,147,483,647,unsigned short是16位,范围0 to65,535,这样int型的足够表示unsigned short类型的数据,因此在混有这两者的运算中,unsigned short类型数据被转换为int型;

4、unsigned int 与long类型的转换规律同3,在32位机上,unsignedint是32位,范围0 to 4,294,967,295,long是32位,范围–2,147,483,648 to 2,147,483,647,可见long类型不够表示所有的unsignedint型,因此在混有unsigned int及long的表达式中,两者都被转换为unsigned long;

5、如果表达式中既有int 又有unsignedint,则所有的int数据都被转化为unsigned int类型。

经过这番总结,前面提出的问题的答案应该就很明显了。在表达式i*-1中,i是unsigned int型,-1是int型(常量整数的类型同enum),按第5条可以知道-1必须转换为unsigned int型,即0xffffffff,十进制的4294967295,然后再与i相乘,即4294967295*3,如果不考虑溢出的话,结果是12884901885,十六进制0x2FFFFFFFD,由于unsigned int只能表示32位,因此结果是0xfffffffd,即4294967293。