【问题标题】:Internal conversion of integer to char whose size is smaller将整数内部转换为大小更小的 char
【发布时间】:2018-06-13 05:28:50
【问题描述】:

在以下程序中,我将整数数据类型分配给 char 数据类型。

    public static void main(String args[]) {
        char ch =65;
        System.out.println(ch);
    }

我知道 int 占用 32 位而 char 占用 16 位的事实。有了这些知识,我希望编译器会抛出一些错误消息“尝试将较大大小的数据转换为较小大小”。

为什么编译器不抱怨并在内部将输出转换并打印为“A”(我理解它是 65 的 ASCII 等价物,我的问题仅与数据类型的大小有关)?

【问题讨论】:

  • 编译器会抱怨的 int 在哪里?它在编译时知道 65 将适合您的字符。
  • 问问自己 1000001 占用多少位?

标签: java c# .net types


【解决方案1】:

编译器实际上会验证范围。这是有效的,因为int 65 在预期范围内。

以下内容无法编译:

char c = (int)Character.MAX_VALUE + 1
char c = 65536

这会像你的任务一样:

char c = 65535 //Within range

但是,当值在编译时不是常量时,需要进行强制转换:

private static void charRange(int i) {
    char c = (char) i;
    System.out.println(" --> " + (int) c);
}

charRange(65);
charRange(Character.MAX_VALUE + 20);

并且检查没有发生(为溢出腾出空间)

--> 65
--> 19

【讨论】:

  • 类型转换后,如果我调用 charRange(65536); char c = (char) 我如何存储这个值?它会被转换为 char 范围内的数字,比如 65535?
  • @user1400915 它将溢出并环绕。查看第二个示例调用charRange(Character.MAX_VALUE + 20);,它导致了意外的值19。
  • 为什么值总是 19 ,它有特定的模式还是只是一个随机数?
  • @user1400915 这与其他数字类型溢出时的行为相同,尽管char 范围是0-65535。您可以在这篇文章中找到有关溢出/下溢的信息:stackoverflow.com/questions/3001836/…
【解决方案2】:

Java 将int 转换为char 的一般规则有一个例外。如果 int 是编译时常量表达式(例如文字)并且表达式的 int 值在所需范围内(0 到 65535),则将 int 表达式分配给 @ 是合法的987654327@.

直观地说,对于编译时常量表达式,编译器知道是否可以在不丢失信息的情况下分配表达式值。

这被JLS 5.2 ...在开头的段落中涵盖了“另外,如果表达式是一个常量表达式...”

【讨论】:

    【解决方案3】:

    Java 或 C# 等编程语言带有一组整数 primitive types。每种类型都有一个明确定义的范围,形式为 [min value, max value]。这些值存储在从最高有效位到最低位的固定位序列中。

    例如,让十进制数 123456 表示为下一个 32 位序列

    0000000000000011110001001000000

    当您尝试将 32 位数字类型转换为 16 位数字类型时,编译器会复制 16 个最低有效位(或最后 16 位),然后将 123456 数字包装到

    1110001001000000

    如果将此二进制数转换为十进制数,则为 57920。如您所知,32 位数字无法放入 16 位序列,并且原始序列被任意包装。这被称为integer overflow,当您将 2 个数字相加或相乘时也会发生这种情况,结果超出整数类型范围。

    作为程序员,您应该意识到溢出,并对此做出反应以避免程序失败。您还应该阅读有关signed integer representation 的更多详细信息。

    【讨论】:

      猜你喜欢
      • 2015-04-14
      • 2015-10-08
      • 2021-11-09
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-29
      相关资源
      最近更新 更多