从编译器的角度来看,字符串是什么样的?

时间:2015-10-04 18:13:54

标签: c# .net string memory compiler-construction

C中,编译器有一个指向字符串开头的指针,并有一个结束符号('\0')。如果用户想要计算字符串的长度,编译器必须计算字符串数组的元素,直到找到'\0'

UCSD-strings中,编译器在第一个符号中具有字符串的长度。

编译器对C#-strings的看法是什么?是的,从用户的角度来看, String 是一个object,其字段为 Length ,我不是在谈论高级的东西。我想知道深度算法;例如,编译器如何计算字符串的长度?

2 个答案:

答案 0 :(得分:21)

让我们执行以下代码:

string s = "123";
string s2 = "234";
string s3 = s + s2;
string s4 = s2 + s3;
Console.WriteLine(s + s2);

现在让我们在最后一行放一个断点并打开内存窗口:

Strings

在内存窗口中编写s3,我们可以看到2(s3s4)字符串一个接一个地分配,开头有4个字节的大小。

您还可以看到已分配其他内存,例如strings类类型标记和其他string类数据。

string class本身包含一个成员private int m_stringLength;,其中包含string的长度,这也使string.Concat()执行速度超快(通过在开头分配整个长度) ):

int totalLength = str0.Length + str1.Length + str2.Length;

String result = FastAllocateString(totalLength);
FillStringChecked(result, 0, str0);
FillStringChecked(result, str0.Length, str1);
FillStringChecked(result, str0.Length + str1.Length, str2);

我觉得有点奇怪的是IEnumerable<char>.Count() string的实现是使用默认实现来完成的,这意味着逐个迭代项目,而不像ICollection<T>那样List<T> } IEnumerable<char>.Count()通过获取ICollection<T>.Count属性来实现。

答案 1 :(得分:6)

在C#中,字符串的长度存储在私有字段([NonSerialized]private int m_stringLength;)中的对象中,不必在运行时计算。

The source code of String class is available online.