【问题标题】:What happens when a char is assigned a value too large to fit in a byte?当一个 char 被赋予一个太大而无法放入一个字节的值时会发生什么?
【发布时间】:2014-02-10 02:10:05
【问题描述】:

假设我有一个 char 指针:

    char * cp;
    int val2 = 2;
    cp = &val2;
    *cp = 1234;

由于值 1234 太大而无法放入 1 个字节,会发生什么情况?它会溢出并导致存储不正确的值,还是会以某种方式跨多个字节存储正确的值?

【问题讨论】:

    标签: c char integer-overflow


    【解决方案1】:

    *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。

    cpcp = &val2; 之后指向的字节是val2 的最低寻址字节。它不一定是val2 的最低有效字节。一些 C 实现在内存中存储具有最低有效字节的整数(little endian),而一些 C 实现在内存中存储具有最低有效字节的整数(big endian) . (甚至有些系统不按顺序存储字节;它们可能在内存中混在一起。)

    大多数现代 C 实现以二进制补码形式存储整数而没有填充,因此,一旦您知道 C 实现是大端还是小端,您就会知道更改一个字节将如何影响 int 的值.但是,C 标准仍然允许符号和大小或二进制补码。它还允许在有符号整数中填充位。

    最后,请注意char 是一种特殊类型,它允许以这种方式访问​​其他对象的一部分。例如,如果您使用short 而不是char,如short *sp = &val2; *sp = 0;,则违反了别名规则,并且行为未定义。

    【讨论】:

    • @user3284549 一个很好而完整的答案。一定要花时间去理解它。
    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 2017-03-24
    • 2023-03-25
    • 1970-01-01
    • 2013-10-05
    相关资源
    最近更新 更多