字符在内存中最终的表示形式是什么?是某种字符编码还是码位(Code Point)?

字符在内存中最终的表示形式是什么?是某种字符编码还是码位(Code Point)?

根据我的了解,编码中有三个核心概念:
1. 字符集(Character Set),可以说是一个抽象概念,字符的合集
2. 码位(Code Point),将抽象的字符集中每一个字符映射到一个整数
3. 字符编码(Encoding),按照某种编码规则用二进制来表示一个字符

我对码位这个概念理解的不是很清楚,Code point中说:

The notion of a code point is used for abstraction, to distinguish both:

  • the number from an encoding as a sequence of bits, and
  • the abstract character from a particular graphical representation (glyph).

This is because one may wish to make these distinctions:

  • encode a particular code space in different ways, or
  • display a character via different glyphs.

说Code Point是用于抽象,但Java中依然可以使用codePointAt方法来获取实际的整数值

    String str = "JAVA";
    System.out.println("String = " + str);

    // codepoint at index 1
    int retval = str.codePointAt(1);

    // prints character at index1 in string
    System.out.println("Character(unicode point) = " + retval);

用Java的String来举例子,引用自深入分析 Java 中的中文编码问题

String str = “I am 君山”;

String 内部的char 数组的值为 49 20 61 6d 20 541b 5c71

请问这char数组的值是码位吗,还是说是JVM使用的UTF16的编码?

字符在内存中最终的表示形式是什么?是不是和具体编程语言相关?

vczh专业造轮子 https://github.com/vczh-libraries

code point是protocol,encoding是内存格式。这就像Unicode与UTF-32的区别一样。

