文章时效性提示
本文发布于 471 天前,部分信息可能已经改变,请注意甄别。
《C程序设计语言》练习2-1
编写一个程序以确定分别由signed及unsigned限定的char、short、int及long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现。后一种方法的实现较困难一些,因为要确定各种浮点类型的取值范围。
思路:
- 先把数字0的二进制位进行按位取反,也就是都变成1。
- 再把这个二进制数的值转换为unsigned型,并右移一位来去掉符号位。
- 最后转换为有符号型。
相关: - 按位取反~
- 移位操作符
- 强制类型转换
- 原码、反码、补码以上面的char型为例,char型是由8位二进制数组成的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
//有符号型
printf("signed char min = %d\n",-(char)((unsigned char) ~0 >> 1)-1);
printf("signed char max = %d\n",(char)((unsigned char) ~0 >> 1));
printf("signed short min = %d\n",-(short)((unsigned short) ~0 >> 1)-1);
printf("signed short max = %d\n",(short)((unsigned short) ~0 >> 1));
printf("signed int min = %d\n",-(int)((unsigned int) ~0 >> 1)-1);
printf("signed int max = %d\n",(int)((unsigned int) ~0 >> 1));
printf("signed long min = %ld\n",-(long)((unsigned long) ~0 >> 1)-1);
printf("signed long max = %ld\n",(long)((unsigned long) ~0 >> 1));
//无符号型
printf("unsigned char max = %u\n",(unsigned char) ~0);
printf("unsigned short max = %u\n",(unsigned short) ~0);
printf("unsigned int max = %u\n",(unsigned int) ~0);
printf("unsigned long max = %lu\n",(unsigned long) ~0);
return 0;
}(char)((unsigned char) ~0 >> 1)~0把数字0进行按位取反,也就是把0000 0000变为1111 1111。
再把~0转换为无符号型:(unsigned char) ~0,这一步是为了下面的右移操作。
把这个无符号型的二进制数右移,去掉符号位。即0111 1111:(unsigned char) ~0 >> 1
最后,把unsigned char型转换为char型,也就是signed char型:(char)((unsigned char) ~0 >> 1)
对于char型的最小值,要在前面最大值的基础上取反再减1。
char、signed char和unsigned char的区别
在C标准中没有规定char是signed char还是unsigned char,主要取决于编译器。
但一般而言,未指定的数据类型均为signed,如int、char等价于signed int、signed char。
如果想要定义无符号类型,需要在前面加上unsigned。
为什么最小值要在最大值的基础上取反再减1?
以char型为例,就是一个占8位的二进制数,去掉符号位,数值位还有7位二进制数。
0-127的二进制表示是从00000000~01111111,全都是0开头的,0是代表正数的符号位,而-128~-1的补码表示为10000000-11111111,全是1开头的,所以1是代表负数的符号位。