user-0 提问: 做《c和指针》课后练习时关于char型溢出的一个疑惑

回复:
user: user-1
content: 引用 15 楼 lin5161678 的回复:[quote=引用 14 楼 lm_whales 的回复:] 同一个地方还规定了  -32767是最小 int  是不是  -32768 不合法?[/quote] 他这个新的规定的思想是 正数 负数要对称，至于合不合理，个人认为，应该是各有道理  所谓最小实现，其实就是 char >= 8 Bits ,int >=16Bits，long >=32Bits这一类的  DSP上 char 是 16 Bits 那其实是  相应的 -32768 在这个时候，是个不合法的数 从前DOS下，TC int 是16 Bits 在这个标准下，-32768 就是不合法的 至于具体 -128 或者-32768 在某个系统下，合不合法，取决于 char,int 等整型的长度（Bits数） char 为8Bits 的时候，-128 是不合法的 int(short) 为16 Bits的时候， -32768 是不合法的 int(short) 型 并不是，每个系统都受制于最小范围， 无论如何实现 整型（有符号数） ， 而是总有一个数不合法，这个数就是 绝对值最大的负数  最小范围，刚好就把 最小长度中的这个 -32768，-128 等 放到 取值范围之外。

user: user-1
content: 引用 15 楼 lin5161678 的回复:[quote=引用 14 楼 lm_whales 的回复:] 同一个地方还规定了  -32767是最小 int  是不是  -32768 不合法?[/quote] 这么做还有一个很合理的原因 那就是 对负数取绝对值，在数学上，结果一定是正的 而 -32768 ，-128 等数，在该长度正数的取值范围，没法定义绝对值 如果定义为 32768 ，128 这个数二进制 和  -32768 ，-128  值相同，表示的却是负数。 这样 【-32767 ，32767】 就比 【-32768，32767】要严谨一点 同理 【-127，127】 这个范围 比【-128，127】 要严谨一点 当然，这样做，也有他的缺点，就是有一个编码没有用上（-32768 ，-128）

user: user-2
content: 引用 12 楼 lm_whales 的回复:问题是 一般实现，也都是 -127 ～127 而不是  -32767 ~ 32767那又如何? 反正 这也不能说明 -128 就是 非法啊

user: user-2
content: 引用 14 楼 lm_whales 的回复: 同一个地方还规定了  -32767是最小 int  是不是  -32768 不合法?

user: user-1
content: 引用 13 楼 lin5161678 的回复:[quote=引用 12 楼 lm_whales 的回复:] 问题是 一般实现，也都是 -127 ～127 而不是  -32767 ~ 32767那又如何? 反正 这也不能说明 -128 就是 非法啊 [/quote]不能如何，只是不被认可而已 连 标准库里面都改掉了， 你写 -128 在某些系统上可能会警告，或者直接报错，如此而已。

user: user-1
content: 引用 10 楼 lin5161678 的回复:[quote=引用 9 楼 lm_whales 的回复:] [quote=引用 6 楼 adlay 的回复:] [quote=引用 3 楼 lm_whales 的回复:] char型范围是-127到127 是这样的 -128  这个数值，已经溢出了  最高位同时表示 符号，和值 0x80 二进制为 1000 0000  本来应该是 128 但是 符号位是负值 实际应该表示为 1 1000 0000 ,不是8 位数数了 所以是 -128   早期char型范围，确实是 -128 ～127  如今已经改为 -127 ～127了   -128 应该表示为 -127 - 1 其实还是 0x80  如果真如你所的，0x80 表示 -127，那 0x81 怎么办？ 也表示 -127？ 两个不同的数变了成同一个数，那面对  char x = -127 的时候，内存里面该如何存储这个值才能符合写的人的预期？世界都乱套了。[/quote] -127 ~127 是表数范围 即 char 值只有 -127 ～127  -128  =0x80 是非法数值 不在  char  表示范围  char 的范围是  负数 [0x81 0xFF] ， 0，正数 [1~ 0x7F]   正好是 【-127 ～ -1】，0，【1，127】  所以正好是 【-127，127】  0x80 正好不在这个范围，所以是个非法数  [/quote]说错了 不是非法数 标准要求-127~127 说的是最小范围  只要比这个范围大 喜欢实现为 -32768 ~ 32767 也是完全没问题的 都是合法的[/quote] 问题是 一般实现，也都是 -127 ～127 而不是  -32767 ~ 32767

user: user-1
content: C新标准（其实不新，早就是老标准了） char 范围确实是 【-127，127】 但是 char（8Bits 整数） 也确实可以表示 0x80 char c =0x80; /* 也可以改为 char c =128; */ printf ("%d",c);不能说明问题，因为 char 参数在这里 按照 int 传递。这里有类型提升。 即便新标准，hhd 格式。 printf("%hhd",c);也不能说明什么问题。

