本篇核心知识点C# 内存划分栈 / 堆、unsafe 指针使用规范、值类型 引用类型、装箱拆箱、类型转换隐式 / 显式、变量、常量、readonly 只读、字符串转义与 原生字符串、运算符算术 / 关系 / 逻辑 / 位 / 赋值 / 三元、浮点精度坑、短路运算、流程控制if/switch/for/while/do-while一、C# 内存分区与指针相关1. 栈内存、堆内存划分概念栈 (Stack)自动分配释放函数执行结束自动回收存放值类型变量、局部变量、函数形参堆 (Heap)手动 GC 垃圾回收管理存放引用类型对象特性值类型变量直接存储数据本体存栈引用类型变量仅存堆内存地址真实数据存堆多个引用变量存同一地址修改一处所有变量同步变化。2. unsafe 不安全代码与指针概念C# 默认安全托管环境禁止直接操作原生指针如需使用 C/C 风格指针必须开启不安全代码。使用步骤项目设置VS 项目属性→生成→勾选「允许不安全代码」代码用unsafe修饰代码块 / 函数特性语法与 C 指针完全一致支持*解引用、取地址sizeof获取类型字节大小仅能放在 unsafe 块内日常开发极少使用面试常提问「C# 是否支持指针」。代码示例unsafe void TestPointer() { int a 10; int* p a; // 取地址 Console.WriteLine(*p); // 解引用取值 Console.WriteLine(sizeof(int)); // int占4字节 }二、值类型 引用类型2.1 值类型概念派生自System.ValueType数据直接存储在栈内存赋值时完整拷贝一份数据副本。包含类型bool、char、byte/sbyte、short/ushort、int/uint、long/ulong、float (32 位单精度)、double (64 位双精度)、enum 枚举、struct 结构体。特性1 赋值互不干扰修改副本不影响原变量2 函数传参默认值拷贝内部修改不会影响外部实参3 内存自动回收无 GC 开销。2.2 引用类型概念变量仅保存堆内存地址真实数据存堆赋值仅拷贝地址多个变量指向同一块数据。包含类型object、string、自定义 class、dynamic 动态类型、数组、集合 List 等。特性1 赋值共享同一份堆数据一处修改全部同步2 依靠垃圾回收 GC 释放堆内存3 string 特殊字符串不可变修改会生成新堆对象。3. 装箱 拆箱面试高频1装箱概念栈内值类型拷贝到堆转为object引用类型隐式自动转换。内存变化栈复制数据→堆开辟 object 包装。int num 10; object obj num; // 自动装箱2拆箱概念堆中 object 转回栈内值类型必须强制显式转换转换类型不匹配报错。int res (int)obj; // 强制拆箱拓展频繁装箱拆箱会产生大量堆临时对象GC 压力大高性能游戏项目尽量避免。三、类型转换3.1 隐式转换自动转换概念编译器自动完成无需强转小范围 / 低精度 → 大范围 / 高精度无数据丢失风险。示例规则int → long / int → double易错点double num 8.0; float f num;编译报错double 精度高于 float无法隐式转 float浮点常量默认 double单精度必须后缀ffloat f 5.5f;3.2 显式强制转换概念 大范围→小范围手动强制转换存在精度丢失、数值溢出风险double d 3.14; int i (int)d; // 强制截断小数3.3 内置转换工具类Convert.ToBoolean() / Convert.ToByte() / Convert.ToInt32()等可实现字符串、任意基础类型互转字符串转数字必须用Convert.ToInt32(123)C# 无 JS/TS 隐式数字转换。四、变量、常量、只读 readonly4.1 变量概念内存空间别名必须显式指定类型强类型运行中可修改值。作用域由{}代码块决定1 局部变量方法 / 循环 /if 内部仅当前代码块有效出块销毁2 成员变量写在类内部、方法外部整个类所有方法可访问3 静态 static 变量类变量不依赖对象类名直接访问。左值 / 右值左值可放在赋值号左边变量右值仅能读取、不可赋值常量、表达式结果。4.2 常量 const概念编译期确定固定值定义时必须初始化全程不可修改。特性1 关键字const修饰2 仅支持基础值类型3 类中常量直接类名访问无需实例const int MAX_HP 1000;4.3 readonly 只读概念运行时赋值构造函数内可改构造完毕后永久只读。区别 constconst 编译期定值readonly 运行期赋值支持对象类型单例模式高频使用。五、字符串两种写法与转义字符1 普通双引号字符串支持\n换行、\t制表、\\反斜杠等转义字符。string str D:\\Game\\test.txt;2 原生字符串前缀所有反斜杠不再转义路径、SQL 语句专用。string path D:\Game\test.txt;拓展字符串是引用类型但具备值语义修改会新建堆对象不会修改原字符串。六、运算符全分类与易错点6.1 算术运算符 - * / % --1 自增i先加再运算i先运算后加2 取模%仅整数适用3 浮点除法5 / 2.0结果 2.5整数相除5/2直接截断得 2。6.2 关系运算符 !重点易错浮点数不能直接判等浮点数存储存在精度误差如 3.4 实际存储为 3.3999999直接大概率判断失败。标准写法取绝对值差值小于极小阈值即判定相等double a 3.4; double b 3.4; if(Math.Abs(a - b) 1e-6) Console.WriteLine(相等);6.3 逻辑运算符 || !短路运算短路规则1左边条件 false右侧代码完全不执行2||左边条件 true右侧代码完全不执行作用减少无意义运算提升性能。6.4 位运算符 | ^ ~ 游戏高频用途RGBA 颜色拆分、碰撞分组标记1按位与提取指定字节如取 RGB 红色通道color 0xFF2|按位或合并标记、叠加颜色通道3左移、右移等价乘 2 / 除 2效率极高。示例32 位 int 存储 RGBA 四色通道单字节 0~255。6.5 赋值运算符 - * / %等价简写a 5→a a 5Lua 等脚本无复合赋值运算符后期学习注意区分。6.6 三元条件运算符条件 ? 真值 : 假值唯一三目运算符简化 if-else 取值常用于取最大 / 最小值int min a b ? a : b;6.7 运算符优先级乘除 加减 位运算 关系 逻辑 三元 赋值复杂表达式建议括号提升可读性。七、流程控制语句7.1 if / else if / else易错规范if 条件后禁止加分号分号代表空语句逻辑失效// 错误写法 if(a 10); { }7.2 switch 分支规则1 case 后必须是常量不支持变量2 支持 int、char、字符串 string 常量3 每个 case 末尾建议加break无 break 会穿透到下一分支4 多个 case 执行同一段代码可堆叠 case5default所有分支不匹配时执行可选写6 case 内定义变量需包裹{}代码块防止重定义报错。int key 2; switch(key){ case 1: case 2: // 1、2执行相同逻辑 Console.WriteLine(选中); break; default: Console.WriteLine(无匹配); break; }7.3 循环语句 for /while/do-while1 for 循环格式for(初始化;条件;迭代)三部分用分号分隔循环变量仅循环内有效外部无法访问循环头禁止加分号。2 while 循环先判断条件不成立一次都不执行初始化写循环外部迭代写循环体内。3 do-while 循环先执行一次循环体再判断条件至少执行 1 次末尾必须加分号do {} while(条件);八、拓展工程 面试考点1 内存区分值栈引用堆、装箱拆箱原理必考题2 浮点数判等坑笔试高频改错3 短路运算、位运算游戏开发实际用途4 unsafe 指针使用前提项目设置 代码块修饰5 const 与 readonly 核心区别6 switch、if、for 通用代码书写规范规避语法陷阱。
C# 语言入门(二)内存机制、类型特性
本篇核心知识点C# 内存划分栈 / 堆、unsafe 指针使用规范、值类型 引用类型、装箱拆箱、类型转换隐式 / 显式、变量、常量、readonly 只读、字符串转义与 原生字符串、运算符算术 / 关系 / 逻辑 / 位 / 赋值 / 三元、浮点精度坑、短路运算、流程控制if/switch/for/while/do-while一、C# 内存分区与指针相关1. 栈内存、堆内存划分概念栈 (Stack)自动分配释放函数执行结束自动回收存放值类型变量、局部变量、函数形参堆 (Heap)手动 GC 垃圾回收管理存放引用类型对象特性值类型变量直接存储数据本体存栈引用类型变量仅存堆内存地址真实数据存堆多个引用变量存同一地址修改一处所有变量同步变化。2. unsafe 不安全代码与指针概念C# 默认安全托管环境禁止直接操作原生指针如需使用 C/C 风格指针必须开启不安全代码。使用步骤项目设置VS 项目属性→生成→勾选「允许不安全代码」代码用unsafe修饰代码块 / 函数特性语法与 C 指针完全一致支持*解引用、取地址sizeof获取类型字节大小仅能放在 unsafe 块内日常开发极少使用面试常提问「C# 是否支持指针」。代码示例unsafe void TestPointer() { int a 10; int* p a; // 取地址 Console.WriteLine(*p); // 解引用取值 Console.WriteLine(sizeof(int)); // int占4字节 }二、值类型 引用类型2.1 值类型概念派生自System.ValueType数据直接存储在栈内存赋值时完整拷贝一份数据副本。包含类型bool、char、byte/sbyte、short/ushort、int/uint、long/ulong、float (32 位单精度)、double (64 位双精度)、enum 枚举、struct 结构体。特性1 赋值互不干扰修改副本不影响原变量2 函数传参默认值拷贝内部修改不会影响外部实参3 内存自动回收无 GC 开销。2.2 引用类型概念变量仅保存堆内存地址真实数据存堆赋值仅拷贝地址多个变量指向同一块数据。包含类型object、string、自定义 class、dynamic 动态类型、数组、集合 List 等。特性1 赋值共享同一份堆数据一处修改全部同步2 依靠垃圾回收 GC 释放堆内存3 string 特殊字符串不可变修改会生成新堆对象。3. 装箱 拆箱面试高频1装箱概念栈内值类型拷贝到堆转为object引用类型隐式自动转换。内存变化栈复制数据→堆开辟 object 包装。int num 10; object obj num; // 自动装箱2拆箱概念堆中 object 转回栈内值类型必须强制显式转换转换类型不匹配报错。int res (int)obj; // 强制拆箱拓展频繁装箱拆箱会产生大量堆临时对象GC 压力大高性能游戏项目尽量避免。三、类型转换3.1 隐式转换自动转换概念编译器自动完成无需强转小范围 / 低精度 → 大范围 / 高精度无数据丢失风险。示例规则int → long / int → double易错点double num 8.0; float f num;编译报错double 精度高于 float无法隐式转 float浮点常量默认 double单精度必须后缀ffloat f 5.5f;3.2 显式强制转换概念 大范围→小范围手动强制转换存在精度丢失、数值溢出风险double d 3.14; int i (int)d; // 强制截断小数3.3 内置转换工具类Convert.ToBoolean() / Convert.ToByte() / Convert.ToInt32()等可实现字符串、任意基础类型互转字符串转数字必须用Convert.ToInt32(123)C# 无 JS/TS 隐式数字转换。四、变量、常量、只读 readonly4.1 变量概念内存空间别名必须显式指定类型强类型运行中可修改值。作用域由{}代码块决定1 局部变量方法 / 循环 /if 内部仅当前代码块有效出块销毁2 成员变量写在类内部、方法外部整个类所有方法可访问3 静态 static 变量类变量不依赖对象类名直接访问。左值 / 右值左值可放在赋值号左边变量右值仅能读取、不可赋值常量、表达式结果。4.2 常量 const概念编译期确定固定值定义时必须初始化全程不可修改。特性1 关键字const修饰2 仅支持基础值类型3 类中常量直接类名访问无需实例const int MAX_HP 1000;4.3 readonly 只读概念运行时赋值构造函数内可改构造完毕后永久只读。区别 constconst 编译期定值readonly 运行期赋值支持对象类型单例模式高频使用。五、字符串两种写法与转义字符1 普通双引号字符串支持\n换行、\t制表、\\反斜杠等转义字符。string str D:\\Game\\test.txt;2 原生字符串前缀所有反斜杠不再转义路径、SQL 语句专用。string path D:\Game\test.txt;拓展字符串是引用类型但具备值语义修改会新建堆对象不会修改原字符串。六、运算符全分类与易错点6.1 算术运算符 - * / % --1 自增i先加再运算i先运算后加2 取模%仅整数适用3 浮点除法5 / 2.0结果 2.5整数相除5/2直接截断得 2。6.2 关系运算符 !重点易错浮点数不能直接判等浮点数存储存在精度误差如 3.4 实际存储为 3.3999999直接大概率判断失败。标准写法取绝对值差值小于极小阈值即判定相等double a 3.4; double b 3.4; if(Math.Abs(a - b) 1e-6) Console.WriteLine(相等);6.3 逻辑运算符 || !短路运算短路规则1左边条件 false右侧代码完全不执行2||左边条件 true右侧代码完全不执行作用减少无意义运算提升性能。6.4 位运算符 | ^ ~ 游戏高频用途RGBA 颜色拆分、碰撞分组标记1按位与提取指定字节如取 RGB 红色通道color 0xFF2|按位或合并标记、叠加颜色通道3左移、右移等价乘 2 / 除 2效率极高。示例32 位 int 存储 RGBA 四色通道单字节 0~255。6.5 赋值运算符 - * / %等价简写a 5→a a 5Lua 等脚本无复合赋值运算符后期学习注意区分。6.6 三元条件运算符条件 ? 真值 : 假值唯一三目运算符简化 if-else 取值常用于取最大 / 最小值int min a b ? a : b;6.7 运算符优先级乘除 加减 位运算 关系 逻辑 三元 赋值复杂表达式建议括号提升可读性。七、流程控制语句7.1 if / else if / else易错规范if 条件后禁止加分号分号代表空语句逻辑失效// 错误写法 if(a 10); { }7.2 switch 分支规则1 case 后必须是常量不支持变量2 支持 int、char、字符串 string 常量3 每个 case 末尾建议加break无 break 会穿透到下一分支4 多个 case 执行同一段代码可堆叠 case5default所有分支不匹配时执行可选写6 case 内定义变量需包裹{}代码块防止重定义报错。int key 2; switch(key){ case 1: case 2: // 1、2执行相同逻辑 Console.WriteLine(选中); break; default: Console.WriteLine(无匹配); break; }7.3 循环语句 for /while/do-while1 for 循环格式for(初始化;条件;迭代)三部分用分号分隔循环变量仅循环内有效外部无法访问循环头禁止加分号。2 while 循环先判断条件不成立一次都不执行初始化写循环外部迭代写循环体内。3 do-while 循环先执行一次循环体再判断条件至少执行 1 次末尾必须加分号do {} while(条件);八、拓展工程 面试考点1 内存区分值栈引用堆、装箱拆箱原理必考题2 浮点数判等坑笔试高频改错3 短路运算、位运算游戏开发实际用途4 unsafe 指针使用前提项目设置 代码块修饰5 const 与 readonly 核心区别6 switch、if、for 通用代码书写规范规避语法陷阱。