假设我有一个字符指针:
char * cp;
int val2 = 2;
cp = &val2;
*cp = 1234;
由于值1234太大而无法容纳1个字节会发生什么?它会溢出并导致存储不正确的值,还是会以某种方式将正确的值存储在几个字节中?
答案 0 :(得分:9)
在*cp = 1234;
中,*cp
仅指一个字节,即val2
的第一个(寻址最低的)字节。
在赋值中,右侧的值将转换为左侧的类型。因此,1234将转换为char
。
这里有两个复杂情况。其中一个,在大多数C实现中,1234太大而不适合char
。 (C标准允许char
大于8位,但这在现代计算机中很少见。)两个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实现是big-endian还是little-endian,你就会知道改变一个字节会如何影响{{1 }}。但是,C标准仍然允许符号或数字补码。它还允许有符号整数中的填充位。
最后,请注意int
是一种特殊类型,它允许以这种方式访问其他对象的部分。例如,如果您使用char
而不是short
,就像在char
中一样,那将违反别名规则,并且行为将是未定义的。