在定义整数变量的型态的时候可以加上 unsigned 或是 signed, 例如
unsigned char
unsigned short (int)
unsigned long (int)
unsigned int
----------
signed char
signed short (int)
signed long (int)
signed int
--------------
上面 signed 有加和没有加是一样的意义
加上 unsigned 以后,
1. 所需要的数据储存空间和没有加 unsigned 时是一样的
2. 在使用 printf() 打印时基本上你必须分清楚
unsigned 有影响到的是参数的传递, 使用 %d 或是
%u 基本上是看程序设计者自己的选择
int i=-1;
printf("%d %u/n", i, i);
会印出
-1 4294967295
unsigned int i=-1;
printf("%d %u/n", i, i);
也会印出
-1 4294967295
char i=-1;
printf("%d %u/n", i, i);
还是会印出
-1 4294967295
但是
unsigned char i=-1;
printf("%d %u/n", i, i);
则会印出
255 255
这不是 %d 和 %u 的问题, 而是
参数传递时数据转换的问题 (见下面第 3 项)
不一样的地方有下面几个
1. 数据的范围基本上加上 unsigned 以后会变成 2 倍
2. 程序里比较大小的时候
int i=1;
int j=-1;
if (i>j) printf("i>j/n");
else printf("i<=j/n");
你会发现结果是 i>j
unsigned int i=1;
int j=-1;
if (i>j) printf("i>j/n");
else printf("i<=j/n");
你会发现结果是 i<=j
也就是说 signed 和 unsigned 在比较的时候 compiler
会把 signed int 自动当成 unsigned int 来比较
2. 数据转换的时候 (或是函式呼叫的时候)
char i = -128;
int j = i;
变量 i 里面的数据只有 1 个字节, 要放进
变量 j 里面的时候需要做 sign extension
也就是多出来的 3 个字节 (24 个 bit) 都要
填入原来 i 的 sign bit (第 8 个 bit)
以上例来说 (用二进制表示)
i: 10000000
j: 11111111 11111111 11111111 10000000
unsigned char i = -128;
int j = i;
由 unsigned 转为 signed 时前面一率补 0
用二进制表示
i: 10000000
j: 00000000 00000000 00000000 10000000
char i = -128;
unsigned int j = i;
还是做 sign extension
用二进制表示
i: 10000000
j: 11111111 11111111 11111111 10000000
函式呼叫的时候会做型态的转变, 例如
void fun(int x)
{
...
}
呼叫时如果用
unsigned char i=-1;
fun(i);
就会自动做转换
小结:
以下均针对VC++6.0编译器
1、 char 和unsigned char (1字节)
char c = 0x90 (1001 0000)首位是1
c >>= 4
c = 0xF9
char c = 0x70 (0111 0000) 首位是0
c >>= 4
c = 0x07
char c = 0x90 (1001 0000)与首位无关
c <<= 4
c = 0x00
char c = 0x70 (0111 0000) 与首位无关
c <<= 4
c = 0x00
2、 int 和 unsigned int (4字节)
int I = 0xF0 00 11 11 (11110000 00000000 00010001 00010001)首位1
I >>= 4
I = 0xFF 00 01 11
int I = 0x00 00 11 11 (00000000 00000000 00010001 00010001)首位0
I >> 4
I = 0x00 00 01 11
unsigned int I = 0xF0 00 11 11 (11110000 00000000 00010001 00010001)与首位无关
I << 4
I = 0x00 01 11 10
unsigned int I = 0x00 00 11 11 (00000000 00000000 00010001 00010001)与首位无关
I << 4
I = 0x00 01 11 10
3、 char 转 int
char c = 0x90 (首位是1)
int I = 0
I = c
I = 0xFF FF FF 90
char c = 0x70 (首位是0)
int I = 0
I = c
I = 0x00 00 00 70
4、 char 转 unsigned int
char c = 0x90 (首位是1)
unsigned int I = 0
I = c
I = 0xFF FF FF 90
char c = 0x70 (首位是0)
unsigned int I = 0
I = c
I = 0x00 00 00 70
5、 unsigned char 转 int
unsigned char c = 0x90 (与首位无关)
int I = 0
I = c
I = 0x00 00 00 90
unsigned char c = 0x70 (与首位无关)
int I = 0
I = c
I = 0x00 00 00 70
6、 unsigned char 转 unsigned int
unsigned char c = 0x90 (与首位无关)
int I = 0
I = c
I = 0x00 00 00 90
unsigned char c = 0x70 (与首位无关)
int I = 0
I = c
I = 0x00 00 00 70
总结:unsigned(无符号)不管左移,还是右移,均补0;signed(有符号)左移补0,右移补(如果首位是1,补1;首位是0,补0)。