【问题标题】:Cyclic Nature of char datatype [duplicate]char数据类型的循环性质[重复]
【发布时间】:2014-08-17 08:04:12
【问题描述】:

我一直在学习 C,遇到了一个名为 C 中数据类型的循环性质的主题。

就像例子

char c=125;
c=c+10;
printf("%d",c);

输出为 -121。 给出的逻辑是

125+1= 126
125+2= 127
125+3=-128
125+4=-127
125+5=-126
125+6=-125
125+7=-124
125+8=-123
125+9=-122
125+10=-121

这是由于 char 数据类型的循环性质。 Y Char 是否表现出循环性质?怎么可能烧焦??

【问题讨论】:

  • 我不知道你提到的数据类型的循环性质。你描述的解释叫做溢出

标签: c


【解决方案1】:

在您的系统上,charsigned char。当有符号整数类型溢出时,结果未定义。它可能是循环的,也可能不是循环的。尽管在大多数执行 2 的补码算术的机器上,您可能会发现这是循环的。

【讨论】:

  • 我知道这是一个溢出,但该主题被解释为数据类型的循环性质
  • @shashank 那么你应该把你正在读的书扔掉或者烧掉。
  • @shashank 不要阅读教程
  • 谢谢你,我终于明白了不要盲目相信某事
  • + 的操作数被提升为int(所以加法不会溢出)。返回到char 的转换是实现定义的(或引发实现定义的信号),我猜大多数编译器都将它定义为gcc,转换如问题所示。跨度>
【解决方案2】:

根据您的实现,char 数据类型是 signed 类型。因此,它可以将值存储在范围内:-128 to 127。当你存储一个大于 127 的值时,你最终会得到一个可能是负数或正数的值,这取决于存储的值有多大以及你正在使用什么样的平台。 有符号整数溢出是 C 中的 undefined 行为,然后根本不保证无符号数字回绕。

【讨论】:

  • char 类型可以是有符号的或无符号的(取决于实现),并且有符号 char 的最小范围是-127 to 127,在大多数以 2s 补码系统工作的系统上是-128 to 127
  • @MohitJain char 数据类型是实现定义的,但根据 OP 的问题和代码输出,很明显它已在他的平台上签名。仍然更新了答案以反映这种结构。
  • (+1) 现在更清楚了。
【解决方案3】:

char 在这方面并不特别(除了它的实现定义的符号),所有到有符号类型的转换通常都表现出这种“循环性质”。但是,有符号溢出存在未定义和实现定义的方面,因此在执行此类操作时要小心。

这里发生了什么:

在表达式中

c=c+10

+ 的操作数受制于通常的算术转换。它们包括整数提升,如果它们类型的所有值都可以表示为int,则它将所有值转换为int。这意味着,+ (c) 的左操作数被转换为 intint 可以容纳每个 char1))。添加的结果类型为int。该赋值隐式将此值转换为char,它恰好是在您的平台上签名的。 (8 位)签名的char 不能保存值 135,因此它以实现定义的方式进行转换2)。对于gcc

为了转换为宽度 N 的类型,该值以 2N 为模减少到该类型的范围内;没有发出信号。

您的char 的宽度为 828256 135 ☰ -121 mod 256(参见例如2’s complement on Wikipedia)。

你没有说你使用哪个编译器,但是所有编译器的行为应该是相同的(实际上不再有任何非 2 的补码机器,并且有 2 的补码,这是我唯一合理的有符号转换定义能想到)。

请注意,这种实现定义的行为仅适用于转换,而不适用于任意表达式中的溢出,例如

int n = INT_MAX;
n += 1;

是未定义的行为,并被某些编译器用于优化(例如通过优化此类语句),因此绝对应避免此类事情。

第三种情况(此处无关,但为了完整起见)是无符号整数类型:不发生溢出(但也有例外,例如位移超过类型的宽度),结果总是减少对精度为 N 的类型取模 2N

相关:


1 至少对于 8 位 chars、签名 chars 或精度高于 charints,几乎总是如此。

2 C 标准说(C99 和 C11 (n1570) 6.3.1.3 p.3)“[...] 结果是实现定义的,或者引发了实现定义的信号。”在这种情况下,我不知道有任何实现会发出信号。但最好不要在不阅读编译器文档的情况下依赖该转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-16
    • 2018-12-17
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多