short、int、long 占用的字节数不同,所能表示的数值范围也不同。
以32位平台为例,下面是它们的取值范围:
数据类型 所占字节数 取值范围
short 2 -32768~32767,即 -215~(215-1)
unsigned short 2 0~65535,即 0~(216-1)
int 4 -2147483648~2147483647,即 -231~(231-1)
unsigned int 4 0~4294967295,即0~(232-1)
long 4 -2147483648~2147483647,即 -231~(231-1)
unsigned long 4 0~4294967295,即0~(232-1)
在C语言中, signed char 类型的范围为-128~127,而不是-127~127
-128的原码:1 1000 0000 ,9位,最高位符号位,
再算它的反码:1 0111 1111,进而,补码为: 1 1000 0000,这是-128的补码
-128的原码和-0(1000 000)的原码是不同的,但是在char 型中,
是可以用1000 000 表示-128的,关键在于char 是8位,
它把-128的最高位符号位1 丢弃了,截断后-128的原码为1000 000 和-0的原码相同,也就是说
1000 0000 和-128丢弃最高位后余下的8位相同,所以才可以用-0 表示-128,
这样,当初剩余的-0(1000 0000),被拿来表示截断后的-128,
因为即使截断后的-128和char 型范围的其他数(-127~127)运算也不会影响结果,
所以才敢这么表示-128。
#include<stdio.h>
void test()
{
char c1 = 128;
unsigned char c2 = 257;
//short s1 = 65535;
short s1 = 32768;
unsigned s2 = 65537;
printf("%d,%d,%d,%d \n",c1,c2,s1,s2);
printf("%08x,%08x,%08x,%08x \n",c1,c2,s1,s2);
char c3 = -128-1;
printf("%08d,%08x \n",c3,c3);
unsigned char a = -1;
printf("%08d,%08x \n",a,a);
}
//-128,1,-32768,65537
//ffffff80,00000001,ffff8000,00010001
//00000127,0000007f
//00000255,000000ff
void test2()
{
int i = 2147483647,j = -2147483648;
unsigned int k = 4294967295, l = 0;
printf("%d %d %d %d \n",i,i+1,j,j-1);
printf("%u %u %u %u %u\n",k,k+1,k+2,l,l-1);
}
//2147483647 -2147483648 -2147483648 2147483647
//4294967295 0 1 0 4294967295
void test1()
{
unsigned int un = 3000000000;
short end = 200;
long big = 65537;
printf("un =%u and not %d\n",un,un);
printf("end = %hd and %d\n",end,end);
printf("big = %ld and not %hd\n",big,big);
}
//un =3000000000 and not -1294967296
//end = 200 and 200
//big = 65537 and not 1
int main()
{
test();
return 0;
}
结论
以32位平台为例,下面是它们的取值范围:
数据类型 所占字节数 取值范围
short 2 -32768~32767,即 -215~(215-1)
unsigned short 2 0~65535,即 0~(216-1)
int 4 -2147483648~2147483647,即 -231~(231-1)
unsigned int 4 0~4294967295,即0~(232-1)
long 4 -2147483648~2147483647,即 -231~(231-1)
unsigned long 4 0~4294967295,即0~(232-1)
在C语言中, signed char 类型的范围为-128~127,而不是-127~127
-128的原码:1 1000 0000 ,9位,最高位符号位,
再算它的反码:1 0111 1111,进而,补码为: 1 1000 0000,这是-128的补码
-128的原码和-0(1000 000)的原码是不同的,但是在char 型中,
是可以用1000 000 表示-128的,关键在于char 是8位,
它把-128的最高位符号位1 丢弃了,截断后-128的原码为1000 000 和-0的原码相同,也就是说
1000 0000 和-128丢弃最高位后余下的8位相同,所以才可以用-0 表示-128,
这样,当初剩余的-0(1000 0000),被拿来表示截断后的-128,
因为即使截断后的-128和char 型范围的其他数(-127~127)运算也不会影响结果,
所以才敢这么表示-128。
#include<stdio.h>
void test()
{
char c1 = 128;
unsigned char c2 = 257;
//short s1 = 65535;
short s1 = 32768;
unsigned s2 = 65537;
printf("%d,%d,%d,%d \n",c1,c2,s1,s2);
printf("%08x,%08x,%08x,%08x \n",c1,c2,s1,s2);
char c3 = -128-1;
printf("%08d,%08x \n",c3,c3);
unsigned char a = -1;
printf("%08d,%08x \n",a,a);
}
//-128,1,-32768,65537
//ffffff80,00000001,ffff8000,00010001
//00000127,0000007f
//00000255,000000ff
void test2()
{
int i = 2147483647,j = -2147483648;
unsigned int k = 4294967295, l = 0;
printf("%d %d %d %d \n",i,i+1,j,j-1);
printf("%u %u %u %u %u\n",k,k+1,k+2,l,l-1);
}
//2147483647 -2147483648 -2147483648 2147483647
//4294967295 0 1 0 4294967295
void test1()
{
unsigned int un = 3000000000;
short end = 200;
long big = 65537;
printf("un =%u and not %d\n",un,un);
printf("end = %hd and %d\n",end,end);
printf("big = %ld and not %hd\n",big,big);
}
//un =3000000000 and not -1294967296
//end = 200 and 200
//big = 65537 and not 1
int main()
{
test();
return 0;
}
结论
注意高位截断