这个循环会一直继续下去:为什么使用char循环,因为它的索引循环是无限的?
char a = 100;
for(a=100; a>=0;--a)
System.out.println(a);
它是否会发生,因为一个被推举为算术运算int值和被扩大至从16位字符值32位,因此将始终保持积极的态度?
这个循环会一直继续下去:为什么使用char循环,因为它的索引循环是无限的?
char a = 100;
for(a=100; a>=0;--a)
System.out.println(a);
它是否会发生,因为一个被推举为算术运算int值和被扩大至从16位字符值32位,因此将始终保持积极的态度?
它确实会无限循环 - 你说的原因很接近。发生这种情况是因为a
不能代表没有的任何数字满足a >= 0
- char
是无符号的。算术下溢在Java中是明确定义的,并且是不明确的。请参阅规范的以下相关部分。
的整数运算符不表明以任何方式溢或下溢。
这意味着除了比较值之外没有上溢/下溢的指示。如果a
< = --a
,则意味着发生了下溢。
减法之前,二进制数值提升是在值1和变量的值进行(§5.6.2)。如有必要,差异会通过缩小原始转换(§5.1.3)和/或受到装箱转换(§5.1.7)的限制变为存储前的变量类型。前缀递减表达式的值是之后变量的值,该值存储在新值中。
因此,我们可以看到在这里有两个主要步骤:二进制数字提升,然后是缩小的优先转换。
加宽原语转换(§5.1.2)被施加到转换的任一个或由下面的规则中指定的两个操作数:
- 如果操作数是
double
类型,另一个转换为double
。- 否则,如果任一操作数的类型为
float
,则另一个操作数转换为float
。- 否则,如果任一操作数的类型为
long
,则另一个操作数转换为long
。- 否则,两个操作数都转换为
int
类型。
我们可以看到,减量表达可与a
为int
处理,由此进行扩大转换。这允许它代表值-1。
甲基本收缩转换可能会失去约数值的总幅度的信息,并且还可能会丢失精度和范围。
...
带符号的整数的收缩转换为整数类型T简单地丢弃所有,但Ñ最低阶位,其中Ñ是用于表示类型T.比特数除了可能丢失有关数值大小的信息之外,这可能会导致结果值的符号与输入值的符号不同。
仅保留Ñ最低阶位意味着只有int
表达a - 1
的最低16位被保留。由于-1是0b11111111 11111111 11111111 11111111此处仅保存下一个0b11111111 11111111。由于char
是无符号的,因此的所有都贡献了结果,给出。
在这里注意什么?实质上,这意味着Java整数运算是模块化;在这种情况下,模数是2^16或,因为char
是16位数据类型。 -1(mod 65536)≡65535,所以减量将回绕。
没有。 char
值是无符号的 - 当它们低于0时,它们返回到65535.
交换char
与byte
- 然后它会工作。
Ermmm ...你的意思是65535. –
Stephen,你是对的。我假设它像C的字符。 –
@NickODell那么你应该知道* plain *'char'的签名是实现定义的......它只能保证能够适合整个ASCII字符集(0-127),并且C99确保它可以存储在至少8位。 – oldrinb
正如其他人所说,Java中的char
类型是无符号的,因此a >= 0
将始终为真。当a
命中0,然后递减一次,就变成65535如果你只是想乖张,你可以写你的循环后,101次迭代终止这样:然后
char a = 100;
for(a=100; a<=100;--a)
System.out.println(a);
代码审阅者可以有一个字段因为写这样一件可怕的事情而把你分开。 :)
你试过吗? – oldrinb
@oldrinb - 只回答“将它”。更有趣的问题是“为什么”。 –
@StephenC我的评论回答了标题中的问题。 “为什么”我在下面回答。 – oldrinb