盡管我熱愛C和C ++,但我還是忍不住選擇以null結(jié)尾的字符串:在C之前存在長度前綴(即Pascal)的字符串長度前綴的字符串允許進行恒定的時間長度查找,從而使幾種算法更快。前綴字符串的長度使導致緩沖區(qū)溢出錯誤更加困難。即使在32位計算機上,如果允許字符串成為可用內(nèi)存的大小,則帶前綴的長度字符串也只比以空終止的字符串寬3個字節(jié)。在16位計算機上,這是一個字節(jié)。在64位計算機上,4GB是一個合理的字符串長度限制,但是即使您希望將其擴展為機器字的大小,64位計算機通常也具有足夠的內(nèi)存,使得多余的七個字節(jié)屬于null參數(shù)。我知道原始的C標準是為極差的機器(就內(nèi)存而言)編寫的,但是效率論點在這里并沒有賣給我。幾乎所有其他語言(例如Perl,Pascal,Python,Java,C#等)都使用長度前綴的字符串。這些語言通常在字符串操作基準中勝過C,因為它們在使用字符串時效率更高。C ++使用std::basic_string模板對此進行了一些糾正,但是期望以null終止的字符串的純字符數(shù)組仍然很普遍。這也是不完美的,因為它需要堆分配。空終止的字符串必須保留一個字符(即null),該字符不能存在于字符串中,而長度前綴的字符串可以包含嵌入的null。這些事情中,有幾件事比C揭露的要新,因此C不必了解它們是有道理的。但是,在C出現(xiàn)之前,有幾個很簡單。為什么會選擇空終止的字符串而不是明顯更好的長度前綴?編輯:由于有些人在上述效率點上要求提供事實(并且不喜歡我已經(jīng)提供的事實),因此它們源于以下幾點:使用空終止字符串的Concat需要O(n + m)的時間復雜度。長度前綴通常只需要O(m)。使用空終止字符串的長度需要O(n)時間復雜度。長度前綴為O(1)。長度和concat是迄今為止最常見的字符串操作。在某些情況下,以null終止的字符串可能更有效,但這種情況發(fā)生的頻率要少得多。從以下答案中可以看出,在某些情況下以null終止的字符串更有效:當您需要截斷字符串的開頭并將其傳遞給某種方法時。即使允許您銷毀原始字符串,也無法真正在恒定時間內(nèi)使用長度前綴來執(zhí)行此操作,因為長度前綴可能需要遵循對齊規(guī)則。在某些情況下,您只是逐個字符地遍歷字符串,則可以保存CPU寄存器。請注意,這僅在您沒有動態(tài)分配字符串的情況下才有效(因為您必須釋放它,因此必須使用保存的CPU寄存器保存最初從malloc和friends獲得的指針)。以上都不是最常見的長度和連貫性。以下答案中還有一個斷言:您需要切斷字符串的結(jié)尾但這是不正確的-空終止和長度為前綴的字符串的時間相同。(以NULL終止的字符串只是在您希望新的結(jié)尾處保留一個NULL,長度前綴只是從前綴中減去。)
3 回答

守著星空守著你
TA貢獻1799條經(jīng)驗 獲得超8個贊
C沒有字符串作為語言的一部分。C語言中的“字符串”只是指向char的指針。所以也許您問錯了問題。
“省略字符串類型的基本原理是什么”可能更有意義。為此,我要指出,C不是面向?qū)ο蟮恼Z言,僅具有基本的值類型。字符串是一個高級概念,必須通過某種方式組合其他類型的值來實現(xiàn)。C處于較低的抽象級別。
鑒于下面的狂風:
我只想指出,我并不是要說這是一個愚蠢或糟糕的問題,或者表示字符串的C方法是最佳選擇。我試圖澄清的是,如果考慮到C沒有將字符串作為數(shù)據(jù)類型與字節(jié)數(shù)組區(qū)分開的機制,這一問題將更加簡潔。鑒于當今計算機的處理能力和存儲能力,這是最佳選擇嗎?可能不是。但是事后看來總是20/20等等:)
- 3 回答
- 0 關注
- 771 瀏覽
添加回答
舉報
0/150
提交
取消