我注意到当我创建一个字符数组来保存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如何以不同的方式处理这种情况?
答案 0 :(得分:7)
在Java中,我们有一个名为String
的类,它有一个名为length()
的方法。
在C语言中,您需要在字符串的末尾添加\0
,以便知道字符串的结束位置。但在Java中,此问题使用方法length()
处理。
答案 1 :(得分:5)
在C中没有类型string
,只有指向char
的指针。当你在C中需要一个字符串时,你需要知道字符串中有多少个字符,或者有一个指示符来表明你已到达字符串的末尾。
传统上,这种要求有两种方法。在C世界中,约定是使用\0
字符终止字符串。在PASCAL世界中,约定是使用另一个变量来存储字符串的长度。
Java使用PASCAL约定并将字符串的长度存储在另一个变量中作为字符串的内容。
这两种方法都有其优点。在Java / PASCAL世界中,很容易知道字符串的长度,字符串可以包含\ 0字符。在C中,您可以为尾部子串等重用相同的字符数组。
答案 2 :(得分:3)
C没有字符串作为实际数据类型,并且约定只是以空字符结尾的字符数组可以用作字符串。这就是你在语言中使用字符串文字时所得到的,这就是你不使用它时必须重新创建的内容。
潜在的问题是C想要通过不存储长度来保存其字符串表示形式的内存(例如,Pascal将字符串长度存储在第一个字节中),因此长度必须以某种方式遵循数据,在这种情况下用'\0'
结束数据。
答案 3 :(得分:2)
在Java中,字符串主要是一种抽象,你不应该关心内部表示。您有方法对其执行操作,并允许您获取有关字符串的信息。
然而,在C中,这恰恰相反。您希望了解并关注字符串的内部结构,以避免分段违规。此外,在C中,组成字符串的以空值终止的字符序列占据了一组连续的内存位置。大多数字符串函数(strcmp,strcat等)都希望你有一个以null结尾的字符串来知道字符串结尾的位置。因此,如果最后没有空字符,那么字符串函数可以在字符串的末尾运行。
答案 4 :(得分:1)
由于这是一个董事会问题,我们必须指出两件重要的事情:
1)要确认的第一件事是,C作为基本语言并且具有低抽象,它没有字符串作为数据类型。在C中,string只是一个字符集合。所以我们需要一些东西来指定字符串结束的位置,为此我们使用\ 0 null终止符(它告诉库,这是字符串结束的地方)
所以,为什么\ 0 null终止符: Null终止恰好是C语言的选择方式,用于字符串文字和处理字符串的标准库函数。不经意的是,它很方便,因为空字符并不真正用于其他任何东西。它既不是可打印的,也不是控制字符,也没有为它定义任何行为(比如以某种特定方式移动光标,例如\ t)
此外,根据ISO C标准,第7.1.1节,以这种方式定义字符串:
A string is a contiguous sequence of characters terminated by and including the first null character.
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.
那么,他们如何跟踪字符串结尾? String类提供了一个名为length的方法来知道字符串中的字符数。
因此,您可以从语言实现中明确看出,C要求字符串的Null终止,因为它们只是一个字符序列,需要一个特殊字符来确定此序列的结束位置,同时,java字符串被实现作为类(&对象)。
额外注意事项我知道这没有被问到,但是我指的是,如果您通过JNI读取C代码中的Java字符串数据,那么我们使用JNI函数如GetStringChars()或GetStringUTFChars()。这些函数都没有记录为返回以null结尾的数据,我们应该使用GetStringLength()来确定它的长度。与GetStringUTFChars()类似,您必须使用GetStringUTF8Length()以修改的UTF-8格式确定其长度。