"在语言中x字符串是y - 例如UTF-16 - 默认情况下" - 那是什么意思?

时间:2015-10-14 11:13:38

标签: encoding character-encoding character

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

  • 语言规范要求/建议将编译器输入编码为UTF-16?
  • 标准库函数具有编码感知功能,并将字符串视为UTF-16,例如String的运算符[](返回第n个字符< / em>而不是第n个字节)?
  • 编译器生成可执行文件后,存储在其中的字符串是UTF-16?

我以C#为例,但这个问题适用于任何人都可以说它使用Y代码作为字符串的语言。

2 个答案:

答案 0 :(得分:2)

  

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

据我了解这个概念,这是一个简化。需要CLI运行时(例如CLR)来存储从程序集加载的字符串,或者在运行时以UTF-16编码在内存中生成的字符串 - 或者至少将它们呈现给运行时和应用程序的其余部分。 / p>

请参阅CLI规范:

  

III.1.1.3字符数据类型

     

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

和C#规范:

  

4.2.4字符串类型

     

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

我无法快速找到C#编译器支持的文件编码,但我确信您可以使用UTF-8编码存储源文件,甚至是ASCII(或其他非Unicode代码页)。

  

标准库函数具有编码感知功能,并将字符串视为UTF-16

不,BCL只将字符串视为 strings ,是char[]数组的包装器。只有在运行时之外转换时,就像在P / Invoke调用中一样,运行时“知道”要调用的平台函数以及如何将字符串封送到这些函数。请参阅示例C++/CLI Converting from System::String^ to std::string

  

编译器生成[assembly]后,字符串会以UTF-16格式存储在其中吗?

答案 1 :(得分:0)

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

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

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

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