c 基礎知識

2022-01-16 00:56:20 字數 2265 閱讀 1902

string 是不可變的,是引用型別繼承與object(值型別繼承於valuetype),每次拼接string其實是在託管堆上構造乙個新的物件。這樣在反覆的拼接字串的時候就會產生大量的垃圾字串,由gc自動**,這個時候gc會頻繁的**垃圾字串,影響效能,所以通常推薦使用stringbuilder來做字串拼接,

那麼string支援字串拼接的意義何在呢?

這裡就得說到字串池這個概念,當我們建立乙個字串的時候,會先去字串池中找(雜湊表),如果沒有找到就會建立乙個新的字串並儲存到字串池中,當建立的字串已經在字串池中存在的時候,就會去引用。這樣已經建立過的字串就可以共享,節省空間。因為在程式中,我們會使用大量的字串,假如我們每次出現的字串都在記憶體空間中開闢一塊空間來儲存,就會在記憶體中產生大量相同的字串,也會造成垃圾**頻繁的執行,影響效能。所以string的字串拼接適合少量的拼接,對於大量的拼接,則推薦使用stringbuilder。

下面說說string的字串拼接與stringbuilder拼接的簡單過程。

string的字串拼接過程:string a='a'; a+=b;

1.開闢足夠大的臨時儲存空間來保證足夠儲存字串a和b。

2.將a複製到臨時區的開始處。

3.將b複製到臨時儲存區的結尾處。

4.釋放a的舊有記憶體。

5.給a分配新記憶體。

6.將臨時儲存空間的字串複製到5中新開闢的記憶體,並將a的引用指向新記憶體。

stringbuilder拼接的過程:stringbuilder是鏈式儲存結構,建構函式初始化stringbuilder例項的大小,可儲存的最大容量,當前字串。當新新增的字串大於當前stringbuilder剩餘空間的時候,stringbuilder就會開闢出一塊新的空間(大小=原大小*2),新字串補充滿剩餘記憶體空間後,將剩下的字串放入新開闢的記憶體空間。引用一下網上的一張圖。

2者之間的本質區別在於,string在字串拼接的時候是建立乙個新的物件來儲存拼接後的字串,而stringbuilder則是在原stringbuilder物件上開闢新的記憶體空間,是操作原物件而非string的建立新物件。

1.引用型別的內部變數,即使是值型別,也會在引用型別被例項是一起存放在堆上,方法內部的值型別變數不會初始化,在執行方法的時候放在棧上面。

2.對於值型別的陣列,因為陣列是引用型別。所以陣列內的值型別也在堆上。

3.閉包,lamda表示式。如下:           

actionact = a =>;

c# 成的il 會新增乙個靜態的輔助類,閉包內的區域性變數 也會成為輔助類的成員變數,因此,這種值型別的區域性變數也被分配到堆上。

閉包的陷阱:參考 菩提樹下的楊過 :

using

system;

using

system.collections.generic;

namespace

consoletest

foreach (action action in

ls)

system.console.read();

}

} }

結果:一連輸出了10行完全相同的"10"(可能並沒有按**編寫者的"意圖",輸出0到9)

看了鏈結裡面其實是編譯生成了乙個類,類裡面有乙個變數i和列印i的方法,然後建立乙個action委託集合將方法賦值,最後遍歷集合執行,在執行的時候i已經加到10了。所以要通過乙個內部變數來避免這種陷阱。。

雜湊表 hashtable ,也稱雜湊表,主要是根據關鍵碼值(key,value)來直接訪問資料結構,通過把關鍵碼值對映到表中乙個位置來訪問記錄。

它的實現方法是:把key通過乙個固定的演算法函式(除餘法,數字選擇法)來轉換成乙個整數字元,然後將該整數除以乙個數字進行取餘,將餘數作為陣列的下標,將value儲存在該餘數的陣列下標的空間內。當使用雜湊表查詢的時候,再次將key通過相同函式轉換整數取餘得到下標,定位到對應的陣列控制項獲取value值。(通過餘數分配不同的陣列空間,查詢的時候通過餘數找對應的陣列空間,這樣就避免了全表掃瞄,節約時間。)

a) 除餘法: 

選擇乙個適當的正整數 p ,令 h(k ) = k mod p ,這裡, p 如果選取的是比較大的素數,效果比較好。而且此法非常容易實現,因此是最常用的方法。 

b) 數字選擇法: 

如果關鍵字的位數比較多,超過長整型範圍而無法直接運算,可以選擇其中數字分布比較均勻的若干位,所組成的新的值作為關鍵字或者直接作為函式值。 

C 基礎知識

抽象類 abstract class 一種不可以被例項化的類。抽象類中一般含有抽象方法,當然也可有具體實現。繼承類只有實現過所有抽象類的抽象方法後才能被例項化。介面 inte ce 只含有共有抽象方法 public abstract method 的類。這些方法必須在子類中被實現。反射 程式集包含模...

c 基礎知識

或運算的意義是什麼 0 0 0 0 1 1 1 0 1 1 1 1 無進製與運算的意義是什麼 在vc中,視窗的每個屬性對應乙個只有一位為1的16位的二進位制數,當增加某屬性做或運算 即可,取消某個屬性只需與 上這個屬性的取反。cs.style ws maximizebox 和cs.style cs....

C 基礎知識

1 malloc和new區別與聯絡 a malloc malloc為函式,需要標頭檔案,申請的無型別,需要強制轉換 free釋放。示例 char p char malloc 10 sizeof char free p b new new是運算子,不需要標頭檔案,申請的是有型別的,自動呼叫建構函式 d...