user: user-2
content: 引用 9 楼 lm_whales 的回复:[quote=引用 6 楼 adlay 的回复:] [quote=引用 3 楼 lm_whales 的回复:] char型范围是-127到127 是这样的 -128  这个数值，已经溢出了  最高位同时表示 符号，和值 0x80 二进制为 1000 0000  本来应该是 128 但是 符号位是负值 实际应该表示为 1 1000 0000 ,不是8 位数数了 所以是 -128   早期char型范围，确实是 -128 ～127  如今已经改为 -127 ～127了   -128 应该表示为 -127 - 1 其实还是 0x80  如果真如你所的，0x80 表示 -127，那 0x81 怎么办？ 也表示 -127？ 两个不同的数变了成同一个数，那面对  char x = -127 的时候，内存里面该如何存储这个值才能符合写的人的预期？世界都乱套了。[/quote] -127 ~127 是表数范围 即 char 值只有 -127 ～127  -128  =0x80 是非法数值 不在  char  表示范围  char 的范围是  负数 [0x81 0xFF] ， 0，正数 [1~ 0x7F]   正好是 【-127 ～ -1】，0，【1，127】  所以正好是 【-127，127】  0x80 正好不在这个范围，所以是个非法数  [/quote]说错了 不是非法数 标准要求-127~127 说的是最小范围  只要比这个范围大 喜欢实现为 -32768 ~ 32767 也是完全没问题的 都是合法的

user: user-1
content: 引用 6 楼 adlay 的回复:[quote=引用 3 楼 lm_whales 的回复:] char型范围是-127到127 是这样的 -128  这个数值，已经溢出了  最高位同时表示 符号，和值 0x80 二进制为 1000 0000  本来应该是 128 但是 符号位是负值 实际应该表示为 1 1000 0000 ,不是8 位数数了 所以是 -128   早期char型范围，确实是 -128 ～127  如今已经改为 -127 ～127了   -128 应该表示为 -127 - 1 其实还是 0x80  如果真如你所的，0x80 表示 -127，那 0x81 怎么办？ 也表示 -127？ 两个不同的数变了成同一个数，那面对  char x = -127 的时候，内存里面该如何存储这个值才能符合写的人的预期？世界都乱套了。[/quote] -127 ~127 是表数范围 即 char 值只有 -127 ～127  -128  =0x80 是非法数值 不在  char  表示范围  char 的范围是  负数 [0x81 0xFF] ， 0，正数 [1~ 0x7F]   正好是 【-127 ～ -1】，0，【1，127】  所以正好是 【-127，127】  0x80 正好不在这个范围，所以是个非法数

user: user-0
content: 引用 4 楼 adlay 的回复:补码表示的数的绝对值是  取反 + 1,  10101100 按位取反后是 83，再加 1 就是 84 了。同理，0x80 表示的有符号数也是 -128. 这里确实忘记加1了，无语，这么弱智的错误居然也会犯。。

user: user-0
content: 引用 3 楼 lm_whales 的回复:char型范围是-127到127 是这样的 -128  这个数值，已经溢出了  最高位同时表示 符号，和值 0x80 二进制为 1000 0000  本来应该是 128 但是 符号位是负值 实际应该表示为 1 1000 0000 ,不是8 位数数了 所以是 -128   早期char型范围，确实是 -128 ～127  如今已经改为 -127 ～127了   -128 应该表示为 -127 - 1 其实还是 0x80   赞~\(≧▽≦)/~  解释的很清楚

user: user-3
content: 引用 3 楼 lm_whales 的回复:char型范围是-127到127 是这样的 -128  这个数值，已经溢出了  最高位同时表示 符号，和值 0x80 二进制为 1000 0000  本来应该是 128 但是 符号位是负值 实际应该表示为 1 1000 0000 ,不是8 位数数了 所以是 -128   早期char型范围，确实是 -128 ～127  如今已经改为 -127 ～127了   -128 应该表示为 -127 - 1 其实还是 0x80  如果真如你所的，0x80 表示 -127，那 0x81 怎么办？ 也表示 -127？ 两个不同的数变了成同一个数，那面对  char x = -127 的时候，内存里面该如何存储这个值才能符合写的人的预期？世界都乱套了。

user: user-3
content: 引用 3 楼 lm_whales 的回复:char型范围是-127到127 是这样的 -128  这个数值，已经溢出了  最高位同时表示 符号，和值 0x80 二进制为 1000 0000  本来应该是 128 但是 符号位是负值 实际应该表示为 1 1000 0000 ,不是8 位数数了 所以是 -128   早期char型范围，确实是 -128 ～127  如今已经改为 -127 ～127了   -128 应该表示为 -127 - 1 其实还是 0x80  这个很好验证   	char x = 0x80; 	printf("%d\n", x);   它就是 -128

user: user-3
content: 补码表示的数的绝对值是  取反 + 1,  10101100 按位取反后是 83，再加 1 就是 84 了。同理，0x80 表示的有符号数也是 -128.

user: user-1
content: char型范围是-127到127 是这样的 -128  这个数值，已经溢出了  最高位同时表示 符号，和值 0x80 二进制为 1000 0000  本来应该是 128 但是 符号位是负值 实际应该表示为 1 1000 0000 ,不是8 位数数了 所以是 -128   早期char型范围，确实是 -128 ～127  如今已经改为 -127 ～127了   -128 应该表示为 -127 - 1 其实还是 0x80

user: user-4
content: 新人看看 哈哈

user: user-5
content: checksum(检验和）用一个signed char变量进行计算，它初始为-1 -128~127