Encoding &引用;在语言中,x字符串是y-例如UTF-16-默认情况下这是什么意思?

Encoding &引用;在语言中,x字符串是y-例如UTF-16-默认情况下这是什么意思?,encoding,character-encoding,character,Encoding,Character Encoding,Character,在许多地方,我们可以看到,例如,“C#使用UTF-16作为字符串”()。从技术上讲,这意味着什么? 我的源文件只是一些文本。假设我正在使用Notepad++编写一个简单的C应用程序;保存文件后,文本在磁盘上的字节表示方式取决于N++,所以这可能不是人们的意思。这是否意味着: 语言规范要求/建议将编译器输入编码为UTF-16 标准库函数支持编码并将字符串视为UTF-16,例如String的运算符[](返回第n个字符而不是第n个字节) 一旦编译器生成一个可执行文件,其中存储的字符串是UTF-16

在许多地方,我们可以看到,例如,“C#使用UTF-16作为字符串”()。从技术上讲,这意味着什么? 我的源文件只是一些文本。假设我正在使用Notepad++编写一个简单的C应用程序;保存文件后,文本在磁盘上的字节表示方式取决于N++,所以这可能不是人们的意思。这是否意味着:

  • 语言规范要求/建议将编译器输入编码为UTF-16
  • 标准库函数支持编码并将字符串视为UTF-16,例如
    String
    的运算符
    []
    (返回第n个字符而不是第n个字节)
  • 一旦编译器生成一个可执行文件,其中存储的字符串是UTF-16
我以C#为例,但这个问题适用于任何一种可以说它对字符串使用编码Y的语言

“C#使用UTF-16作为其字符串”

就我所理解的这个概念而言,这充其量只是一种简化。CLI运行时(如CLR)需要将它从程序集加载的字符串或运行时以UTF-16编码生成的字符串存储在内存中,或者至少将它们以这种方式呈现给运行时的其余部分和应用程序

请参阅CLI规范:

III.1.1.3字符数据类型

CLI字符类型占用内存中的2个字节,表示使用UTF-16的Unicode代码单元 编码。为了进行堆栈操作,字符值被视为无符号2字节整数 (§III.1.1.1)

和C#规格:

4.2.4字符串类型

string类的实例表示Unicode[在.NET术语中为UTF-16]字符串

我无法很快找到C#编译器支持哪些文件编码,但我很确定您可以将源文件存储为UTF-8编码,甚至ASCII(或其他非unicode代码页)

标准库函数支持编码,并将字符串视为UTF-16

不,BCL只将字符串视为字符串,作为
char[]
数组的包装器。只有在运行时之外进行转换时,如在P/Invoke调用中,运行时才“知道”要调用哪些平台函数以及如何将字符串封送到这些函数。例如,见

一旦编译器生成[assembly],字符串就存储在UTF-16中


是的。

让我们看看C/C++字符类型。它有8位长(1字节)。这意味着它可以存储255个不同的符号。现在让我们想想字体到底是什么。它有点像地图。从0到255(1字节)的值映射到符号。这些类型的字体通常包含两种类型的字符(例如西里尔文和拉丁文)和特殊符号。没有足够的空间(255个限制)保存希腊字母或中文字母

现在让我们看看什么是UTF-8。它是一种编码,它使用8位存储一些符号,使用16位存储一些符号。例如,如果您键入记事本单词“word”并使用UTF-8编码保存文件,则生成的文件的长度将恰好为4字节,但如果您键入单词“Пааа”,这也是4个符号,它将在您的存储上使用8个字节。因此,一些字母存储为1字节,其他字母存储为2字节

UTF-16表示所有符号都存储在2个字节中,逻辑上UTF-32=4个字节


让我们从编程的角度来看看这是什么样子。在记事本中键入符号时,它们存储在RAM中(以记事本可以理解的某种格式)。在磁盘记事本上保存文件时,在磁盘上写入一系列字节。这些序列取决于所选择的编码。当你阅读(用C#或其他语言)文件时,你必须知道它的编码。通过了解它,您将知道如何解释写在磁盘上的序列。

我认为OP要求的不是对Unicode的总结,而是对Unicode感知的语言或运行时意味着什么。事实上,这个答案有点离题。
BCL只是将字符串视为字符串。
-好的,但是,例如,要实现前面提到的
操作符[]
(不确定我在这里使用的是技术上正确的名称),我们必须知道字符串的编码;因此,类中至少有一些代码需要知道如何解释类的内容,对吗?@szczurcio否,运行时的字符串保证以UTF-16编码,因此运行时或语言必须“知道”编码。:)这些知识在运行时本身内置于
char
string
类型中,并通过语言公开。只有当字符串要导出到“字符串范围”(即.NET类型)之外时,编码才会起作用,比如在表示字符数据的字节数组中,或者在编组到平台函数时。啊,这是有意义的。您是否会避免声明一种语言对其字符串使用一种特定的编码过于简单化,或者这在其他(C#)语言的上下文中有意义?肯定不是自由主义的C和C++,而是别的什么?“SZCZURCIO我不太精通规范术语,所以我不会真的认为自己是一个权威的来源。我想说的是,C#语言仅仅公开了CLI的核心原则和规则,或者与之交互(同时为某些概念添加了语法糖,以便程序员更容易访问它们)。所以在某种意义上,你可以说“C#使用UTF-16表示字符串”,但这不是C#所做的,而是CLI所做的。