尽管我喜欢C和C++,但我还是忍不住在选择空终止字符串时不知所措:
std::basic_string模板进行了一些纠正,但是期望空终止字符串的普通字符数组仍然很普遍.这也是不完美的,因为它需要堆分配.这些事情中的一些最近比C更明显,因此C对于不了解它们是有意义的.然而,在C出现之前,有几个很平常.为什么选择空终止字符串而不是明显优越的长度前缀?
编辑:由于一些人在我的效率点上询问事实(并且不喜欢我已提供的事实),他们源于以下几点:
从下面的答案中,这些是空终止字符串更有效的一些情况:
以上都不像长度和连续那样常见.
在下面的答案中还有一个断言:
但这个不正确 - 它与null终止和长度前缀字符串的时间相同.(Null终止字符串只是在你希望新结束的地方粘贴一个空值,长度前缀只是从前缀中减去.)
我正在用C编写语言解释器,我的string类型包含一个length属性,如下所示:
struct String
{
char* characters;
size_t length;
};
Run Code Online (Sandbox Code Playgroud)
因此,我必须花费大量时间在我的解释器中手动处理这种字符串,因为C不包含对它的内置支持.我考虑过切换到简单的以null结尾的字符串只是为了符合底层C,但似乎有很多理由不:
如果使用"length"而不是查找null,则内置边界检查.
您必须遍历整个字符串才能找到它的长度.
你必须做额外的事情来处理以null结尾的字符串中间的空字符.
以空值终止的字符串与Unicode处理不佳.
非空终止字符串可以实习更多,即"Hello,world"和"Hello"的字符可以存储在同一个地方,只是具有不同的长度.使用以null结尾的字符串无法做到这一点.
字符串切片(注意:字符串在我的语言中是不可变的).显然,第二较慢(和更容易出错:考虑增加的错误检查begin和end对两种功能).
struct String slice(struct String in, size_t begin, size_t end)
{
struct String out;
out.characters = in.characters + begin;
out.length = end - begin;
return out;
}
char* slice(char* in, size_t begin, size_t end)
{
char* out = malloc(end - begin + 1);
for(int i = 0; i < end - begin; i++)
out[i] = in[i + …Run Code Online (Sandbox Code Playgroud)