c#資料型別/變數/常量/計算機資料儲存(進位制之間的相互轉化)
一c#資料型別
注:值型別:值直接儲存在堆疊中(儲存空間小,呼叫速度快);
引用型別:值儲存在堆中(儲存空間大,呼叫速度慢)
1.值型別
a. 值型別變數可以直接分配給一個值.它們是從類System.ValueType中派生的.
b.值型別直接儲存其值.
c.值型別的例項通常是線上程棧上分配的(靜態分配),但是在某些情形下可以儲存在堆中.
d.值型別總是分配在它宣告的地方:作為欄位時,跟隨其所屬的變數(例項)儲存;作為區域性變數時,儲存在棧上.棧的記憶體是自動釋放的.
e.值型別在記憶體管理方面具有更好的效率,並且不支援多型, 適合用做儲存資料的載體.
f.C#的值型別包括:結構體(數值型別、bool 型、使用者定義 的結構體),列舉,可空型別.
型別 | 描述 | 範圍 | 預設值 |
---|---|---|---|
bool | 布林值 | True 或 False | False |
byte | 8 位無符號整數 | 0 到 255 | 0 |
char | 16 位 Unicode字元 | U +0000 到 U +ffff | ‘’ |
decimal | 128 位精確的十進 制值,28-29 有效位 數 | (-7.9 x 1028 到 7.9 x 1028) / 100 到 28 | 0.0M |
double | 64 位雙精度浮點型 | (+/-)5.0 x 10-324 到 (+/-)1.7 x 10308 | 0.0D |
float | 32 位單精度浮點型 | -3.4 x 1038 到 + 3.4 x 1038 | 0.0F |
int | 32位有符號整數型別 | -2,147,483,648 到 2,147,483,647 | 0 |
long | 64 位有符號整數型別 | -923,372,036,854,775,808 到 9,23,372,036,854,775,807 | 0L |
sbyte | 8 位有符號整數型別 | -128 到 127 | 0 |
short | 16 位有符號整數類 型 | -32,768 到 32,767 | 0 |
uint | 32 位無符號整數型別 | 0 到 4,294,967,295 | 0 |
ulong | 64 位無符號整數類 型 | 0 到 18,446,744,073,709,551,615 | 0 |
ushort | 16 位無符號整數類 型 | 0 到 65,535 | 0 |
2.引用型別
a.引用型別不包含儲存在變數中的實際資料,但它們包含對 變數的引用.繼承自System.Object 類.
b.引用型別儲存對其值的引用.它們指的是一個記憶體位置.使用多個變數時,引用型別可以指向一個記憶體位置.如果記憶體位置的資料是由一個變數改變的,其他變數會自動反映這種值的變化.
c.引用型別當宣告一個類時,只在棧中分配一小片記憶體用於容納一個地址,而此時並沒有為其分配堆上的記憶體空間.當使用new 建立一個類的例項時,分配堆上的空間,並把堆上空間的地址儲存到棧上分配的小片空間中.
d.引用型別的物件總是在程序堆中分配(動態分配).
e.引用型別在棧中儲存一個引用,其實際的儲存位置位於託管堆.簡稱引用型別部署在託管推上. (堆記憶體是.NET 中會 由 GC 來自動釋放).
f.引用型別可以派生出新的型別,而值型別不能,因為所有的值型別都是密封(seal).
g.引用型別可以包含 null 值,值型別不能(可空型別功能允 許將 null 賦給值型別,如 int? a = null; ).
h.引用型別變數的賦值只複製對物件的引用,而不復制物件 本身.而將一個值型別變數賦給另一個值型別變數時,將複製包含的值.
i. C#的引用型別包括:
內建的 引用型別有:object、dynamic 和 string。
①物件(Object)型別是C#通用型別系統(Common Type System - CTS)中所有資料型別的終極類.ObjectSystem.Object 類的別名.所以物件 (Object)型別可以被分配任何其他型別(值型別、 引用型別、預定義型別或使用者自定義型別)的值. 但是,在分配值之前,需要先進行型別轉換.
② 動態(Dynamic)型別您可以儲存任何型別的值在動 態資料型別變數中.這些變數的型別檢查是在執行時發生的.動態型別與物件型別相似,但是物件型別變數的型別檢查是在編譯時發生的,而動態型別 變數的型別檢查是在執行時發生的.
③字串(String)型別允許給變數分配任何字串值.字串(String)型別是 System.String 類的別名它是從物件(Object)型別派生的.字串(String)型別的值可以通過兩種形式進行分配: 引號和 @引號.
使用者自定義引用型別有:class、陣列、interface 或 delegate.
二.變數
一個變數只不過是一個供程式操作的儲存區的名字.在 C# 中, 每個變數都有一個特定的型別,型別決定了變數的記憶體大小和布 局.範圍內的值可以儲存在記憶體中,可以對變數進行一系列操作.
1. C# 中提供的基本的值型別大致可以分為以下幾類:
型別 | 舉例 |
---|---|
整數型別 | sbyte、byte、short、ushort、int、uint、long、ulong 和 char |
浮點型 | float 和 double |
十進位制型別 | decimal |
布林型別 | true 或 false 值,指定的值 |
空型別 | 可為空值的資料型別 |
C# 允許定義其他值型別的變數,比如 enum,也允許定義引用型別變數,比如 class.這些我們將在以後的章節中進行討論.在本章節中,我們只研究基本變數型別.
2. 變數的宣告
C#中變數定義的語法
<data_type> <variable_list>;
data_type:必須是一個有效的C# 資料型別,可以是 char、 int、float、double 或其他使用者自定義的資料型別.
variable_list:可以由一個或多個用逗號分隔的識別符號名稱組成.
一些有效的變數定義如下所示
int i, j, k;
char c, ch;
float f, salary;
double d;
3.變數的初始化
變數通過在等號後跟一個常量表達式進行初始化(賦值).
a. 變數初始化是C#強調安全性的另一種方式.簡單的說,C# 編譯器需要用某個初始值對變數進行初始化,之後才能在操作中引用該變數.大多數現代編譯器把未初始化標記為警告,但 C#編譯器把它當作錯誤來看待.這樣可以防止我們無意中從其他程式遺留下來的你記憶體中獲取垃圾值.
b. C#確保變數在使用前初始化的兩個方法
變數直接定義在類中或者結構中,如果沒有顯示初始化,那麼在建立變數的時候會有預設值
方法、事件內的變數必須在程式碼中顯示初始化,之後才能在語句中使用它們的值.此時初始化不是宣告該 變數時進行的,但編譯器會通過方法檢查所有可能的路徑,如果檢測到區域性變數在初始化之前就使用了他的值,直接報錯.
4. 變數的作用域
變數的作用域是可以訪問該變數的程式碼區域。一般情況下, 確定作用域遵循以下規則:
全域性變數:只要類在某個作用域內,其成員變數也在該作 用域內
區域性變數:存在於表示宣告該變數的塊級語句或方法結束 的大括號之前的作用域內
區域性變數:在 for、while 或類似語句中宣告的區域性變數存 在於該迴圈語句內 5
5.變數的作用域衝突
區域性變數,同一區域性內有至少兩個變數的變數名相同,那 麼程式編譯會報錯.
全域性變數,在同一個類裡面有至少兩個全域性變數的變數名相同,那麼程式編譯會報錯.
一個全域性變數和多個不同區域性的區域性變數的變數名相同,那麼變數遵循就近原則.
三. 常量
常量是固定值,程式執行期間不會改變.常量可以是任何 基本資料型別,比如整數常量、浮點常量、字元常量或者字串常量,還有列舉常量.
常量可以被當作常規的變數,只是它們的值在定義後不能被修改.
1. 整數常量
整數常量可以是十進位制、八進位制或十六進位制的常量.字首 指定基數:0x 或 0X 表示十六進位制,0 表示八進位制,沒有字首則表示十進位制.
整數常量也可以有後綴,可以是 U 和 L 的組合,其中, U 和 L 分別表示 unsigned 和 long.字尾可以是大寫或者小寫,多個字尾以任意順序進行組合.
2. 浮點常量
一個浮點常量是由整數部分、小數點、小數部分和指數部分組成.您可以使用小數形式或者指數形式來表示浮點常量.
使用小數形式表示時,必須包含小數點、指數或同時包含兩者.使用指數形式表示時,必須包含整數部分、小數部分或同時包含兩者.有符號的指數是用 e 或 E 表示的.
3. 字元常量
字元常量是括在單引號裡,例如,‘x’,且可儲存在一個簡 單的字元型別變數中.
一個字元常量可以是一個普通字元(例如 ‘x’)、一個轉 義序列(例如 ‘\t’)或者一個通用字元(例如 ‘\u02C0’).
在 C# 中有一些特定的字元,當它們的前面帶有反斜槓時 有特殊的意義,可用於表示換行符(\n)或製表符 tab(\t).在這裡,列出一些轉義序列碼:
4. 字串常量
字元常量是括在雙引號 “” 裡,或者是括在 @"" 裡.字串常量包含的字元與字元常量相似,可以是:普通字元、 轉義序列和通用字元
使用字串常量時,可以把一個很長的行拆成多個行,可以使用空格分隔各個部分.
5. 常量的宣告
常量是使用 const 關鍵字來定義的.定義一個常量的語法如下:
const <data_type> <constant_name> = value;
四. 計算機儲存資料
整數在計算機中儲存是以補碼的方式儲存的,想要知道補碼,必須先知道數字進位制轉換和原碼和反碼.
1. 不同進位制的組成和輸出
二進位制:以 0b 開頭,由 0 和 1 組成
八進位制:以 0 開頭,由 0-7 組。(C#中沒有現成的表示方式)
十進位制:預設就是十進位制,由 0-9 組成
十六進位制:以 0x 開頭,由 0-9+A-F 組成
2. 進位制之間的轉換演算法
其他進位制轉十進位制
√口訣:將所有的位上面的值進位制數的次方連起來既可以得到十進位制
√位值:每一個位數上面對應的值
√進位制數:本身是多少進位制,進位制數就是多少
√次方:從右向左,從 0 開始編號,對應位上面的編號就 是改位的次方
① 十進位制=》十進位制
1234=1000+200+30+4
=1103+2*102+31001+4*100=1234
② 二進位制=》十進位制
0b100100=125+0*24+023+1*22+021+0*20
=32+0+0+4+0+0=36
③八進位制=》十進位制
011223=184+1*83+282+2*81+38^0
=4096+512+128+16+3=4755
④十六進位制=》十進位制
0x11c0a=1164+1*163+12162+0*161+1016^0
=65536+4096+3072+0+10=72714
十進位制轉其他進位制
除以要轉換的進位制數,直至商為 0,餘數反轉
將 x 進位制轉成 y 進位制快速轉換法
√利用8421碼(將每個二進位制對應的位上計算一個固定的 十進位制數)
1 1 1 1 1 1 1 1
128 64 32 16 8 4 2 1
二進位制 2 位數組合
八進位制 3 位數組合
十六進位制 4 位數組合
例如: 將二進位制 0b100100 轉成 8 進位制
0b100100=>100 100=>4 4=44
將二進位制 0b100100 轉成 16 進位制
0b100100=>10 0100=>2 4=24
√以十進位制為橋樑
x 進位制>十進位制>y 進位制
3. 原碼
將一個整數轉換成二進位制,然後最高位用來表示符號位(0 表示正數,1 表示負數,其餘位表示數值位)
例如:7:00000111 -7:10000111
4. 反碼
正數的反碼和原碼一致,負數的反碼位數全部取反,除最高位
5. 補碼
正數的補碼和原碼一致,負數的補碼在反碼的基礎上末尾+1
6. 十進位制負整數轉二進位制演算法
將十進位制輸轉化成二進位制數,不管符號.
對轉化的二進位制數逐位取反.
對取反後的二進位制數加 1,結果就是十進位制負數轉化成的二進位制數.
7.二進位制負數轉十進位制演算法
對二進位制數逐位取反
對取反後的二進位制數加 1,加上負號,結果就是二進位制負數轉化成的十進位制數.