risc-v中文社区

 找回密码
 立即注册
查看: 1241|回复: 3

[原创] java for risc-v系列知识讲座(4)---number和char的关系及char的en...

  [复制链接]

20

主题

23

帖子

96

积分

注册会员

Rank: 2

积分
96
发表于 2021-7-29 13:50:11 | 显示全部楼层 |阅读模式
本帖最后由 szy 于 2021-7-29 16:59 编辑

public class NumChar {
    public static void main(String[] args)
    {
        char a= 'a';//java中char在内存用二个字节表示吗?
        int num = 97;

        System.out.println("char a =" + a);
        System.out.println("int num="+num);
        int n = a;
        System.out.println("int n = "+ n);
        char b = (char)num;
        System.out.println("char b =" + b);
    }
}
实验结果:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

20

主题

23

帖子

96

积分

注册会员

Rank: 2

积分
96
 楼主| 发表于 2021-7-29 15:22:28 | 显示全部楼层
中文字符实验:
        char c = '中';
        System.out.println("c = " + c);
        int nc = c;
        System.out.println("nc = " + nc + " 0x" + Integer.toHexString(nc));
        char cc = (char)(nc+1);
        System.out.println("cc = " + cc + " 0x" + Integer.toHexString(nc+1));
        char d = '丮';
        int nd = d;
        System.out.println("d = " + d + " ox" + Integer.toHexString(nd));
打印结果如下:
c = 中
nc = 20013 0x4e2d
cc = 丮 0x4e2e
d = 丮 ox4e2e
回复

使用道具 举报

20

主题

23

帖子

96

积分

注册会员

Rank: 2

积分
96
 楼主| 发表于 2021-7-29 15:31:59 | 显示全部楼层
帖子最开头提到:java的char在内存中是不是用二个字节表示的呢?按我的电脑环境来说,这需要理解utf8和utf16,先上二张图,一张是文件编码utf8,用winhex.exe打开显示出来的文件二进制内容,另一张是同样的文件内容只不过是utf16格式:




通过 https://www.haomeili.net/Code/DetailCodes 查看可以知道字符‘中’的Unicode(Big-Endian)编码(编号1201,代码页标识符utf-16BE)是0x4E2D
而字符'丮'的Unicode(Big-Endian)编码是0x4E2E,所以将int值nc加1之后打印出来的char也就是'中'的后一个字符'丮'。
通过上面的实验可以发现一个中文字符在我的电脑环境中是用二个字符来表示的,那有没有可能一个字符是三个字符或四个字节表示的呢?这需要理解编码格式,我上面的实验可以看到我的环境是unicode utf16BE,一个字符其实是用二个字节来保存的,也就是说最多能有65536个字符(当然,utf8和utf16保存的文件,最开始的几个字节用来区分格式:EF BB BF表示utf8,FE FF 表示utf16),具体见下面图中所示。从图中可以知道,如果用utf8表示,则内存中‘实’则需要三个字节,如果用utf16表示则只需要二个字节即可。在UTF8表示的时候是有规则的,它和UTF16的规则是不同的,UTF16上来就用二个字节表示,无需多话,粗暴;但UTF8因可能是一个字节也有可能是多个字节表示一个信息,所以:
0XXXXXXX:以0开头则表示这个字符肯定是跟acii完全一样
110XXXXX 10XXXXXX:这样的格式,表示要将二个字节当作一个单元信息
1110XXXX 10XXXXXX 10XXXXXX:这样的格式,表示要将三个字节当作一个单元信息
我们回来再看图中utf8,字符'实' E5 AE 9E用二进制表示则为:11100101 10101110 10011110,这个二进制格式刚好符合第三种格式情况。所以在实验代码中,我将0x5B9E转为char时就可以得到字符‘实’,补充代码如下:


int ne = 0x5B9E;
char ce = (char)ne;
System.out.println("cd = " + ce);
System.out.println(Charset.defaultCharset());

显示:
cd = 实
UTF-16



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-7-29 15:45:52 | 显示全部楼层
关于java的char深层次说明,这篇帖子加二张图,讲清楚了,不错。总结:java char不一定是二个字节,要看jvm的Charset是如何设置的,如果不是用到jni或JNA等C/C++级别,不是直接操作指针可能感觉不出来,只需要明白大概意思即可,如果用到JNI/JNA则需要明白细节。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-27 15:05 , Processed in 0.022061 second(s), 18 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表