数据类型的最高位(二进制)用于标识数据的符号:
最高位为1,表明这个数为负数;
最高位为0,表明这个数为正数。
示例代码:
#include <stdio.h> int main() { int sign = 0; char a = -5; short b = 1; //两个字节 int c = -1; sign = ((a & 0x80) != 0); printf("%d\n", sign); sign = ((b & 0x8000)!= 0); printf("%d\n", sign) ; sign =((c & 0x80000000) != 0); printf("%d\n", sign); return 0; }
运行上面代码,通过与0x80、0x8000、0x80000000进行按位与操作,来判断a、b、c的二进制数最高位。
1 0 1
在计算机中,用补码来表示有符号数。
正数的补码为正数本身,负数的补码为负数的绝对值,然后各位取反后加1;
-7 ==》7 ==》 111 ==》 0000 0111 ==》 1111 1000 ==》 1111 1001;
在计算机内部用原码表示无符号数,无符号数默认为正数,且没有符号位;
对于固定长度的无符号数,最小值为0.
MAX_VALUE + 1 -> MIN_VALUE; MIN_VALUE - 1 -> MAX_VALUE;
最大值根据占用内存大小(数据类型)决定。
C语言中默认变量为有符号的类型,unsigned关键字声明变量为无符号类型。
int i; 有符号; signed int j ; 显式声明为有符号数; unsigne int l; 声明为无符号数
C语言中只有整数类型能够声明为unsigned类型。
当有符号数遇见无符号数:
阅读下面代码,判断输出是什么?
#include<stdio.h> int main() { unsigned int i = 5; int j = -10; //运行过程中自动转换为无符号数。 if( (i + j) > 0) { printf(" (i + j) > 0\n"); } else { printf(" (i + j ) < 0\n"); } return 0; }
在linux Gcc下编译后运行结果为:
delphi@delphi-vm:~/will$ ./a.out (i + j) > 0
原因在于,有符号数在和无符号数进行运算时,会自动转换为无符号数。
观察下面代码,判断输出:
int main() { unsigned int i = 0; for(i = 9; i>=0; i--) //注意此处i的范围 i>= 0 { printf("%u\n", i); } return 0; }
程序运行后进去死循环。
原因在于无符号数的特点:
MAX_VALUE + 1 -> MIN_VALUE; MIN_VALUE - 1 -> MAX_VALUE;划重点:当无符号数和有符号数进行混合运算时,会将有符号数转换为无符号数后再进行计算,结果为无符号数。