什么是空字符串的基本原理?
就像我喜欢C和C ++一样,我忍不住在选择以null结尾的字符串时抓住我的头:
std::basic_string
模板纠正了这一点,但期望终止字符串的普通字符数组仍然普遍存在。 这也是不完善的,因为它需要堆分配。 这些东西中有几个比C更早出现,因此C不知道它们是有意义的。 然而,在C成立之前,有几个很清楚。 为什么会选择以null结尾的字符串而不是明显优越的长度前缀?
编辑 :由于有些人在上面的效率问题上提出了事实(并且不喜欢我已经提供的那些事实),它们源自一些事情:
从下面的答案,这些是一些情况下,空字符串更有效:
以上都不像长度和连续一样普遍。
在下面的答案中还有一个说法:
但是这是不正确的 - 对于以空字符结尾和长度为前缀的字符串,这是相同的时间量。 (空终止的字符串只在你想要新结束的地方粘住null,长度前缀只是从前缀中减去。)
从马的嘴里
BCPL,B或C都不支持该语言中的字符数据; 每个字符都像整数的向量一样处理字符串,并且通过一些约定来补充一般规则。 在BCPL和B中,字符串文字表示用字符串的字符初始化的静态区域的地址,并被打包到单元格中。 在BCPL中,第一个打包字节包含字符串中的字符数; 在B中,没有计数,并且字符串由一个特殊字符终止,这个特殊字符B拼写*e
。 这种改变是为了避免由于将计数保持在8位或9位槽中而造成的字符串长度限制,部分原因在于,根据我们的经验,维持计数看起来不如使用终止符方便。
Dennis M Ritchie,C语言的发展
C没有一个字符串作为语言的一部分。 C中的'字符串'只是一个指向char的指针。 所以也许你问的是错误的问题。
“忽略字符串类型的原因是什么”可能更具相关性。 为此我要指出,C不是面向对象的语言,只有基本的值类型。 一个字符串是一个更高层次的概念,必须以某种方式结合其他类型的值来实现。 C处于较低的抽象层次。
鉴于下面的狂风暴雨:
我只想指出,我并不是想说这是一个愚蠢或不好的问题,或者C表示字符串的C方式是最佳选择。 我试图澄清,如果考虑到C没有将字符串作为数据类型与字节数组区分的机制这一事实,问题会更简洁明了。 鉴于今天电脑的处理和记忆能力,这是否是最好的选择? 可能不会。 但事后总是20/20和所有:)
这个问题被称为Length Prefixed Strings (LPS)
与zero terminated strings (SZ)
东西,但主要暴露长度前缀字符串的好处。 这看起来可能是压倒性的,但说实话,我们也应该考虑LPS的缺点和深圳的优势。
据我所知,这个问题甚至可以被理解为一种有偏见的方式来问“零终止字符串有什么优点?”。
零终止字符串的优点(我看到):
"this is valid C"
。 它是一个字符串吗? 或四弦? 或者一堆字节...... char a[3] = "foo";
是有效的C(不是C ++),并且不会在a中放置最终的零。 char*
时,必须使其具有非常奇怪的行为。 即不返回字符串的地址,而是返回实际的数据。 也就是说,在标准C字符串确实效率低下的罕见情况下,无需抱怨。 Libs可用。 如果我遵循这个趋势,我应该抱怨标准C不包含任何正则表达式支持函数......但是真的每个人都知道它不是一个真正的问题,因为有用于此目的的库。 所以,当需要字符串操作效率时,为什么不使用像bstring这样的库? 甚至是C ++字符串?
编辑 :我最近看了D字符串。 足够有趣的是,选择的解决方案既不是大小前缀也不是零终止。 和C一样,用双引号括起来的文字字符串对于不可变的char数组来说简直就是短手,而且该语言也有一个字符串关键字,意思是(不可变的char数组)。
但是D阵列比C阵列要丰富得多。 在静态数组的情况下,长度在运行时是已知的,所以不需要存储长度。 编译器在编译时有它。 在动态数组的情况下,长度是可用的,但D文档没有说明它保存的位置。 就我们所知,编译器可以选择将它保存在某个寄存器中,或者存储在远离字符数据的一些变量中。
在普通的char数组或非literal字符串中,没有最终的零,因此如果程序员想从D调用某个C函数,程序员必须自行放置它。在字符串的特殊情况下,D编译器仍然在每个字符串的末尾(以便于转换为C字符串以使调用C函数更容易?),但是此零不是字符串的一部分(D不会以字符串大小计算)。
唯一让我感到失望的是字符串应该是utf-8,但是即使使用多字节字符,长度显然仍然会返回大量字节(至少在我的编译器gdc中是这样)。 我不清楚它是编译器错误还是目的。 (好吧,我可能已经知道发生了什么事情,对D编译器说你的源代码使用utf-8,你必须在开始时写一些愚蠢的字节顺序标记,我写愚蠢的是因为我知道不是编辑器这样做,尤其是对于UTF- 8应该是ASCII兼容的)。
链接地址: http://www.djcxy.com/p/73547.html上一篇: What's the rationale for null terminated strings?
下一篇: O2, and bitfields