第2课 - 有符号数与无符号数
第2课 - 有符号数与无符号数
1. 有符号整型的符号位
有符号整型有正数和负数,那在内存中是如何区分它们的呢?最高位用来标识数据的正负。
- 最高位为1,表明这个数为负数
- 最高位为0,表明这个数为正数
【有符号数的符号位】
1 #include <stdio.h> 2 3 int main() 4 { 5 char c = -5; 6 short s = 6; 7 int i = -7; 8 9 // 与最高位进行&运算,结果为0表示正数,结果为1表示负数 10 printf("%d\n", ((c & 0x80) != 0 )); // 1 ==> 负数 11 printf("%d\n", ((s & 0x8000) != 0)); // 0 ==> 正数 12 printf("%d\n", ((c & 0x80000000) != 0)); // 1 ==> 负数 13 14 return 0; 15 }
2. 有符号整型的表示法
在计算机内部用补码表示有符号整型
- 正数的补码为正数本身
- 负数的补码为负值的绝对值各位取反后加1
举例:
char型整数 5 的补码:0000 0101
char型整数 -7 的补码:0000 0111 ==> 1111 1000 ==> 1111 1001
short型整数 20 的补码:0000 0000 0001 0100
short型整数 -13 的补码:0000 0000 0000 1101 ==> 1111 1111 1111 0010 ==> 1111 1111 1111 0011
3. 无符号整型的表示法
(1)在计算机内部用原码表示无符号数
-
- 无符号数默认为正数
- 无符号数没有符号位
(2)对于固定长度的无符号数
-
- MAX_VALUE + 1 ==> MIN_VALUE
- MIN_VALUE - 1 ==> MAX_VALUE
(3)signed和unsigned
-
- C语言中整型变量默认为有符号的类型
- 用unsigned关键字声明整型变量为无符号类型
1 int i; // 默认为有符号整数 2 3 signed int j; // 显式声明变量为有符号整数 4 5 unsigned int k ; // 声明为无符号整数
下面看两个笔试中容易考察到的题目:
(1)当有符号数遇到无符号数时,有符号数在内存中的值会被看作无符号数
1 #include<stdio.h> 2 3 int main() 4 { 5 unsigned int i = 5; 6 int j = -10; 7 8 // 有符号数遇到无符号数,会被看作无符号数 9 // -10 在内存中表示为 0000 0000 0000 0000 0000 0000 0000 1010 ==> 10 // 1111 1111 1111 1111 1111 1111 1111 0101 ==> 11 // 1111 1111 1111 1111 1111 1111 1111 0110 ==> 这个看作无符号数是一个非常大的数 12 if ((i + j) > 0) 13 { 14 printf("i+j >= 0\n"); // 程序走到这个分支 15 } 16 else 17 { 18 printf("i+j <= 0\n"); 19 } 20 21 return 0; 22 }
(2)错误的使用了unsigned,unsigned修饰的无符号数不会是一个负数
1 #include <stdio.h> 2 3 int main() 4 { 5 unsigned int i = 0; 6 7 // 当i = 0时,i--变为最大值 8 // 前面讲过 MIN_VALUE - 1 ==> MAX_VALUE 9 for (i = 9; i >= 0; i--) // i >= 0一直成立 10 { 11 printf("i = %u\n", i); 12 } 13 14 return 0; 15 }