C#:整数类型详解

整数类型是什么

整数类型用于存储整数(没有小数部分的数字),包括正整数、负整数和零。

整数类型分类

根据取值范围的不同,C#提供了八种整数类型:

类型 术语 大小 范围 后缀 默认值
sbyte 字节整型 1字节(8位) -128 到 127 0
byte 字节整型 1字节(8位) 0 到 255 0
short 短整型 2字节(16位) -32,76832,767 0
ushort 短整型 2字节(16位) 065,535 0
int 整型 4字节(32位) -2,147,483,648 到 2,147,483,647 0
uint 整型 4字节(32位) 0 到 4,294,967,295 u/U 0
long 长整型 8字节(64位) -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 l/L 0L
ulong 长整型 8字节(64位) 0 到 18,446,744,073,709,551,615 ul/UL 0UL

声明整型的语法

sbyte(8位有符号整数):

  sbyte mySByte = -100;

byte(8位无符号整数):

  byte myByte = 200;

short(16位有符号整数):

  short myShort = -10000;

ushort(16位无符号整数):

  ushort myUShort = 30000;

int(32位有符号整数):

  int myInt = 1000000;

声明整型的语法(后缀)

声明uint(32位无符号整数):

  uint myUInt = 2000000000;
  uint myUInt = 2000000000U;

声明long(64位有符号整数):

  long myLong = 1000000000000;
   long myLong = 1000000000000L;

声明ulong(64位无符号整数):

  ulong myULong = 1000000000000000000;
  ulong myULong = 1000000000000000000UL;

关于添加后缀的原因

C# 编译器默认将整数字面量视为 int 类型(32 位有符号整数),如2000000000默认被视为“int”类型,不加后缀会导致编译错误:"整数太大,无法用 int 类型表示"。

  • U:当数字较大时(接近或超过20亿),需要明确指定为无符号整数类型,这就是使用U后缀的原因。
  • L:后缀显式告诉编译器:"这是 long 类型"。提高代码可读性,明确表示处理大数字。
// 错误写法(不加L)
long myLong = 1000000000000; // 编译错误:数字太大

// 正确写法(加L后缀)
long myLong = 1000000000000L; // 正确

byte与int比较

在 C# 中存储年龄时,选择 byte 还是 int 取决于具体场景和需求。下面我将详细分析两种选择的优缺点,并提供实际建议。

对比分析表

特性 byte (推荐) int (常用)
内存占用 1字节 ✅ 4字节 ❌
取值范围 0-255 (0-120 完全覆盖) ✅ -20亿到+20亿 (远超需求) ❌
性能影响 微小优势 ✅ 良好 ⚠️
类型转换 需要显式转换 ❌ 无需转换 ✅
代码可读性 明确表示小范围数值 ✅ 通用但不够精确 ⚠️
默认类型兼容 不兼容大多数API ❌ 完美兼容 ✅
最佳适用场景 内存敏感应用、大数据集 通用开发、初学阶段

使用 byte 的优势

byte age = 25; // 明确表示年龄是小范围值,推荐首选

优点

  • 内存高效:1字节 vs int的4字节(节省75%内存)

  • 范围精确:0-255 完美覆盖人类年龄范围(0-120)

  • 语义明确:清晰表明这是小范围非负整数

  • 大数据优势:存储百万用户年龄可节省约 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 的优势

int age = 25; // 默认整数类型,传统选择

优点

  • 无需转换:直接用于数学运算
  • API兼容:完美匹配大多数框架方法
  • 开发便捷:初学者友好
  • 范围安全:永不溢出(对年龄而言)

缺点

  • 内存浪费(每个年龄多占3字节)
  • 语义不够精确(可表示负数和极大值)

使用场景

INT使用场景

日常使用优先默认选择int:除非有特殊需求,否则优先使用int

  • 大多数API使用int
  • 性能最佳(32位系统优化)
  • 范围足够日常使用(±21亿)

BYTE使用场景

内存敏感场景使用byte/sbyte 如:

  • 大型数组
  • 如图像处理
  • 网络传输:使用最小必要类型
byte[] imageData = new byte[1024 * 1024]; // 1MB

LONG使用场景

需要大范围整数使用long(最大支持9EB)或ulong,如:

  • 文件大小
  • 科学计算
long fileSize = 15L * 1024 * 1024 * 1024; // 15GB

UINT使用场景

