C#程序设计——C#基础(从零到精通,看这一篇就够了)

.NET 技术栈核心组件

1. .NET Framework 与 .NET Core
  • .NET Framework
    传统 Windows 平台的运行时环境,包含:

    • CLR (Common Language Runtime):底层运行时,负责内存管理、垃圾回收等。
    • FCL (Framework Class Library):基础类库,提供如System.IOSystem.Net等功能。
    • 支持 Windows Forms、ASP.NET等应用模型。
  • .NET Core/.NET 5+
    跨平台(Windows/macOS/Linux)的现代框架,统一了.NET Framework、.NET Core 和 Xamarin,支持:

    • 控制台、Web、移动(MAUI)、云服务等应用类型。
    • 模块化依赖管理(NuGet)和更小的部署包。
2. C# 与公共类型系统 (CTS)
  • C# 语言:.NET 生态的主要编程语言,语法简洁,支持面向对象、泛型、LINQ 等特性。
  • CTS (Common Type System):.NET 的类型规范,定义了:
    • 基础类型(如int映射到System.Int32)。
    • 类型兼容性规则,确保不同语言(C#、VB.NET等)间的互操作性。

示例

csharp

int a = 10;          // C#语法糖,实际对应System.Int32
Int32 b = 20;        // 显式使用CTS类型名
string s = "hello";  // C#字符串(映射到System.String)
String s2 = "HELLO"; // 等效于string(CTS类型名)
3. CLR 与 JIT 编译
  • CLR (Common Language Runtime):.NET 的运行时环境,负责:

    • 加载和执行程序集(IL 代码)。
    • 通过 JIT(Just-In-Time)编译器将 IL 转换为机器码。
    • 提供内存管理、类型安全检查等服务。
  • JIT 工作流程

    text

    C#源码 → 编译器(csc) → IL中间语言(.dll/.exe) → JIT → 机器码(CPU执行)
    
4. CTS 与 CLS
  • CTS (Common Type System):定义所有.NET 语言必须遵循的类型规范。
  • CLS (Common Language Specification):CTS 的子集,确保语言间互操作性(如 C# 与VB.NET)。

第一个 C# 程序解析

代码结构

csharp

using System;  // 引入System命名空间

namespace demo2  // 命名空间:组织代码的逻辑容器
{
    public class Program  // 公共类:程序入口点
    {
        public static void Main()  // 程序主方法(入口点)
        {
            Console.WriteLine("Hello C#");  // 输出到控制台
            Console.ReadKey();  // 等待用户按键,防止窗口自动关闭
        }
    }
}
编译流程
  1. 源码 (.cs) → IL 中间语言 (.exe) → 机器码
  2. 手动编译步骤(需配置环境变量):

    bash

    # 1. 进入源码目录
    cd C:\Users\YourName\Documents
    
    # 2. 使用csc编译器生成.exe
    csc HelloWorld.cs
    
    # 3. 运行程序
    HelloWorld.exe
    

编译工具与环境配置

1. csc 编译器
  • 路径C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe
    (64 位系统的.NET Framework 4.0 版本)
2. 环境变量配置
  • 旧方法:手动将csc.exe路径添加到系统PATH变量。
  • 现代开发:安装 Visual Studio 后自动配置环境变量,支持直接使用csc命令。

DOS 命令基础

命令 作用 示例
cd 切换目录 cd C:\Projects
dir 显示当前目录内容 dir
cls 清屏 cls
csc 编译 C# 源码 csc Program.cs

命名空间与标识符规范

命名空间(Namespace)
  • 逻辑分组代码,避免命名冲突。
  • 示例:System.Console 中的 System 是命名空间。
标识符规范
元素 命名规范 示例
类 / 命名空间 PascalCase CustomerManager
方法 / 属性 PascalCase GetUserInfo()
变量 / 参数 camelCase userName
常量 全大写 + 下划线 MAX_CONNECTIONS

核心类与方法解析

1. Console 类
  • 位于System命名空间,提供控制台输入 / 输出功能:

    csharp

    Console.WriteLine("文本");  // 输出并换行
    Console.Write("不换行");    // 输出不换行
    Console.ReadLine();        // 读取用户输入(按回车结束)
    
2. Main 方法
  • 程序入口点,签名必须为:

    csharp

    public static void Main()  // 无参数版本
    public static int Main()   // 返回int表示退出代码
    public static void Main(string[] args)  // 接收命令行参数
    

语句、块与空白

  • 语句:一行可执行代码(如int a = 10;)。
  • :用{}包裹的语句组(如方法体)。
  • 空白:空格、制表符、换行符,用于提高代码可读性,编译器会忽略。

C# 标识符规则

标识符用于命名类、变量、函数等用户定义的元素,命名需遵循以下规则:

  1. 字符组成:由字母、数字、下划线(_)组成。
  2. 开头限制:必须以字母、下划线或 @ 开头,不能以数字开头。
  3. 特殊符号:禁止包含空格或特殊符号(如 ?、+、!、# 等)。
  4. 关键字冲突:不能是 C# 关键字,但若添加 @ 前缀可作为标识符(如 @if)。
  5. 大小写敏感:严格区分大小写(如 UserAge 和 userAge 是不同标识符)。
  6. 命名规范:建议 “见名知意”,例如用 userName 表示用户名。

C# 关键字

C# 关键字分为保留关键字上下文关键字,以下是常见类型:

保留关键字(不可直接作为标识符)
abstract as base bool break byte case
catch char checked class const continue decimal
default delegate do double else enum event
if int interface namespace new public static
try void while ... ... ... ...
上下文关键字(仅在特定上下文有特殊含义)

| add | alias | ascending| dynamic | from | get |
| global | group | into | join | let | orderby |
| partial | remove | select | set | where | yield |

变量与常量

变量
  • 定义格式数据类型 变量名;(如 int age;)。
  • 赋值方式:通过 = 运算符赋值(如 age = 18;),可声明时直接赋值(如 string name = "张三";)。
  • 注意事项
    • 变量名不可重复声明。
    • 必须初始化(赋值)后才能使用。
    • 可同时定义多个同类型变量(如 int a, b, c;)。
常量
  • 定义格式:使用 const 关键字,值在编译阶段确定且不可修改。

    csharp

    const double PI = 3.1415926; // 正确  
    // PI = 3.14; // 错误:常量不可修改  
    

控制台常用方法

方法 描述
WriteLine() 输出内容并换行(如 Console.WriteLine("Hello World!");)。
Write() 输出内容不换行(如 Console.Write("No newline");)。
ReadKey() 等待用户输入单个字符,返回输入的键(常用于暂停程序)。
ReadLine() 等待用户输入一行文本,返回字符串(需按回车键确认)。
Beep() 播放系统提示音(如 Console.Beep(2000, 800);:频率 2000Hz,持续 800ms)。
Clear() 清空控制台窗口内容。
控制台属性(修改颜色)

csharp

Console.BackgroundColor = ConsoleColor.Red; // 设置背景色为红色  
Console.ForegroundColor = ConsoleColor.Yellow; // 设置字体颜色为黄色  
Console.WriteLine("红色背景+黄色字体");  

数据类型

C# 数据类型分为值类型引用类型

值类型(直接存储数据值)
类型 描述 示例 默认值
整数 有符号 / 无符号整数 int age = 18; byte score = 90; 0
浮点数 单精度 / 双精度小数 float price = 9.9f; double pi = 3.14; 0.0
布尔 逻辑值(真 / 假) bool isReady = true; false
字符 单个 Unicode 字符 char gender = '男'; \0
字符串 字符序列(引用类型) string name = "李四"; null
引用类型(存储数据引用)
  • 对象(object:所有类型的基类,可存储任意类型数据(如 object obj = "文本"; obj = 123;)。
  • 动态类型(dynamic:类型检查在运行时进行,灵活性高但可能引发运行时错误。

作业:变量定义练习

根据描述定义合适的变量(注意数据类型和命名规范):

描述 变量名 数据类型 示例值
苹果的个数 appleCount int 5
头发的长度 hairLength double 15.5
眼睛的颜色 eyeColor string "黑色"
大象的重量 elephantWeight double 3000.5
现在的季节 currentSeason string "夏季"
现在的天气 currentWeather string "晴"
手指的个数 fingerCount int 10
空调的温度 airConditionTemp int 24
现在放学没有 isAfterSchool bool true
明天下雨不下 willRainTomorrow bool false
水的重量 waterWeight double 50.2
鞋的码数 shoeSize int 42
女朋友的名字 girlfriendName string "小美"
有没有女朋友 hasGirlfriend bool true
餐厅名字 restaurantName string "幸福餐厅"
学生的学号 studentId string "20230101"
电话号码 phoneNumber string "13812345678"
一句话 sentence string "C# 学习很有趣!"

扩展知识:计算机存储单位

  • 基本单位
    • 位(bit):最小存储单位,只能是 0 或 1
    • 字节(Byte, B):基本存储单位,1 Byte = 8 bit,一个英文字符占 1 Byte,一个汉字占 2 Byte
  • 换算关系

    plaintext

    1 KB = 1024 B  
    1 MB = 1024 KB  
    1 GB = 1024 MB  
    1 TB = 1024 GB  
    
  • 注意
    • 十进制单位(GB)与二进制单位(GiB)易混淆,计算机实际按二进制换算。

    • 大文件存储(如视频、硬盘容量)常用 GB、TB 表示。

运算符概述

运算符是用于执行特定数学或逻辑操作的符号。通过组合变量、常量和运算符,可以构成表达式(如 a + btrue && false)。表达式的运算结果具有值类型。

算术运算符

运算符 描述 示例 注意事项
+ 加法 5 + 3 → 8 字符串拼接时使用 +(如 "a" + "b" → "ab"
- 减法 5 - 3 → 2
* 乘法 5 * 3 → 15
/ 除法 5 / 3 → 1(整数) 整数相除结果为整数(舍弃小数部分)
% 取余(模) 5 % 3 → 2 除数不能为 0(如 10 % 0 会报错)

示例代码

csharp

int a = 10;  
int b = 3;  
Console.WriteLine(a / b);  // 输出 3(整数除法)  
Console.WriteLine(a % b);  // 输出 1(取余)  

// 字符串拼接  
string name = "张三";  
int age = 20;  
Console.WriteLine(name + "今年" + age + "岁");  // 输出:张三今年20岁  

赋值运算符

运算符 等价形式 示例
= 直接赋值 int a = 10;
+= a = a + n a += 5 → a = 15
-= a = a - n a -= 3 → a = 7
*= a = a * n a *= 2 → a = 20
/= a = a / n a /= 5 → a = 2
%= a = a % n a %= 3 → a = 1

自增 / 自减运算符(++/--

  • 后置自增(a++:先返回值,再自增。
  • 前置自增(++a:先自增,再返回值。

示例

csharp

int a = 5;  
int b = a++;  // b = 5(先赋值,后a自增为6)  
int c = ++a;  // c = 7(a先自增为7,再赋值给c)  

Console.WriteLine(a);  // 输出 7  
Console.WriteLine(b);  // 输出 5  
Console.WriteLine(c);  // 输出 7  

比较运算符(返回bool类型)

运算符 描述 示例
< 小于 5 < 3 → false
> 大于 5 > 3 → true
<= 小于等于 5 <= 5 → true
>= 大于等于 5 >= 3 → true
== 等于 5 == 3 → false
!= 不等于 5 != 3 → true

逻辑运算符(操作bool值)

运算符 描述 示例
&& 短路与(两边为真才为真) true && false → false
` ` 短路或(一边为真即为真) `true falsetrue`
! 非(取反) !true → false
& 逻辑与(不短路) true & false → false
` ` 逻辑或(不短路) `true falsetrue`

短路逻辑

  • &&:若左侧为false,右侧不执行。
  • ||:若左侧为true,右侧不执行。

示例

csharp

int a = 5;  
bool result = (a > 10) && (++a > 0);  // a>10为false,右侧不执行  
Console.WriteLine(a);  // 输出 5(a未自增)  

bool result2 = (a < 10) || (++a > 0);  // a<10为true,右侧不执行  
Console.WriteLine(a);  // 输出 5(a未自增)  

运算符优先级(从高到低)

优先级 运算符 结合性
1 . () {} ; 从左到右
2 ++ -- ! 从右到左
3 * / % 从左到右
4 + - 从左到右
5 < > <= >= 从左到右
6 == != 从左到右
7 & 从左到右
8 ` ` 从左到右
9 && 从左到右
10 ` ` 从左到右
11 ?:(三元运算符) 从右到左

建议:使用括号明确运算顺序,避免混淆(如 (a + b) * c)。

C# 逻辑练习题解析

1. 判断奇偶数

题目:接收用户输入的整数,判断其奇偶性。
关键逻辑:利用取余运算符 % 判断是否能被 2 整除。

csharp

Console.Write("请输入一个整数: ");
int number = Convert.ToInt32(Console.ReadLine()); // 兼容空输入的健壮性处理
string result = number % 2 == 0 ? "偶数" : "奇数";
Console.WriteLine($"{number} 是{result}");

扩展:负数的奇偶性判断与正数一致(如 -3 % 2 = -1,取余结果符号与被除数相同)。

2. 找出三个数中的最大值

题目:比较三个整数,输出最大值。
解法 1:逐步比较

csharp

int a = 10, b = 25, c = 15;
int max = Math.Max(Math.Max(a, b), c); // 利用内置Math类简化代码
Console.WriteLine($"最大值是: {max}");

解法 2:三目运算符

csharp

int max = a > b ? (a > c ? a : c) : (b > c ? b : c);

注意Math.Max 支持多个重载,可直接处理数组或参数列表。

3. 斐波那契数列

题目:输出前 n 项斐波那契数列(0, 1, 1, 2, 3, 5...)。
优化代码

csharp

int n = 10;
int first = 0, second = 1;
Console.Write("斐波那契数列前{0}项: ", n);
for (int i = 0; i < n; i++)
{
    Console.Write(first + " ");
    (first, second) = (second, first + second); // 元组赋值简化代码
}

扩展:递归实现(适用于小 n 值,大 n 会因重复计算导致性能问题):

csharp

int Fibonacci(int n) => n <= 1 ? n : Fibonacci(n-1) + Fibonacci(n-2);
4. 判断素数

题目:判断输入的正整数是否为素数(只能被 1 和自身整除)。
优化逻辑

  • 1 不是素数,直接排除。
  • 只需遍历到平方根(减少循环次数)。

csharp

Console.Write("请输入一个正整数: ");
if (!int.TryParse(Console.ReadLine(), out int num) || num < 2) // 输入验证
{
    Console.WriteLine("输入无效或非素数");
    return;
}

bool isPrime = true;
for (int i = 2; i <= Math.Sqrt(num); i++)
{
    if (num % i == 0)
    {
        isPrime = false;
        break;
    }
}
Console.WriteLine($"{num} {(isPrime ? "是" : "不是")}素数");
5. 反转字符串

题目:不使用内置反转方法(如Reverse()),手动反转字符串。
核心思路:通过字符数组交换首尾字符。

csharp

string input = "Hello World";
char[] chars = input.ToCharArray();
for (int i = 0, j = chars.Length - 1; i < j; i++, j--)
{
    (chars[i], chars[j]) = (chars[j], chars[i]); // 元组交换,无需临时变量
}
Console.WriteLine("反转后的字符串: " + new string(chars));

注意string是不可变类型,需转换为char[]操作。

6. 二分查找

题目:在有序数组中查找目标值的索引。
代码优化

csharp

int[] sortedArray = { 2, 5, 8, 12, 16, 23, 38, 56, 72, 91 };
int target = 23;
int left = 0, right = sortedArray.Length - 1;

while (left <= right)
{
    int mid = left + (right - left) / 2; // 避免整数溢出
    if (sortedArray[mid] == target) return mid;
    else if (sortedArray[mid] < target) left = mid + 1;
    else right = mid - 1;
}
Console.WriteLine("未找到目标值");

前提:数组必须已排序,否则需先排序(如Array.Sort())。

7. 水仙花数

题目:找出 100-999 之间的水仙花数(各位数字立方和等于自身)。
数学拆解

  • 百位:num / 100
  • 十位:(num / 10) % 10
  • 个位:num % 10

csharp

Console.WriteLine("100-999之间的水仙花数:");
for (int i = 100; i <= 999; i++)
{
    int a = i / 100, b = (i / 10) % 10, c = i % 10;
    if (a*a*a + b*b*b + c*c*c == i)
    {
        Console.WriteLine(i); // 常见结果:153, 370, 371, 407
    }
}
8. 汉诺塔问题

题目:使用递归解决汉诺塔问题,输出移动步骤。
递归逻辑

  • 若只有 1 个盘子,直接移动。
  • 否则,先将 n-1 个盘子从起点移到辅助柱,再移动第 n 个盘子,最后将 n-1 个盘子从辅助柱移到终点。

csharp

void Hanoi(int n, char from, char to, char aux)
{
    if (n == 0) return;
    Hanoi(n-1, from, aux, to); // 递归移动n-1个盘子到辅助柱
    Console.WriteLine($"将盘子{n}从 {from} 移动到 {to}");
    Hanoi(n-1, aux, to, from); // 递归移动n-1个盘子到终点
}

Hanoi(3, 'A', 'C', 'B'); // 输出3层汉诺塔的7步移动

扩展:时间复杂度为 O (2ⁿ),n 层需要 2ⁿ-1 步移动。

你可能感兴趣的:(c#,开发语言)