C-超过字符限制-标准规则

C-超过字符限制-标准规则,c,size,limit,standards,C,Size,Limit,Standards,此代码: signed char a = 128; a++; printf("%d", a); 打印'-127'的值。 我理解为什么,基本上,当值达到极限并从极限开始时,它会“重置”,但我很难确定这是标准中指定的,还是我的编译器执行的只是随机操作?有符号字符从-128到127 没有警告吗?=128 从-128+1=-127,就可以了 在从127+1到-128的运行时,编译器不应该在那里进行计算。假设最常见的平台具有8位char类型和2的补码(x86、ARM、MIPS、PPC、MSP430等),

此代码:

signed char a = 128;
a++;
printf("%d", a);
打印'-127'的值。
我理解为什么,基本上,当值达到极限并从极限开始时,它会“重置”,但我很难确定这是标准中指定的,还是我的编译器执行的只是随机操作?

有符号字符从-128到127

没有警告吗?=128

从-128+1=-127,就可以了


在从127+1到-128的运行时,编译器不应该在那里进行计算。

假设最常见的平台具有8位
char
类型和2的补码(x86、ARM、MIPS、PPC、MSP430等),则会发生以下情况:

  • 128
    对于
    签名字符来说太大了。它以实现定义的方式转换为
    有符号字符
    。通常它只是被截断和位复制(1:1)。在2的补码中,
    0b1000000
    是有符号字符中十进制-128的2的补码表示形式
  • 以下是基础数学:
    -128+1->-127
在其他平台上,结果各不相同,但最有可能的是,它们只使用
int
常量
128
的低位


要检测这些缺陷(但不是全部),请启用编译器警告并注意它们。gcc将报告初始化器的截断警告(
-Wconversion
)。

启用和不启用编译器警告
128
很可能已经是您平台上的
签名字符的无效值。@Olaf没有警告…请阅读我的答案,其中我删除的内容超过了注释的范围。你也应该仔细阅读我的评论。如果你没有得到默认的警告,请集中精力理解第一个单词的意思。现在你完全把我弄糊涂了。我不打算在真正的程序中使用它,而是想知道,因为它可能是我考试中的一个问题。我不需要“可能”的输出,我只需要知道它是由编译器的标准操作还是随机操作指定的。为了简单起见,我甚至在写这篇文章时假设char是1字节。@NerminaAvdić:
实现定义的
是标准的一个术语,请查阅!这意味着它是由实现定义的。这意味着您的实现必须定义如何处理此类情况。我提供了如何在常见实施/平台上处理此问题的信息;由于显而易见的原因,我无法涵盖所有内容。无论如何,很明显,这不是“编译器的随机操作”(如果软件中可能存在这种情况)。@NerminaAvdić:
char
类型始终是一个字节。这就是它的定义!然而,一个字节不能保证有8位!另外,负值的编码不能保证是2的补码。我的回答尽可能清楚。如果您所处的平台与所列平台不同,您应在问题中对此进行澄清,并提供最终答案所需的所有信息。否则,我给你足够的信息来找出你自己。因此,总之,(如果在一个32位的机器上运行1字节是8位)如果超过127的值被执行,符号char会认为它是第二个补充,并相应地打印出它的值。或者我还缺少一些其他的实现规则?@NerminaAvdić:我并没有说它适用于所有32位平台(而且要明确的是:32位平台并不自动意味着8位/字节;32位平台可能只有32位访问)。但最有可能的情况是(对于gcc,我肯定是在提到的平台上)。正如我所写的:您必须检查编译器的文档。它是“两个补语”(因此撇号),而不是“第二个补语”——查一查!认真对待这一点:启用所有相关警告