无符号数仅无符号数场景,使用uint,如:

  • 颜色值(ARGB):
uint color = 0xFFAABBCC; // 带透明度的颜色值
  • 位掩码操作:uint/ulong
const uint ReadPermission = 0b0001;
const uint WritePermission = 0b0010;
uint userPermissions = ReadPermission | WritePermission;
  1. 类型转换时注意范围检查
  2. 使用数字分隔符提高大数可读性
  3. 涉及金融计算时使用decimal而非整数类型

数字分隔符

c#允许在数字字面量中使用下划线 _ 作为分隔符以提高代码可读性。

long bigNumber = 9_223_372_036_854_775_807; // 提高可读性
  • 数字分隔符 _ 仅用于提升代码可读性
  • 编译时会完全忽略。
  • 不改变数值的实际大小

使用规则

1.除去首尾,可在一个整数的任意位置添加分割符

int valid = 123_456;            // ✅ 合法
int invalid = _123;             // ❌ 错误:不能在开头
int invalid = 123_;             // ❌ 错误:不能在结尾

2.可以连续使用两个下划线,禁止连续使用三个下划线

int valid = 1__2__3;           // ✅ 合法(但建议避免过度使用)
int invalid = 1___23;          // ❌ 错误:连续三个下划线

3.分隔符兼容各种进制

int dec = 1_000_000;            // ✅ 十进制整数
double flt = 1_000.000_001;     // ✅ 浮点数
decimal mon = 1_000_000.99m;    // ✅ 十进制数
int hex = 0xDEAD_BEEF;          // ✅ 十六进制
int bin = 0b1010_0101_1100;     // ✅ 二进制

常见应用场景

// 大数值分段
long worldPopulation = 8045311447; // 难以阅读
long worldPopulation = 8_045_311_447; // 立即理解为"80亿"

//浮点数分段
double pi = 3.141_592_653_589_793;// π 的近似值

//金融数值
decimal nationalDebt = 31_456_932_742_893.27m;// 百万美元金额

//二进制
uint ipMask = 0b1111_1111_1111_1111_0000_0000_0000_0000;// IP地址掩码

//十六进制数据分组
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后缀在下划线后
   
//科学计数法:
double avogadro = 6.022_140_857e23; // ✅ 下划线在指数部分前
 

分组策略:

  • 十进制:每3位分组(千位分隔)
  • 十六进制:每4位分组(半字节/nibble)
  • 二进制:每4位或8位分组

一致性原则:

int x = 10_0000;  // 混合分组不一致(不推荐)
int x = 100_000;  // 标准千位分隔,(推荐)

避免过度使用:

int overSeparated = 1_0_0_0_0; // 过度分隔(不推荐)
int readable = 100_000;// 适度分隔(推荐)

整数的除法运算

整数除法会导致小数点被截断的行为。

示例

int n = 10 / 3;
Console.Write(n); //结果是3,而不是3.333333333

代码行为分析

  • 操作数103 都是 int 类型。 int / int,输出仍是 int类型未改变
  • 运算规则:当两个整数相除时,C# 执行整数除法,结果仍是 int 类型,小数部分直接丢弃(不是四舍五入)。
  • 结果10 / 3 = 3(余数 1 被丢弃)。

示例:隐式转换

double n = 10 / 3;
Console.Write(n); //结果是3.0,而不是3。此时发生了**隐式转换**(`int` → `double`),但除法本身仍是整数除法。

示例:浮点数结果

double correct1 = 10.0 / 3;  // 10.0 是 double,触发浮点除法 → 3.333...
double correct2 = 10 / 3.0;  // 3.0 是 double → 3.333...
double correct3 = (double)10 / 3; // 显式转换其中一个操作数

示例:decimal 的除法
decimal 会保留小数,但必须所有操作数都是 decimal

decimal n = 10m / 3m;  // 结果是 3.3333333333333333333333333333

总结

代码 运算类型 结果 是否涉及转换
int n = 10 / 3; 整数除法 3 ❌ 否
double n = 10 / 3; 整数除法 + 隐式转换 3.0 ✅ 是(结果转换)
double n = 10.0 / 3; 浮点除法 3.333... ❌ 否(操作数类型提升)

问题及修正方法

问题类型 修正方法
整数除法截断 至少一个操作数转为 double/decimal
浮点数精度问题 使用 doubledecimal
输入安全处理 TryParse 替代 Parse
四舍五入需求 使用 Math.Round
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容