为什么C需要空零作为字符串终止符,而Java不需要';T

为什么C需要空零作为字符串终止符,而Java不需要';T,java,c,Java,C,我注意到,当我在C中创建一个字符数组来保存字符串时,我总是需要在末尾添加一个空零作为终止符。例如: char Month[10]; Month[0] = 'M'; Month[1] = 'a'; Month[2] = 'r'; Month[3] = 'c'; Month[4] = 'h'; Month[5] = '\0'; 这里我需要添加Month[5]='\0',以使char数组显示正确的结果。如果我忽略空零,它将给出结果March\377。但是在Java中,我仍然会得到March,而不添加

我注意到,当我在C中创建一个字符数组来保存字符串时,我总是需要在末尾添加一个空零作为终止符。例如:

char Month[10];
Month[0] = 'M';
Month[1] = 'a';
Month[2] = 'r';
Month[3] = 'c';
Month[4] = 'h';
Month[5] = '\0';

这里我需要添加
Month[5]='\0'
,以使char数组显示正确的结果。如果我忽略空零,它将给出结果
March\377
。但是在Java中,我仍然会得到
March
,而不添加空零。我想知道C和Java如何不同地处理这种情况?

在Java中,我们有一个名为
String
的类,它有一个名为
length()
的方法


在C语言中,您需要在字符串的末尾有一个
\0
,这样您就可以知道字符串的结尾。但是在Java中,使用
length()
C方法处理的这个问题并没有将字符串作为实际的数据类型,惯例是以空字符结尾的字符数组可以用作字符串。这是在语言中使用字符串文字时得到的结果,也是不使用字符串文字时必须重新创建的结果


根本的问题是C希望通过不存储长度(例如Pascal将字符串长度存储在第一个字节中)来节省其字符串表示的内存,因此长度必须以某种方式跟随数据,在这种情况下,使用
'\0'

结束数据。在C中,没有类型
字符串,只有一个指向
字符的指针。在C语言中,当您需要一个字符串时,您需要知道该字符串中有多少个字符,或者有一个指示器来查看您是否已到达该字符串的末尾

传统上,有两种方法满足此需求。在C世界中,约定是用
\0
字符终止字符串。在PASCAL世界中,惯例是使用另一个变量来存储字符串的长度

Java使用PASCAL约定并将字符串的长度存储在另一个变量中作为字符串的内容


这两种方法都有各自的优点。在Java/PASCAL世界中,很容易知道字符串的长度,字符串可以包含\0字符。在C语言中,您可以对尾部子字符串等重复使用相同的字符数组。

在Java中,字符串主要是一种抽象,您不必关心内部表示。您有一些方法可以对其执行操作,并允许您获取有关字符串的信息

然而,在C语言中,情况恰恰相反。您希望了解并关注字符串的内部结构,以避免分段冲突


此外,在C语言中,组成字符串的以null结尾的字符序列占据一组连续的内存位置。大多数字符串函数(strcmp、strcat等)都希望您有一个以null结尾的字符串来知道字符串的结尾在哪里。因此,如果末尾没有空字符,则字符串函数可以从字符串的末尾运行。

由于这是一个电路板问题,我们必须在这里指出两件重要的事情:

1) 首先要确认的是,C作为一种基本语言,抽象性很低,它没有字符串作为数据类型。在C语言中,字符串只是字符的集合。所以我们需要一些东西来指定字符串的结束位置,为此我们使用\0 null终止符(它告诉库,这是字符串的结束位置)

那么,为什么\0空终止符:空终止符恰好是C、字符串文本和处理字符串的标准库函数所选择的方式。显然,这很方便,因为空字符实际上不用于其他任何用途。它不可打印,既不是控制字符,也没有为其定义的任何行为(如以某种特定方式移动光标,例如\t)

此外,根据ISO C标准第7.1.1节,字符串的定义如下:

字符串是以第一个空字符结尾并包含该空字符的连续字符序列

2) Java是一种成熟的语言,我的意思是,它是比C更高级的语言。在Java中,我们可以将字符串定义为:

A String is defined to be a fixed length sequence of char values. All possible char values (from 0 to 65535) may be used in a String. There is no "distinguished" value that means that the string ends. 字符串定义为固定长度的字符值序列。字符串中可以使用所有可能的字符值(从0到65535)。没有表示字符串结束的“可分辨”值。 那么,它们是如何跟踪字符串结尾的呢?string类提供了一个名为length的方法来了解字符串中的字符数

因此,您可以从语言实现说明中清楚地看到,C要求字符串以Null结尾,因为它们只是一个字符序列,需要一个特殊字符来确定该序列的结束位置,而java字符串是作为类(和对象)实现的


额外注意事项:我知道这不是问题,但我指定,如果您通过JNI读取C代码中Java字符串的数据,那么我们使用JNI函数,如GetStringChars()或GetStringUTFChars()。这两个函数都没有记录为返回以null结尾的数据,我们应该使用GetStringLength()来确定其长度。同样,对于GetStringUTFChars(),必须使用GetStringUTF8Length()以修改的UTF-8格式确定其长度

在Java中,所有字符串都是不可变的对象。在C语言中,您可以通过将指向
char
的指针指向字符串文本来重新创建相同的内容。但是,你的问题似乎太宽泛了,因为每种语言都有自己的相同点和不同点。@edyy你自己知道的答案是:他们确实以不同的方式处理这种情况。@Vlad,来自莫斯科。嗯,这不仅仅是一个武断的选择。拥有一个带有length属性的String对象可以避免在整个字符串中进行迭代以查找“\0”,因为在Java 8中,这个变量似乎已被删除
length()
简单地
返回backedCharArray.length