2015-10-04 35 views
11

C中,編譯器有一個指向字符串開頭的指針,並有一個結束符號('\0')。如果用戶想要計算字符串的長度,編譯器必須對字符串數組的元素進行計數,直至找到'\0'從編譯器的角度看字符串是如何看的?

UCSD-strings中,編譯器具有第一個符號中字符串的長度。

編譯器認爲C#-strings是什麼?是的,從用戶的角度來看String是一個object有一個字段Length,我不是在談論高層次的東西。我想知道深層算法;例如,編譯器如何計算字符串的長度?

+4

你的C假設是錯誤的。一個C編譯器完全知道**每個字符串的長度。要看到這個,請在​​字符串上調用'sizeof'(而不是指向_字符串!)。 – MSalters

+1

通常情況下,我會把它作爲一個複製品來關閉,但是重複是不好的。 http://www.codeproject.com/Articles/3377/Strings-UNDOCUMENTED – usr

+0

@MSalters你是混淆的概念。數組和字符串不同的實體,他們有不同的操作相關聯。他們是相關的,但他們是不同的抽象,他們不應該混合。 –

回答

21

讓我們執行以下代碼:

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

現在,讓我們把一個斷點在最後一行並打開存儲窗口:

Strings

在寫作s3內存窗口我們可以看到2(s3s4)str在開始時一個接一個地分配4個字節的大小。

此外,您還可以看到其他內存已分配,例如strings類型令牌和其他string類數據。

string class本身包含其中包含string的長度成員private int m_stringLength;,這也使得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); 

我覺得有點怪stringIEnumerable<char>.Count()的實現是使用默認實現完成的,這意味着一個接一個迭代項目,而不像ICollection<T>s,如List<T>,其中IEnumerable<char>.Count()通過其ICollection<T>.Count屬性來實現。

+2

@homk如果這就是你想知道的,你真正的問題與'從編譯器的角度'無論如何都沒有關係。 – EJP