24.C#入门语法知识总结

24.总结


24.1 知识点

学习的主要内容

总结讲什么

为什么要讲练结合

如何培养良好的学习习惯

如何快速的提升编程能力


24.2 核心要点速览

输入输出操作

API 作用 返回值 示例
Console.WriteLine 输出文本并换行 Console.WriteLine("Hello");
Console.Write 输出文本但不换行 Console.Write("Hello");
Console.ReadLine 读取一行用户输入 string string s = Console.ReadLine();
Console.ReadKey 读取单个按键 ConsoleKeyInfo ConsoleKeyInfo k = Console.ReadKey();

注释

三种注释:单行 //、块 /* ... */、文档 ///(用于类/方法说明)。

代码分组

#region 折叠代码块,便于阅读长文件。

#region 变量声明
int a = 1;
int b = 2;
#endregion

注意:仅编辑器功能,编译时会被忽略。

基础变量类型

分类 类型 位数 取值范围 说明
有符号整型 sbyte 8位 -128 ~ 127
short 16位 -3万多 ~ 3万多
int 32位 -21亿多 ~ 21亿多 最常用
long 64位 -9百万兆 ~ 9百万兆
无符号整型 byte 8位 0 ~ 255
ushort 16位 0 ~ 6万多
uint 32位 0 ~ 42亿多
ulong 64位 0 ~ 18百万兆
浮点数 float 32位 7-8位有效数字,需加f后缀
double 64位 15-17位有效数字,默认小数类型
decimal 128位 27-28位有效数字,适合金钱计算
布尔 bool 8位 true/false
字符 char 16位 单个字符 'A''中'
字符串 string 不定 引用类型,不可变

选择建议

  • 整数用 int,不够用 long
  • 小数用 double,需要高精度用 decimal
  • 判断用 bool
  • 单字符用 char,文本用 string

获取类型内存大小

sizeof 获取类型占用的字节数。

Console.WriteLine(sizeof(int));     // 4
Console.WriteLine(sizeof(double));  // 8

注意:不能用于 string(长度不固定)。

变量命名规则

