本節內容是對於C#基礎類型的存儲方式以及C#基礎類型的理論介紹git
例如如下這句話:「張三是一名程序員,今年15歲重50.3kg,他的代號是‘A’,他家的經緯度是(N30,E134)。」,這句話就是一個字符串,使用雙引號括起來。而15則表示是一個 整數類型,50.3就是小數類型,不過咱們在C# 中一般稱爲 浮點類型,最後一個經緯度,咱們一般定位地點的時候都是成對出現,因此咱們認爲這兩者是一個密不可分的結構,這種類型咱們稱爲 結構體類型(struct)。程序員
以上我所說的數據類型都是一個所含有信息量必定的數值,咱們稱爲值類型;而張三這我的,他所含有的數據大小是不固定的,好比我又瞭解到了張三是一個富二代,那麼他就會增長一個屬性是富二代,咱們須要更多的空間去存儲他,張三這個變量咱們一般就稱爲引用類型,而張三這個名字,咱們就稱爲引用,若是你對C或者C++熟悉的話,張三這個名字就是指向張三這我的(對象)的一個指針。github
在C# 中,數據在內存中的存儲方式主要分爲在堆中存儲和棧中存儲。咱們以前提到的值類型就是存儲在棧中,引用類型的數據是存儲在堆中,而數據是在棧中。編程
值類型:存儲在棧(Stack,一段連續的內存塊)中,存儲遵循先進後出,有嚴格的順序讀取訪問速度快,可經過地址推算訪問同一個棧的其他變量。數組
引用類型:引用(本質上和C++中的指針一致)存儲在棧中,內含的數據存儲在堆中(一大塊內存地址,內部變量存儲不必定連續存儲)。安全
(此處須要補充堆棧圖片)編程語言
事實上,值類型和引用類型有一個很明顯的區別就是值類型應當都是有值的,而引用類型是能夠爲空值的。ide
數組:繼承自Array類,屬於任意類型的一種集合,但不一樣於集合,大小必須被初始化。在內存中是一段連續的內存空間,可是不是值類型。函數
int number = 5;//定義一個32位整數類型 bool b = true;//定義 //注意看如下兩條,string定義的字符串必須爲雙引號,而char使用單引號而且只容許輸入一個字符 string str = "test"; char a = 'a'; //記得後綴 float f = 1.3f; decimal d = 1.5m;
數據類型的轉換分爲隱式轉換和顯式轉換,看下面幾個例子:學習
string a = "15"; int b = int.Parse(a);//顯式轉換 b = (int)a;//強制轉換 b = Convert.ToInt32(a);//顯式轉換,較經常使用 double d = 1.5; b = d;//隱式轉換
數組指一個類型(任意)的集合,例如你定義一個變量爲a=5,很輕鬆,假設你須要100個呢?所以咱們使用數組來存儲。
數組的定義以及使用以下:
///僞代碼,T爲類型,n爲大小 T [] t = new T[n]; //定義一個整型數組 int [] a = new int [5]; //你也能夠選擇初始化的方式定義 int [] b = new int [] {1,2,3,4,5}; //或 int [] c = new int [5]{1,2,3,4,5}; //數組的訪問,從0開始索引 Console.WriteLine(b[0]);
具體的操做我會在我在BiliBili上發佈的.Net Core教程上進行詳細的講述。
結構體你能夠理解爲將將若干個類型拼接在一塊兒,可是存在一個很重要的內容——內存對齊。例以下面兩個結構體:
struct S { int a; long b; int c; } struct SS { int a; int b; long c; }
乍一看你會以爲這兩個結構體徹底一致,絲毫沒有任何的差異。但事實上,在大多數編程語言裏面,對於結構體這種大小並非定值的值類型,都存在一個最小分配單元用於結構體內單個變量的大小分配。在內存中,他們兩個的存儲方式有很大的不一樣。
對於上面兩個結構體,他們在內存中的單元分配是:
在C#中,若是你不指定最小分配單元,那麼編譯器將會把結構體中佔用內存最大的做爲最小分配單元。不過尤爲須要注意一件事,就是引用類型在結構體中。鑑於咱們如今還沒有講解面向對象的類,咱們用string做爲成員寫一個結構體。以下面這個例子:
struct S { char a; long b; string c; } //函數中建立 S s = new S(); s.a = 'a'; s.b = 15; s.c = "I Love .NET Core And Microsoft"
很顯然s.c的大小超過告終構體中其他兩個,可是內存分配的時候就是以最大的c做爲標準嗎?
顯然不是,咱們要知道struct是在棧中分配內存,string的內容是在堆中的,因此在結構體中存儲的string只是一個引用,並不會包含其餘的東西,只佔用4個字節。而且特別的,引用類型在內存中的位置位於大於四字節的字段前,小於四字節字段後。
上面內存分配應當是這樣:
a(8) --> c(8) --> b(8)。
若是須要深刻了解這一方面內容,建議去閱讀《CLR Via C#》這本書,以及學習SOS調試相關內容。
更多內容請關注個人BiliBili地址以及個人博客。
Github上有練習題、實例代碼以及ppt。
若是我幫到了你,請在個人Github點上一顆星,一個fork。謝謝,地址Github