【发布时间】:2014-02-10 02:10:05
【问题描述】:
假设我有一个 char 指针:
char * cp;
int val2 = 2;
cp = &val2;
*cp = 1234;
由于值 1234 太大而无法放入 1 个字节,会发生什么情况?它会溢出并导致存储不正确的值,还是会以某种方式跨多个字节存储正确的值?
【问题讨论】:
标签: c char integer-overflow
假设我有一个 char 指针:
char * cp;
int val2 = 2;
cp = &val2;
*cp = 1234;
由于值 1234 太大而无法放入 1 个字节,会发生什么情况?它会溢出并导致存储不正确的值,还是会以某种方式跨多个字节存储正确的值?
【问题讨论】:
标签: c char integer-overflow
在*cp = 1234; 中,*cp 仅指一个字节,即val2 的第一个(最低寻址)字节。
在赋值中,右边的值被转换为左边的类型。因此,1234 将被转换为char。
这里有两个并发症。第一,在大多数 C 实现中,1234 太大而无法放入char。 (C 标准允许char 大于八位,但这在现代计算机中很少见。)二,char 可以有符号或无符号。
如果char 是无符号的,则转换是明确定义的:1234 比char 的最大值多一个模减少(通常为255,因此减少是模256)。通常情况下,1234 会减少到 210,这将存储在 *cp 引用的字节中。
如果 char 已签名且 1234 不适合 char,则转换是实现定义的或引发实现定义的信号。在许多现代 C 实现中,转换的结果将是 -46。
cp 在cp = &val2; 之后指向的字节是val2 的最低寻址字节。它不一定是val2 的最低有效字节。一些 C 实现在内存中存储具有最低有效字节的整数(little endian),而一些 C 实现在内存中存储具有最低有效字节的整数(big endian) . (甚至有些系统不按顺序存储字节;它们可能在内存中混在一起。)
大多数现代 C 实现以二进制补码形式存储整数而没有填充,因此,一旦您知道 C 实现是大端还是小端,您就会知道更改一个字节将如何影响 int 的值.但是,C 标准仍然允许符号和大小或二进制补码。它还允许在有符号整数中填充位。
最后,请注意char 是一种特殊类型,它允许以这种方式访问其他对象的一部分。例如,如果您使用short 而不是char,如short *sp = &val2; *sp = 0;,则违反了别名规则,并且行为未定义。
【讨论】: