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結果:一連輸出了10行完全相同的"10"(可能並沒有按**編寫者的"意圖",輸出0到9)system;
using
system.collections.generic;
namespace
consoletest
foreach (action action in
ls)
system.console.read();
}
} }
看了鏈結裡面其實是編譯生成了乙個類,類裡面有乙個變數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...