整數(shù)類型是什么
整數(shù)類型用于存儲整數(shù)(沒有小數(shù)部分的數(shù)字),包括正整數(shù)、負整數(shù)和零。
整數(shù)類型分類
根據取值范圍的不同,C#提供了八種整數(shù)類型:
| 類型 | 術語 | 大小 | 范圍 | 后綴 | 默認值 |
|---|---|---|---|---|---|
| sbyte | 字節(jié)整型 | 1字節(jié)(8位) | -128 到 127 | 0 | |
| byte | 字節(jié)整型 | 1字節(jié)(8位) | 0 到 255 | 0 | |
| short | 短整型 | 2字節(jié)(16位) |
-32,768 到 32,767
|
0 | |
| ushort | 短整型 | 2字節(jié)(16位) |
0 到 65,535
|
0 | |
| int | 整型 | 4字節(jié)(32位) | -2,147,483,648 到 2,147,483,647 | 0 | |
| uint | 整型 | 4字節(jié)(32位) | 0 到 4,294,967,295 | u/U | 0 |
| long | 長整型 | 8字節(jié)(64位) | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | l/L | 0L |
| ulong | 長整型 | 8字節(jié)(64位) | 0 到 18,446,744,073,709,551,615 | ul/UL | 0UL |
聲明整型的語法
sbyte(8位有符號整數(shù)):
sbyte mySByte = -100;
byte(8位無符號整數(shù)):
byte myByte = 200;
short(16位有符號整數(shù)):
short myShort = -10000;
ushort(16位無符號整數(shù)):
ushort myUShort = 30000;
int(32位有符號整數(shù)):
int myInt = 1000000;
聲明整型的語法(后綴)
聲明uint(32位無符號整數(shù)):
uint myUInt = 2000000000;
uint myUInt = 2000000000U;
聲明long(64位有符號整數(shù)):
long myLong = 1000000000000;
long myLong = 1000000000000L;
聲明ulong(64位無符號整數(shù)):
ulong myULong = 1000000000000000000;
ulong myULong = 1000000000000000000UL;
關于添加后綴的原因
C# 編譯器默認將整數(shù)字面量視為 int 類型(32 位有符號整數(shù)),如2000000000默認被視為“int”類型,不加后綴會導致編譯錯誤:"整數(shù)太大,無法用 int 類型表示"。
- U:當數(shù)字較大時(接近或超過20億),需要明確指定為無符號整數(shù)類型,這就是使用U后綴的原因。
- L:后綴顯式告訴編譯器:"這是 long 類型"。提高代碼可讀性,明確表示處理大數(shù)字。
// 錯誤寫法(不加L)
long myLong = 1000000000000; // 編譯錯誤:數(shù)字太大
// 正確寫法(加L后綴)
long myLong = 1000000000000L; // 正確
byte與int比較
在 C# 中存儲年齡時,選擇 byte 還是 int 取決于具體場景和需求。下面我將詳細分析兩種選擇的優(yōu)缺點,并提供實際建議。
對比分析表
| 特性 | byte (推薦) | int (常用) |
|---|---|---|
| 內存占用 | 1字節(jié) ? | 4字節(jié) ? |
| 取值范圍 | 0-255 (0-120 完全覆蓋) ? | -20億到+20億 (遠超需求) ? |
| 性能影響 | 微小優(yōu)勢 ? | 良好 ?? |
| 類型轉換 | 需要顯式轉換 ? | 無需轉換 ? |
| 代碼可讀性 | 明確表示小范圍數(shù)值 ? | 通用但不夠精確 ?? |
| 默認類型兼容 | 不兼容大多數(shù)API ? | 完美兼容 ? |
| 最佳適用場景 | 內存敏感應用、大數(shù)據集 | 通用開發(fā)、初學階段 |
使用 byte 的優(yōu)勢
byte age = 25; // 明確表示年齡是小范圍值,推薦首選
優(yōu)點:
內存高效:1字節(jié) vs int的4字節(jié)(節(jié)省75%內存)
范圍精確:0-255 完美覆蓋人類年齡范圍(0-120)
語義明確:清晰表明這是小范圍非負整數(shù)
-
大數(shù)據優(yōu)勢:存儲百萬用戶年齡可節(jié)省約 2.86MB 內存
// 100萬用戶年齡存儲 byte[] agesByte = new byte[1_000_000]; // 占用 0.95 MB int[] agesInt = new int[1_000_000]; // 占用 3.81 MB
缺點:
- 需要顯式類型轉換
- 不兼容期望int類型的API
- 超出255會拋出異常
使用 int 的優(yōu)勢
int age = 25; // 默認整數(shù)類型,傳統(tǒng)選擇
優(yōu)點:
- 無需轉換:直接用于數(shù)學運算
- API兼容:完美匹配大多數(shù)框架方法
- 開發(fā)便捷:初學者友好
- 范圍安全:永不溢出(對年齡而言)
缺點:
- 內存浪費(每個年齡多占3字節(jié))
- 語義不夠精確(可表示負數(shù)和極大值)
使用場景
INT使用場景
日常使用優(yōu)先默認選擇int:除非有特殊需求,否則優(yōu)先使用int
- 大多數(shù)API使用int
- 性能最佳(32位系統(tǒng)優(yōu)化)
- 范圍足夠日常使用(±21億)
BYTE使用場景
內存敏感場景使用byte/sbyte 如:
- 大型數(shù)組
- 如圖像處理
- 網絡傳輸:使用最小必要類型
byte[] imageData = new byte[1024 * 1024]; // 1MB
LONG使用場景
需要大范圍整數(shù)使用long(最大支持9EB)或ulong,如:
- 文件大小
- 科學計算
long fileSize = 15L * 1024 * 1024 * 1024; // 15GB
UINT使用場景
無符號數(shù)僅無符號數(shù)場景,使用uint,如:
- 顏色值(ARGB):
uint color = 0xFFAABBCC; // 帶透明度的顏色值
- 位掩碼操作:uint/ulong
const uint ReadPermission = 0b0001;
const uint WritePermission = 0b0010;
uint userPermissions = ReadPermission | WritePermission;
- 類型轉換時注意范圍檢查
- 使用數(shù)字分隔符提高大數(shù)可讀性
- 涉及金融計算時使用
decimal而非整數(shù)類型
數(shù)字分隔符
c#允許在數(shù)字字面量中使用下劃線 _ 作為分隔符以提高代碼可讀性。
long bigNumber = 9_223_372_036_854_775_807; // 提高可讀性
- 數(shù)字分隔符 _ 僅用于提升代碼可讀性
- 編譯時會完全忽略。
- 不改變數(shù)值的實際大小
使用規(guī)則
1.除去首尾,可在一個整數(shù)的任意位置添加分割符
int valid = 123_456; // ? 合法
int invalid = _123; // ? 錯誤:不能在開頭
int invalid = 123_; // ? 錯誤:不能在結尾
2.可以連續(xù)使用兩個下劃線,禁止連續(xù)使用三個下劃線
int valid = 1__2__3; // ? 合法(但建議避免過度使用)
int invalid = 1___23; // ? 錯誤:連續(xù)三個下劃線
3.分隔符兼容各種進制
int dec = 1_000_000; // ? 十進制整數(shù)
double flt = 1_000.000_001; // ? 浮點數(shù)
decimal mon = 1_000_000.99m; // ? 十進制數(shù)
int hex = 0xDEAD_BEEF; // ? 十六進制
int bin = 0b1010_0101_1100; // ? 二進制
常見應用場景
// 大數(shù)值分段
long worldPopulation = 8045311447; // 難以閱讀
long worldPopulation = 8_045_311_447; // 立即理解為"80億"
//浮點數(shù)分段
double pi = 3.141_592_653_589_793;// π 的近似值
//金融數(shù)值
decimal nationalDebt = 31_456_932_742_893.27m;// 百萬美元金額
//二進制
uint ipMask = 0b1111_1111_1111_1111_0000_0000_0000_0000;// IP地址掩碼
//十六進制數(shù)據分組
int transparentRed = 0x80_FF_00_00;// 顏色值(ARGB)
// 電話號碼
long customerPhone = 1_800_555_1212;
// 產品代碼
ulong productCode = 12_3456_7890_1234_5678;
//分隔符與類型后綴:
long big = 1_000_000_000_000L; // ? L后綴在下劃線后
//科學計數(shù)法:
double avogadro = 6.022_140_857e23; // ? 下劃線在指數(shù)部分前
分組策略:
- 十進制:每3位分組(千位分隔)
- 十六進制:每4位分組(半字節(jié)/nibble)
- 二進制:每4位或8位分組
一致性原則:
int x = 10_0000; // 混合分組不一致(不推薦)
int x = 100_000; // 標準千位分隔,(推薦)
避免過度使用:
int overSeparated = 1_0_0_0_0; // 過度分隔(不推薦)
int readable = 100_000;// 適度分隔(推薦)
整數(shù)的除法運算
整數(shù)除法會導致小數(shù)點被截斷的行為。
示例
int n = 10 / 3;
Console.Write(n); //結果是3,而不是3.333333333
代碼行為分析
-
操作數(shù):
10和3都是int類型。int / int,輸出仍是int,類型未改變。 -
運算規(guī)則:當兩個整數(shù)相除時,C# 執(zhí)行整數(shù)除法,結果仍是
int類型,小數(shù)部分直接丟棄(不是四舍五入)。 -
結果:
10 / 3 = 3(余數(shù) 1 被丟棄)。
示例:隱式轉換
double n = 10 / 3;
Console.Write(n); //結果是3.0,而不是3。此時發(fā)生了**隱式轉換**(`int` → `double`),但除法本身仍是整數(shù)除法。
示例:浮點數(shù)結果
double correct1 = 10.0 / 3; // 10.0 是 double,觸發(fā)浮點除法 → 3.333...
double correct2 = 10 / 3.0; // 3.0 是 double → 3.333...
double correct3 = (double)10 / 3; // 顯式轉換其中一個操作數(shù)
示例:decimal 的除法
decimal 會保留小數(shù),但必須所有操作數(shù)都是 decimal:
decimal n = 10m / 3m; // 結果是 3.3333333333333333333333333333
總結
| 代碼 | 運算類型 | 結果 | 是否涉及轉換 |
|---|---|---|---|
int n = 10 / 3; |
整數(shù)除法 | 3 |
? 否 |
double n = 10 / 3; |
整數(shù)除法 + 隱式轉換 | 3.0 |
? 是(結果轉換) |
double n = 10.0 / 3; |
浮點除法 | 3.333... |
? 否(操作數(shù)類型提升) |
問題及修正方法
| 問題類型 | 修正方法 |
|---|---|
| 整數(shù)除法截斷 | 至少一個操作數(shù)轉為 double/decimal
|
| 浮點數(shù)精度問題 | 使用 double 或 decimal
|
| 輸入安全處理 | 用 TryParse 替代 Parse
|
| 四舍五入需求 | 使用 Math.Round
|