林威建敲代码的,java迷,在校生

  1. 在现代编码模型里要知道一个字符如何映射成计算机里比特,需要经过如下几个步骤。

    1. 知道一个系统需要支持哪些字符,这些字符的集合被称为字符表(Character repertoire)
    2. 给字符表里的抽象字符编上一个数字,也就是字符集合到一个整数集合的映射。这种映射称为编码字符集(CCS:Coded Character Set),unicode是属于这一层的概念,跟计算机里的什么进制啊没有任何关系,它是完全数学的抽象的。
    3. 将CCS里字符对应的整数转换成有限长度的比特值,便于以后计算机使用一定长度的二进制形式表示该整数。这个对应关系被称为字符编码表(CEF:Character Encoding Form)UTF-8, UTF-16都属于这层。
    4. 对于CEF得到的比特值具体如何在计算机中进行存储,传输。因为存在大端小端的问题,这就会跟具体的操作系统相关了。这种解决方案称为字符编码方案(CES:Character Encoding Scheme)。

    平常我们所说的编码都在第三步的时候完成了,都没有涉及到CES。

    以上摘自(http://blog.jobbole.com/39309/

    unicode只是一种抽象概念,使用一个数字来表示字符集中的一个字符,相当于规定了unicode字符集中那一百多万个字符和数字的映射,代码点就相当于这个字符对应着的数字了。Java中采用UTF-16编码方式对unicode进行表示(unicode是一种抽象概念,只确定了字符和码位的映射关系,不管编码),就是字符串的编码是utf-16,题主的例子中很清楚了。

    注意char类型16位,单个char肯定无法表示这一百多万个码位的,一但字符串中出现了char无法表示的码位(字符)的时候,这时候就用utf-16进行编码,用多个char表示这个码位,相应字符串的length方法也比字符要多(length是char数组的长度),用charat方法也不一定能获得那个字符,而要用codepointat方法获得那个位置所在的字符的unicode码位,我记得还有一个codepointsize方法,可以获得具体的(码位)字符数。

    再次强调一下,这个码位表示的是一个整数,是unicode编码里规定的某个字符想对应的整数。

    所幸大多数常用字符都能用一个char类型表示,所以一般length方法都能确定字符串中字符的个数,但这个方式看起来不是那么可靠,所以不是处理英文的地方,算字符数量的时候,还是考虑不要用length了吧。

    以上。

    手机码字,求指正错误。

张焱凯我的鲨鱼~也来自深海~~

感觉题主对字符编码已经理解的非常清楚了,不过我不知道题主说“我对码位这个概念理解的不是很清楚”是指哪里?

关于Java String的内存表示问题,题主说的那个内部char数组是UTF16码,而不是Unicode Code Point。其实Java里面的char本来就都是UTF16码,Unicode Code Point的数字范围已经超出char类型的范围了。

字符串对象在内存中的表示形式,不同语言确实有些许差异,不过大致只有两类:

一类是像C这种比较原始(raw)、比较底层、比较直接的语言,基本就是把你的源文件里面的那几个代表字符的字节原封不动的编译到可执行文件中,然后加载到内存中。所以这种情况下,字符串对象在内存中的表示形式,直接就是按你源文件的编码来的。

另一类是像Java、Python3之类的比较高级一点的语言,字符串对象在内存中通常是用UTF16表示的。

不过Python2情况还稍微复杂点,它有两种字符串对象,一种是UnicodeObject,另一种是StringObject。区别就是前者相当于Java String,后者相当于C char*。

现在C/C++中也有两种字符类型,一种是传统的char,另一种是宽字符wchar_t,这个跟Python2的情况比较类似。不过严格来说wchar_t的具体宽度是取决于不同编译器的实现的。GCC的实现貌似是32位,不知道是什么编码。VC应该是16位,采用UTF16编码。

时间: 2024-10-11 09:51:41

字符在内存中最终的表示形式是什么?是某种字符编码还是码位(Code Point)?的相关文章

c语言char型常量在内存中是以什么形式存放的

char型常量(字符),在计算机中是按其ASCII值进行存储,ASCII是"整型类"数据,在内存中全部以补码形式进行存放. 补码是一种二进制数据表示形式.整数分为正数.负数和零,计算机设计初期,规定,以字节的最高位表示符号,其余位表示数值,来表示有符号数据,这就是原码.但原码表示法中出现了"正0"和"负0"的表示现象,因此,又研究出来了补码概念,最终用补码来进行数据的存储. 规定: 正数的原码与补码相同. 负数的补码=反码+1, 反码是原码符号位

JavaScript中的变量在内存中的具体存储形式

栈内存和堆内存 JavaScript中的变量分为基本类型和引用类型 基本类型是保存在栈内存中的简单数据段,它们的值都有固定的大小,保存在栈空间,通过按值访问 引用类型是保存在堆内存中的对象,值大小不固定,栈内存中存放的该对象的访问地址指向堆内存中的对象,JavaScript不允许直接访问堆内存中的位置,因此操作对象时,实际操作对象的引用 结合代码与图来理解 let a1 = 0; // 栈内存let a2 = "this is string" // 栈内存let a3 = null;

论C/C++数据在内存中的二进制存放形式

http://blog.csdn.net/asmcos/article/details/46676101 http://blog.csdn.net/asmcos/article/details/46676087 http://blog.csdn.net/asmcos/article/details/46676073 http://blog.csdn.net/asmcos/article/details/46676053 http://blog.csdn.net/asmcos/article/de

C语言strchr()函数:查找某字符在字符串中首次出现的位置

头文件:#include <string.h> strchr() 用来查找某字符在字符串中首次出现的位置,其原型为:    char * strchr (const char *str, int c); [参数]str 为要查找的字符串,c 为要查找的字符. strchr() 将会找出 str 字符串中第一次出现的字符 c 的地址,然后将该地址返回. 注意:字符串 str 的结束标志 NUL 也会被纳入检索范围,所以 str 的组后一个字符也可以被定位. [返回值]如果找到指定的字符则返回该字

C/C++数据在内存中的存储方式

目录 1 内存地址 2 内存空间 ??在学习C/C++编程语言时,免不了和内存打交道,在计算机中,我们存储有电影,文档,音乐等数据,这些数据在内存中是以什么形式存储的呢?下面做一下简单介绍. 本文是学习VIPler的博文关于内存地址和内存空间的理解之后整理的,感谢VIPler提供学习资源. 1 内存地址 ??我们经常在书上或者网络上看到4位和8位的内存地址表示方法,比如0x0001或者0x00000001,为什么会有这两种区别呢? ??其实,这两种表示方法都是表示的编号为1的内存地址,都只是一个

利用libjpeg库解码内存中的jpeg数据

在"VS2013编译libjpeg库"这篇文章中本人介绍了如何在VS中编译libjpeg库并提供了一个应用的范例,而这篇文章将在此基础上,介绍如何用libjpeg库来解码内存中的jpeg数据. 其实这个需求已经不新鲜了,网上也能找到别人提供的一些解决方法,之所以要再次写不过是因为本人觉得那些方法或多或少都有些不对的地方,或者说因为版本的迭代,本来是对的,现在有点问题.当然,本人并没有很费心思的自己去一行一行的看源代码,实现的过程基本是参考这篇文章来做的,所以这里只是提供怎么改,而为什么

Maru OS 源码最终以源代码形式发布

包括一个 Ubuntu 桌面的 Maru OS 手机分发版,经勤快学基础教程QKXue.NET确认最终以源代码形式发布.如果对Maru OS 源码有兴趣,可从 Github(https://github.com/maruos/maruos)下载该项目,使用开发者指引运行起来(https://github.com/maruos/maruos/wiki/Developer-Guide)并加入开发者群(https://groups.google.com/forum/#!forum/maru-os-de

数据在内存中的存储(二进制形式存储)

计算机要处理的信息是多种多样的,如数字.文字.符号.图形.音频.视频等,这些信息在人们的眼里是不同的.但对于计算机来说,它们在内存中都是一样的,都是以二进制的形式来表示. 要想学习编程,就必须了解二进制,它是计算机处理数据的基础. 内存条是一个非常精密的部件,包含了上亿个电子元器件,它们很小,达到了纳米级别.这些元器件,实际上就是电路:电路的电压会变化,要么是 0V,要么是 5V,只有这两种电压.5V 是通电,用1来表示,0V 是断电,用0来表示.所以,一个元器件有2种状态,0 或者 1. 我们

整型数据在内存中的存放形式

整型数据在内存中是以其二进制的补码的形式存放的! 1.原码 就是以最高位作为符号位,0代表该数值为正,1代表为负! 比如:67和-67 2.反码 正数的原码.反码.补码相同! 负数的反码是在其符号位不变的基础之上,其余的数值位按位取反,就是0变成1,1变成0 3.补码 正数的原码.反码.补码相同! 负数的补码是其反码加1! 也就是说,在内存中,67其实存放的就是: 00000000 00000000 00000000 01000011 而-67其实存放的就是: 11111111 11111111