变量与数据类型
变量就像贴了标签的盒子——标签是名字,盒子装的是数据。选对盒子的尺寸和材质,才能安全高效地存储你的货物。
变量声明与初始化
C# 是强类型语言,声明变量时必须指定类型(或使用 var 让编译器推断):
int age;
age = 25;
string name = "Alice";
double score = 95.5;
也可以在同一行声明多个同类型变量:
int x = 1, y = 2, z = 3;
⚠️ C# 不允许使用未初始化的局部变量,编译器会报错。
命名规则
C# 对变量命名有严格规范:
- 必须以字母或
_开头,不能以数字开头 - 只能包含字母、数字和
_ - 区分大小写(
age和Age是不同变量) - 不能使用 C# 关键字(如
int、class、return)
camelCase 与 PascalCase
C# 有两套核心命名约定:
| 标识符类型 | 命名风格 | 示例 |
|---|---|---|
| 局部变量、字段 | camelCase | studentName、totalCount |
| 方法、类、属性 | PascalCase | CalculateSum、Student |
💡 camelCase:首单词小写,后续单词首字母大写;PascalCase:每个单词首字母都大写。
int studentAge = 18;
double averageScore = 87.5;
string homeAddress = "Beijing";
整数类型
C# 提供了 8 种整数类型,涵盖有符号和无符号:
| 类型 | 字节数 | 范围 | 后缀 |
|---|---|---|---|
sbyte |
1 | -128 ~ 127 | — |
byte |
1 | 0 ~ 255 | — |
short |
2 | -32,768 ~ 32,767 | — |
ushort |
2 | 0 ~ 65,535 | — |
int |
4 | -2,147,483,648 ~ 2,147,483,647 | — |
uint |
4 | 0 ~ 4,294,967,295 | U |
long |
8 | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | L |
ulong |
8 | 0 ~ 18,446,744,073,709,551,615 | UL |
💡 C# 与 Java 不同,C# 有无符号整数类型(byte、ushort、uint、ulong)。注意 C# 的 byte 是无符号的,而有符号的是 sbyte。
示例
sbyte sb = -100;
byte b = 200;
short s = -30000;
ushort us = 60000;
int i = 100000;
uint ui = 3000000000U;
long l = 9000000000000000000L;
ulong ul = 18000000000000000000UL;
Console.WriteLine($"sbyte: {sb}");
Console.WriteLine($"byte: {b}");
Console.WriteLine($"short: {s}");
Console.WriteLine($"ushort: {us}");
Console.WriteLine($"int: {i}");
Console.WriteLine($"uint: {ui}");
Console.WriteLine($"long: {l}");
Console.WriteLine($"ulong: {ul}");
sbyte: -100
byte: 200
short: -30000
ushort: 60000
int: 100000
uint: 3000000000
long: 9000000000000000000
ulong: 18000000000000000000
浮点类型
| 类型 | 字节数 | 精度 | 范围(约) | 后缀 | 适用场景 |
|---|---|---|---|---|---|
float |
4 | 7 位 | ±1.5×10⁻⁴⁵ ~ ±3.4×10³⁸ | f |
图形、游戏 |
double |
8 | 15-16 位 | ±5.0×10⁻³²⁴ ~ ±1.7×10³⁰⁸ | d(默认) |
科学计算 |
decimal |
16 | 28-29 位 | ±1.0×10⁻²⁸ ~ ±7.9×10²⁸ | m |
财务金额 |
⚠️ 小数字面量默认是 double 类型,赋值给 float 或 decimal 必须加后缀,否则编译报错。
float f = 3.14f;
double d = 3.14;
decimal m = 3.14m;
Console.WriteLine($"float: {f}");
Console.WriteLine($"double: {d}");
Console.WriteLine($"decimal: {m}");
float: 3.14
double: 3.14
decimal: 3.14
💡 decimal 专为金融计算设计,避免了二进制浮点误差。例如 0.1 + 0.2 在 double 下不精确等于 0.3,但在 decimal 下精确。
bool 类型
bool 只有两个值:true 和 false,占 1 字节。
⚠️ C# 的 bool 与 C 语言不同,不能与整数隐式转换——if(1) 是非法的,必须写 if(true) 或 if(x != 0)。
bool isReady = true;
bool isEmpty = false;
Console.WriteLine($"isReady: {isReady}");
Console.WriteLine($"isEmpty: {isEmpty}");
isReady: True
isEmpty: False
char 类型
C# 的 char 是 2 字节 Unicode 字符,不是 C 语言的 1 字节 ASCII。
char ch1 = 'A';
char ch2 = '\u4e2d';
Console.WriteLine($"ch1: {ch1}");
Console.WriteLine($"ch2: {ch2}");
Console.WriteLine($"ch1 code: {(int)ch1}");
Console.WriteLine($"ch2 code: {(int)ch2}");
ch1: A
ch2: 中
ch1 code: 65
ch2 code: 20013
💡 char 用单引号 'A',string 用双引号 "A"——两者完全不同。
string 类型
string 是引用类型,表示不可变的 Unicode 字符序列。
string greeting = "Hello";
string name = "World";
string message = greeting + ", " + name + "!";
Console.WriteLine(message);
Console.WriteLine($"Length: {message.Length}");
Hello, World!
Length: 13
⚠️ string 是引用类型,默认值是 null(不是空字符串 "")。访问 null 的字符串会抛出 NullReferenceException。
var 隐式类型
C# 3.0 引入 var 关键字,让编译器根据初始值推断类型:
var count = 42;
var price = 9.99m;
var label = "hello";
var flag = true;
Console.WriteLine(count.GetType().Name);
Console.WriteLine(price.GetType().Name);
Console.WriteLine(label.GetType().Name);
Console.WriteLine(flag.GetType().Name);
Int32
Decimal
String
Boolean
⚠️ var 不是"任意类型"——变量类型在编译期就已确定,且必须初始化。以下写法是非法的:
var x;
var x = null;
💡 var 适合类型名很长或类型显而易见的场景,不要滥用以免降低可读性。
sizeof 查看类型大小
sizeof 返回类型占用的字节数。对于基本类型可直接使用,其他类型需要 unsafe 上下文。
示例
Console.WriteLine($"sbyte: {sizeof(sbyte)} bytes");
Console.WriteLine($"byte: {sizeof(byte)} bytes");
Console.WriteLine($"short: {sizeof(short)} bytes");
Console.WriteLine($"ushort: {sizeof(ushort)} bytes");
Console.WriteLine($"int: {sizeof(int)} bytes");
Console.WriteLine($"uint: {sizeof(uint)} bytes");
Console.WriteLine($"long: {sizeof(long)} bytes");
Console.WriteLine($"ulong: {sizeof(ulong)} bytes");
Console.WriteLine($"float: {sizeof(float)} bytes");
Console.WriteLine($"double: {sizeof(double)} bytes");
Console.WriteLine($"decimal: {sizeof(decimal)} bytes");
Console.WriteLine($"char: {sizeof(char)} bytes");
Console.WriteLine($"bool: {sizeof(bool)} bytes");
sbyte: 1 bytes
byte: 1 bytes
short: 2 bytes
ushort: 2 bytes
int: 4 bytes
uint: 4 bytes
long: 8 bytes
ulong: 8 bytes
float: 4 bytes
double: 8 bytes
decimal: 16 bytes
char: 2 bytes
bool: 1 bytes
const 常量
用 const 声明编译期常量,值不可更改,声明时必须初始化:
const double Pi = 3.14159265358979;
const int MaxRetry = 3;
const string AppName = "MyApp";
Console.WriteLine($"Pi = {Pi}");
Console.WriteLine($"MaxRetry = {MaxRetry}");
Console.WriteLine($"AppName = {AppName}");
Pi = 3.14159265358979
MaxRetry = 3
AppName = MyApp
⚠️ const 常量命名通常使用 PascalCase。const 值必须在编译期可确定,不能是变量或方法调用的结果。
📌 如果需要运行时确定的"常量",请使用 readonly 字段。
类型默认值
每种类型在不赋初值时都有默认值:
| 类型 | 默认值 |
|---|---|
sbyte / byte / short / ushort / int / uint / long / ulong |
0 |
float |
0.0f |
double |
0.0d |
decimal |
0.0m |
char |
'\0' |
bool |
false |
string |
null |
| 任意引用类型 | null |
示例
int defaultInt = default;
bool defaultBool = default;
char defaultChar = default;
string defaultString = default;
double defaultDouble = default;
Console.WriteLine($"int: [{defaultInt}]");
Console.WriteLine($"bool: [{defaultBool}]");
Console.WriteLine($"char: [{(int)defaultChar}]");
Console.WriteLine($"string: [{defaultString}]");
Console.WriteLine($"double: [{defaultDouble}]");
int: [0]
bool: [False]
char: [0]
string: []
double: [0]
💡 default 关键字可获取任意类型的默认值,泛型中尤其常用:default(T)。
值类型与引用类型初识
C# 的类型分为两大类:
| 类别 | 存储 | 赋值行为 | 典型类型 |
|---|---|---|---|
| 值类型 | 栈(通常) | 复制值 | int、bool、char、decimal、struct、enum |
| 引用类型 | 堆 | 复制引用(地址) | string、class、object、数组 |
int a = 10;
int b = a;
b = 20;
Console.WriteLine($"a = {a}, b = {b}");
string s1 = "hello";
string s2 = s1;
s2 = "world";
Console.WriteLine($"s1 = {s1}, s2 = {s2}");
a = 10, b = 20
s1 = hello, s2 = world
⚠️ 上面 s1 没有变成 "world",是因为 string 具有不可变性——s2 = "world" 并非修改原对象,而是让 s2 指向了新对象。值类型赋值是真正的值复制,引用类型赋值是引用复制,但 string 的不可变性使它看起来像值类型。
❓ 常见问题
var 和 dynamic 有什么区别?var 在编译期确定类型,类型安全;dynamic 在运行时解析,无编译期类型检查,性能较低且容易出错。decimal 比 double 更适合金额计算?decimal 采用十进制存储,0.1 可以精确表示;double 采用二进制存储,0.1 无法精确表示,会产生累积误差。string 是值类型还是引用类型?string 是引用类型,但因为不可变性,赋值时表现为"值语义"——修改一个变量不影响另一个。const 和 readonly 的区别?const 是编译期常量,声明时必须赋值,隐式 static;readonly 是运行时常量,可在构造函数中赋值,每个实例可以不同。📖 小节
- C# 是强类型语言,变量必须声明类型或使用
var推断 - 局部变量用 camelCase,方法和类用 PascalCase
- 整数有 8 种类型(含无符号),
int是最常用的 - 浮点类型选
decimal做金额,double做科学计算,float做图形 bool不能与整数隐式转换,char是 2 字节 Unicodevar必须初始化,类型在编译期确定const定义编译期常量(PascalCase),readonly定义运行时常量default关键字可获取任意类型的默认值- 值类型赋值复制值,引用类型赋值复制引用
📝 作业
- 声明一个
int变量age并赋值为你的年龄,再声明一个string变量name并赋值为你的名字,输出两者 - 分别用
float、double、decimal计算0.1 + 0.2,对比输出结果是否精确等于0.3 - 使用
sizeof打印int、double、char、bool的字节数 - 声明一个
const double Pi = 3.14159265,计算半径为 5 的圆面积并输出 - 使用
default关键字获取int、bool、char、string的默认值并输出