必须遵守

  • 不能重名
  • 不能以数字开头
  • 不能用关键字(如 intstring
  • 不能有特殊符号(下划线_除外)

建议规范

命名法 格式 用途 示例
驼峰命名法 首字母小写,后续单词首字母大写 变量 userNametotalCount
帕斯卡命名法 每个单词首字母都大写 类名、方法名 UserInfoGetData()

注意:C# 区分大小写,nameName 是两个不同的变量。

常量

值不可变的变量,用 const 声明,必须在声明时初始化。

const float PI = 3.14159f;
const int MAX_SIZE = 100;
// PI = 3.14f;  // 错误!常量不能修改

什么时候用:数学常数、配置参数、固定值。

转义字符

\ 开头的特殊字符,用于表示无法直接输入的字符。

转义符 效果 示例 输出
\' 单引号 "\'哈哈哈\'" '哈哈哈'
\" 双引号 "\"哈哈哈\"" "哈哈哈"
\n 换行 "第一行\n第二行" 两行文本
\\ 反斜杠 "C:\\Users" C:\Users
\t 制表符 "Name\tAge" Name Age
\b 退格 "123\b123" 12123
\a 警报音 "\a" 播放提示音

取消转义:字符串前加 @,如 @"C:\Users\file.txt"

类型转换

隐式转换(自动)

小范围 → 大范围,不丢失数据:

sbyte → short → int → long → float → double
byte → ushort → uint → ulong → float → double

注意stringbool 不参与隐式转换。

显式转换(强制)

方法 语法 说明 注意
括号强转 (int)3.14 强制转换类型 可能丢失精度或溢出
Parse int.Parse("123") 字符串转数值 格式错误会抛异常
Convert Convert.ToInt32("123") 任意类型互转 更安全,失败抛异常
ToString 123.ToString() 转字符串 所有类型都有

精度丢失示例

double d = 1.1234567890123456789;
float f = (float)d;  // 1.1234568,丢失精度

int i = (int)1.9f;   // 1,直接舍弃小数,不四舍五入

范围溢出示例

int big = 40000;
short small = (short)big;  // -25536,溢出后变成负数

异常捕获

处理程序运行时可能发生的错误,防止程序崩溃。

try
{
    int result = int.Parse("abc");  // 可能出错
}
catch (Exception e)
{
    Console.WriteLine("出错:" + e.Message);  // 出错时执行
}
finally
{
    // 无论是否出错都执行,用于清理资源
}
作用 必需
try 包裹可能出错的代码
catch 捕获并处理异常 是(至少一个)
finally 无论如何都执行

运算符

算术运算符

运算符 作用 示例 结果
+ 加法 5 + 3 8
- 减法 5 - 3 2
* 乘法 5 * 3 15
/ 除法 5 / 2 2(整数除法只保留整数)
% 取余 5 % 2 1

复合运算符+=-=*=/=%=(仅一种运算,不能混合)。
自增自减++--a++ 先用后加,++a 先加后用。

注意:整数相除只保留整数部分,要得到小数需 5.0 / 2

关系运算符

> < >= <= == !=,结果为 bool

bool result = 5 > 3;   // true
result = 5 == 3;       // false

注意:C# 不能直接用 1 < i < 5,需用逻辑运算符 i > 1 && i < 5

逻辑运算符

运算符 作用 规则 短路特性
&& 逻辑与 两边都true才true 左边false则右边不执行
|| 逻辑或 一边true就true 左边true则右边不执行
! 逻辑非 true变false,false变true
int a = 1;
bool result = a > 0 || ++a > 1;  // 左边true,右边++a不执行
Console.WriteLine(a);  // 输出1,a没有被自增

位运算符(了解)

对二进制位进行操作,常用于底层开发、权限控制。

运算符 作用 示例
& 位与 5 & 3 = 1
| 位或 5 | 3 = 7
^ 异或 5 ^ 3 = 6
~ 位取反 ~5 = -6
<< 左移 5 << 1 = 10(相当于×2)
>> 右移 5 >> 1 = 2(相当于÷2)

三目运算符

// 条件 ? 为真返回 : 为假返回
int max = a > b ? a : b;  // a>b则取a,否则取b

运算符优先级(高→低)

() → ! → * / % → + - → > < >= <= → == != → & → ^ → | → && → || → ?: 

建议:不确定时多用括号,代码更清晰。

字符串拼接

方法 语法 说明 适用场景
+ "Hello" + "World" 简单直接 少量拼接
+= str += "追加" 复合运算符 循环中追加
string.Format string.Format("{0}岁", 18) 占位符模板 多参数格式化
$ 插值 $"{name}岁" 最简洁直观 推荐使用

Console.WriteLine 也支持占位符:Console.WriteLine("A{0}B", x)(与 string.Format 用法一致)。
注意+ 拼接是唯一方法,不能用 - * /

流程控制

条件分支

语句 语法 特点
if if (条件) { ... } 单分支
if-else if (条件) { ... } else { ... } 二选一
if-else if-else if...else if...else 多分支
switch switch(变量) { case 值: ... break; } 等值判断

switch贯穿:多个case执行相同代码时,可省略中间的break。

switch (day)
{
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        Console.WriteLine("工作日");  // 1-5都执行这里
        break;
    case 6:
    case 7:
        Console.WriteLine("周末");
        break;
}

循环

语句 语法 执行顺序 特点 适用场景
while while (条件) { 循环体 } 先判断→后执行 可能一次都不执行 不确定次数
do-while do { 循环体 } while (条件); 先执行→后判断 至少执行一次 至少执行一次
for for (初始; 条件; 增量) { 循环体 } 初始化→判断→执行→增量 次数明确 固定次数

循环控制

  • break:跳出整个循环
  • continue:跳过本次,进入下一次

24.3 面试题精选

基础题

1. C#中的变量类型及其应用场景

题目

请列举C#中常见的变量类型,并说明在实际开发中如何根据数据特点选择合适的变量类型。

深入解析

C#中的变量类型主要分为三大类:整型、浮点型和特殊类型。

整型包括有符号和无符号两种:

  • 有符号:sbyte(1字节)、short(2字节)、int(4字节)、long(8字节)
  • 无符号:byte(1字节)、ushort(2字节)、uint(4字节)、ulong(8字节)

浮点型包括:

  • float(4字节,单精度)
  • double(8字节,双精度)
  • decimal(16字节,高精度)

特殊类型包括:bool、char、string等。

选择变量类型时需要考虑三个因素:

  1. 数据范围:根据数据的取值范围选择合适的类型,如年龄用byte(0-255),一般整数用int,大整数用long
  2. 精度要求:一般小数用float,需要更高精度用double,涉及金钱计算必须用decimal
  3. 内存占用:处理大量数据时,选择合适的类型可以显著节省内存
// 示例:游戏开发中的类型选择
byte age = 25;           // 年龄范围0-255,用byte节省内存
float position = 1.5f;   // 坐标用float,精度足够且节省内存
decimal money = 99.99m;  // 金钱计算用decimal,保证精度
答题示例

C#变量类型分整型、浮点型、特殊类型。

整型有 sbyte、short、int、long 及其无符号版本;浮点型有 float、double、decimal。

选择时看数据范围、精度和内存占用。比如游戏坐标用 float,金钱用 decimal,年龄用 byte。

参考文章
  • 5.变量
  • 6.变量的本质

2. 转义字符的使用方法

题目

请解释什么是转义字符,并列举几个常用的转义字符及其作用。

深入解析

转义字符是以反斜杠\开头的特殊字符,用于在字符串中表示无法直接输入的字符。

常用转义字符

  • \n:换行
  • \t:制表符
  • \":双引号
  • \\:反斜杠本身
  • \0:空字符

@符号的作用
在字符串前加@符号可以取消转义,字符串中的反斜杠会被当作普通字符处理。这在处理文件路径时特别有用。

// 普通字符串中的转义
string str1 = "第一行\n第二行";     // 换行
string str2 = "路径:C:\\Users\\"; // 双反斜杠表示一个反斜杠

// 使用@符号取消转义
string path = @"C:\Users\file.txt"; // 直接写反斜杠
string json = @"{""name"":""test""}"; // 双引号表示一个双引号
答题示例

转义字符是用反斜杠开头的特殊字符,比如 \n 换行、\t 制表符、\" 双引号。

字符串前加 @ 可以取消转义,处理文件路径时很方便,比如 @"C:\Users\file.txt"

参考文章
  • 9.转义字符

3. 类型转换的两种方式

题目

请简述C#中的隐式转换和显式转换的区别,并举例说明。

深入解析

C#中的类型转换分为隐式转换和显式转换两种。

隐式转换

  • 由编译器自动完成,不需要手动干预
  • 发生在小范围类型向大范围类型转换时
  • 不会丢失数据精度

显式转换

  • 需要手动指定转换类型
  • 发生在大范围类型向小范围类型转换时
  • 可能丢失数据精度

常见的显式转换方法

  1. 括号强转:直接进行类型转换,可能导致精度丢失
  2. Parse方法:将字符串转换为数值类型,格式错误时抛出异常
  3. Convert类方法:提供更安全的转换,会处理边界情况
// 隐式转换
int i = 10;
long l = i;        // int → long,自动转换

// 显式转换
double d = 3.14;
int j = (int)d;    // double → int,丢失小数部分

// Parse方法
int num = int.Parse("123");  // 字符串转整数

// Convert方法
int num2 = Convert.ToInt32(3.9);  // 四舍五入
答题示例

隐式转换是编译器自动完成的,小转大,比如 int 到 long。

显式转换需要手动写,大转小,可能丢精度,比如 double 到 int。

常用方法有括号强转、Parse、Convert。

参考文章
  • 10.类型转换-隐式转换
  • 11.类型转换-显式转换

进阶题

1. 逻辑运算符的短路特性

题目

请解释C#中逻辑运算符的短路特性,并举例说明这一特性在实际开发中的应用。

深入解析

C#中的逻辑运算符&&||具有短路特性,这是指在某些情况下,运算符右侧的表达式不会被执行。

短路特性原理

  • &&运算符:如果左侧条件为false,右侧条件不会执行
  • ||运算符:如果左侧条件为true,右侧条件不会执行

实际应用场景

  1. 空引用检查:在访问对象成员前先检查是否为null
  2. 性能优化:避免不必要的计算
  3. 防止异常:避免执行可能抛出异常的代码
// 空引用检查
if (obj != null && obj.DoSomething())
{
    // 当obj为null时,DoSomething()不会执行
}

// 性能优化
if (IsCacheValid() || ExpensiveCalculation())
{
    // 如果缓存有效,不会执行昂贵的计算
}

// 注意:不要在短路运算符右侧放置有副作用的表达式
int a = 0;
if (false && ++a > 0)  // a不会自增
{
}
Console.WriteLine(a);  // 输出:0
答题示例

&& 左边 false 就不执行右边,|| 左边 true 就不执行右边。

常用于空引用检查,比如 obj != null && obj.Method(),避免空异常。

注意右边不要放有副作用的表达式。

参考文章
  • 16.运算符-逻辑运算符

2. try-catch异常处理的最佳实践

题目

请说明try-catch异常处理的使用场景和注意事项,并给出最佳实践建议。

深入解析

try-catch异常处理用于捕获和处理程序运行时可能发生的错误,防止程序崩溃。

基本结构

  • try块:包裹可能出错的代码
  • catch块:捕获并处理异常
  • finally块:无论是否发生异常都会执行,用于释放资源

适用场景

  • 用户输入处理
  • 文件操作
  • 网络请求
  • 类型转换

最佳实践

  1. 不要用异常处理代替正常的条件判断(会影响性能)
  2. 捕获异常后要进行适当处理(如记录日志或提示用户)
  3. 在finally块中释放资源(如关闭文件流)
  4. 捕获具体的异常类型,而不是笼统的Exception
// 正确做法:具体异常类型 + 资源释放
try
{
    string content = File.ReadAllText("data.txt");
}
catch (FileNotFoundException ex)
{
    Console.WriteLine($"文件不存在:{ex.FileName}");
}
catch (IOException ex)
{
    Console.WriteLine($"读取失败:{ex.Message}");
}
finally
{
    // 释放资源
}

// 错误做法:用异常处理代替条件判断
try
{
    int num = int.Parse(input);
}
catch
{
    // 应该用int.TryParse代替
}
答题示例

try-catch 用于捕获运行时错误。

适用场景有文件操作、网络请求等。

注意不要用异常代替条件判断,要捕获具体异常类型,finally 里释放资源。可预期的错误用条件判断提前检查。

参考文章
  • 12.异常捕获

3. switch与if-else的选择

题目

请说明switch语句和if-else语句的区别,以及在什么情况下应该选择switch而不是if-else。

深入解析

switch语句和if-else语句都是条件分支语句,但适用场景不同。

switch语句特点

  • 适合等值判断,特别是多个固定值的情况
  • 代码结构更清晰
  • 可以使用case贯穿特性,让多个case执行相同代码
  • 编译器可能优化为跳转表,性能更好

if-else语句特点

  • 适合范围判断和复杂条件
  • 更灵活,可以处理任意布尔表达式
  • 条件判断顺序影响执行效率

选择建议

  • 判断变量是否等于多个固定值:优先使用switch
  • 范围判断或复杂条件:使用if-else
// switch适合的场景:等值判断
switch (dayOfWeek)
{
    case 1:
        Console.WriteLine("星期一");
        break;
    case 2:
        Console.WriteLine("星期二");
        break;
    // ...
}

// if-else适合的场景:范围判断
if (score >= 90)
{
    Console.WriteLine("优秀");
}
else if (score >= 60)
{
    Console.WriteLine("及格");
}
else
{
    Console.WriteLine("不及格");
}
答题示例

switch 适合等值判断,多个固定值时代码更清晰,性能可能更好。

if-else 适合范围判断和复杂条件。

比如判断星期几用 switch,判断分数等级用 if-else。

参考文章
  • 19.条件分支语句-if
  • 20.条件分支语句-switch

深度题

1. 变量类型选择对性能的影响

题目

请分析C#中不同变量类型的内存占用情况,并说明类型选择对程序性能的影响。

深入解析

C#中不同变量类型的内存占用不同,类型选择直接影响程序性能。

各类型内存占用

类型 占用字节
byte, sbyte 1字节
short, ushort, char 2字节
int, uint, float 4字节
long, ulong, double 8字节
decimal 16字节

性能影响(紧扣系列:第5、6篇讲的是各类型内存占用与取值范围):

  1. 内存占用:用 sizeof 可知各类型字节数;选小类型(如 byte、float)可减少内存,利于缓存
  2. 取值范围:选型时要避免溢出(如 short 装不下 40000 会变成负数)
  3. 实际选择:年龄用 byte、坐标用 float、金钱用 decimal,既保证正确又控制占用

游戏开发中的优化策略

  • 存储大量NPC年龄使用byte
  • 坐标使用float而非double
  • 状态标记使用位运算而非多个bool
// 优化示例
// 不好的做法
bool isPoisoned;
bool isAccelerated;
bool isInvincible;
// ... 32个bool变量,占用32字节

// 好的做法
int stateFlags;  // 用位存储32个状态,只占4字节
const int POISONED = 1 << 0;
const int ACCELERATED = 1 << 1;
const int INVINCIBLE = 1 << 2;

// 添加状态
stateFlags |= POISONED;
// 检查状态
if ((stateFlags & POISONED) != 0) { }
答题示例

不同类型内存占用不同,byte 1 字节,int 4 字节,double 8 字节,可用 sizeof 查看。

选型时根据范围和精度来选,避免溢出和精度丢失。

游戏开发里坐标用 float、年龄用 byte、状态用位运算打包,能显著节省内存、提升性能。

参考文章
  • 5.变量
  • 6.变量的本质

2. 位运算在游戏开发中的应用

题目

请说明位运算符的作用,并举例说明位运算在游戏开发中的实际应用场景。

深入解析

位运算符用于对二进制位进行直接操作,在游戏开发中有重要应用。

位运算符

  • &(位与):两位都为1时结果为1
  • |(位或):有一位为1时结果为1
  • ^(异或):两位不同时结果为1
  • ~(位取反):0变1,1变0
  • <<(左移):左移n位,相当于乘以2^n
  • >>(右移):右移n位,相当于除以2^n

游戏开发应用场景

  1. 状态管理:用一个整数的每一位表示一个状态
  2. 权限控制:用位表示不同权限
  3. 配置选项:用位存储多个开关选项
// 状态管理示例
[Flags]
enum PlayerState
{
    None = 0,
    Poisoned = 1,      // 0001
    Accelerated = 2,   // 0010
    Invincible = 4,    // 0100
    Invisible = 8      // 1000
}

PlayerState state = PlayerState.Poisoned | PlayerState.Accelerated;

// 检查状态
if (state.HasFlag(PlayerState.Poisoned))
{
    // 处理中毒状态
}

// 移除状态
state &= ~PlayerState.Poisoned;

// 切换状态
state ^= PlayerState.Invincible;

优势

  • 节省内存:一个int存储32个状态
  • 操作快速:位运算是CPU原生支持的
  • 便于网络传输:状态数据紧凑
答题示例

位运算符有 & 与、| 或、^ 异或、~ 取反、<< 左移、>> 右移。

游戏开发中常用于状态管理,一个 int 存 32 个状态,比 32 个 bool 省内存。

比如 state |= 1 添加状态,state &= ~1 移除状态,state & 1 检查状态。

参考文章
  • 17.运算符-位运算符


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