C#学习笔记 - C#基础知识 - C#从入门到放弃

C# 持续更新中~~ 上次更新日期:20231215


上次更新日期:20231215)

第1节 C# 简单介绍

1.1 C# 是什么

C# 的发音为“C Sharp”,是一门由微软开发并获得了 ECMA(欧洲计算机制造商协会)和 ISO(国际标准组织)批准的现代的、通用的、面向对象的编程语言。

C# 之所以能称为一门被广泛应用的编程语言,原因有以下几点:

  • C# 是一种现代的通用的编程语言;
  • C# 是面向对象的; C# 是面向组件的;
  • C# 简单易学;
  • C# 是一种结构化语言;
  • 使用 C# 开发效率很高;
  • C# 可以在各种计算机平台上进行编译;
  • C# 是 .Net Framework 的一部分。

1.2 C# 强大的编程功能

一开始没接触C#的时候,我觉得它可能跟C、C++语言相似,后来发现一点也不像???它与 Java 非常相似,有很多强大的编程功能:

以下是 C# 的一些重要功能的列表:

  • 布尔条件;
  • 自动垃圾回收;
  • 标准库;
  • 组件版本;
  • 属性和事件;
  • 委托和时间管理;
  • 易于使用的泛型;
  • 索引器;
  • 条件编译;
  • 简单的多线程;
  • LINQ 和 Lambda 表达式;
  • 集成 Windows。

借助 C# 编程语言,我们可以开发不同类型且安全可靠的应用程序,例如:
1、桌面应用程序;
2、网络应用程序;
3、分布式应用程序;
4、Web 服务应用程序;
5、数据库应用程序等。

1.3 C# 发展史

在这里插入图片描述

1.4 C#与Java区别

在这里插入图片描述

第2节 C#基本语法

2.1 C#程序结构

“Hello, World”程序历来都用于介绍编程语言。 下面展示了此程序的 C# 代码:

using System;
using System.Collections.Generic;
//using ...
//以上引用命名空间

namespace _Csharp程序结构
{
    class Program       //Program类
    {
        static void Main(string[] args) //static 静态 void 无返回值 Main 函数 - 程序起点
        {
            Console.WriteLine("Hello Word!");
            Console.ReadKey();
        }
    }
}

//以上命名空间或者项目名称

输出:

Hello, World

“Hello, World”程序始于引用 System 命名空间的 using 指令。 命名空间提供了一种用于组织 C# 程序和库的分层方法。命名空间包含类型和其他命名空间。例如,System 命名空间包含许多类型(如程序中引用的 Console 类)和其他许多命名空间(如 IOCollections)。 借助引用给定命名空间的 using 指令,可以非限定的方式使用作为相应命名空间成员的类型。 由于使用 using 指令,因此程序可以使用 Console.WriteLine 作为 System.Console.WriteLine 的简写。

“Hello, World”程序声明的 Hello 类只有一个成员,即 Main 方法。 Main 方法使用 static 修饰符进行声明。 实例方法可以使用关键字 this 引用特定的封闭对象实例,而静态方法则可以在不引用特定对象的情况下运行。 Main 静态方法是 C# 程序的入口点

程序的输出是由 System 命名空间中 Console 类的 WriteLine 方法生成。 此类由标准类库提供。默认情况下,编译器会自动引用标准类库。

2.2 C# 结构解析

有如下一个C# 程序代码:

using System;
using System.Collections.Generic;
using ...
//以上引用命名空间

namespace _Csharp程序结构
{
    class Program       //Program类
    {
        static void Main(string[] args) 
        //static 静态 void 无返回值 Main 函数 - 程序起点
        {
            Console.WriteLine("Hello Word!");
            Console.ReadKey();
        }
    }
}

//以上命名空间或者项目名称

在次程序中:
1、 using System;
using 关键字用来在程序中引入 System 命名空间,一个程序中可以有多个 using 语句。
2、namespace _Csharp程序结构
namespace 关键字用来声明一个命名空间,“Csharp程序结构”则是命名空间的名字。命名空间是类的集合,上面代码中名为“Csharp程序结构”的命名空间中包含了一个名为“Program”的
3、class Program
class 关键字用来定义一个类,“Program”则是类的名,类中通常用来存放程序中要使用的数据和函数(也叫方法)。
4、static void Main(string[ ] args)
此行代码中,Main 为定义的函数名称,Main 函数是整个 C# 程序的入口,其中包含了程序运行时需要执行的操作。static 和 void 都是用来修饰 Main 函数的关键字,具体含义后面我们会详细介绍。
5、 //static 静态 void 无返回值 Main 函数 - 程序起点
这是程序的注释,当程序运行时被//注释的内容将被编译器忽略,不会执行。注释主要用来对所写的代码进行说明。多行可使用/* */

/*
static 静态 
void 无返回值 
Main 函数 - 程序起点
*/

6、Console.WriteLine(“Hello World!”);
此行代码用来在命令行窗口中输出“Hello World!”。WriteLineSystem 命名空间中定义的 Console 类里面的方法,用来输出一些消息。
7、Console.ReadKey( );
此行代码是针对 VS.NET 用户的,它会使程序进入等待状态,敲击键盘上的任意一个按键即可让程序继续运行。需要这行代码是因为命令行窗口会在程序运行结束后自动关闭,导致要输出的内容一闪而过,加入此行代码则可以避免这种情况。

另外,还有以下几点需要注意:
1、C# 区分大小写;
2、所有语句和表达式都必须以英文的分号;结尾;
3、程序从 Main 函数开始执行;
4、与 Java 不同,程序文件名可以与类名不同;
5、代码中出现的{}都是成对出现的,用来标记代码块,{ }中包裹的代码可以看作是一个整体。

2.3 命名空间及标识符、关键字

2.3.1 别名的使用

使用别名(alias)来为类型或命名空间定义一个新的名称,以简化代码并增强可读性。使用别名可以提供更简洁、易懂的类型或命名空间名称,或者使代码与外部库或组件更加兼容。
别名的使用可以通过以下两种方式来实现:
1、使用using语句:
使用using语句可以在给定的作用域内为类型或命名空间指定一个别名。这通常用于简化对长命名空间的引用。

using System;
using Co = System.Console;
//using ...
//以上引用命名空间

namespace _Csharp程序结构
{
    class Program       //Program类
    {
        static void Main(string[] args) //static 静态 void 无返回值 Main 函数 - 程序起点
        {
            Console.WriteLine("1、这是使用Console输出");
            Co.WriteLine("2、这是使用别名Co输出");
            Co.ReadKey();
        }
    }
}
//以上命名空间或者项目名称

输出结果:

1、这是使用Console输出
2、这是使用别名Co输出

2、使用typedef命令:
在一些特殊情况下,可以使用typedef命令来创建类型别名,这种方式只适用于在BCL(基础类库)中定义的类型。

typedef MyAlias = System.Collections.Generic.List<string>;

// 使用别名创建对象
MyAlias myList = new MyAlias();

// 使用别名调用方法
myList.Add("Hello");

需要注意:
① 别名仅在定义它们的范围内有效,如果使用别名的代码超出了别名的作用域,就需要重新引用完整的类型或命名空间。
② 使用别名可以提高代码的可读性和可维护性,特别是在涉及到长、复杂的类型或命名空间时。但是,在使用别名时应保持适度,确保别名具有明确、清晰的意义,不会与其他代码产生混淆。
③ 不建议定义系统自带的方法、函数等别名。

2.3.2 标识符

标识符是用来为类、变量、函数或任何其他自定义内容命名。C# 中标识符的定义规则如下所示:
1、标识符必须以英文字母开头,后面可以跟英文字母、数字0-9或下划线_
2、标识符中的第一个字符不能是数字
3、标识符中不能包含空格或特殊符号,例如? - + ! @ # % ^ & * ( ) [ ] { } . ; : " ’ / \,但是可以使用下划线_
4、C#区分大小写;
5、标识符不能是 C# 关键字。

2.3.3 C#关键字

C# 中的关键字是编译器预先定义好的一些单词,也可以称为保留字或者保留标识符,这些关键字对编译器有特殊的意义,不能用作标识符。但是,如果非要使用的话只需要在关键字前面加上@前缀即可:如@if就是一个有效的标识符,而if则是一个关键字
下图列出了 C# 中的保留关键字(Reserved Keywords)和上下文关键字(Contextual Keywords):
在这里插入图片描述

第3节 变量、常量与数据类型

3.1 C#变量

变量可以理解为是我们程序可以操作的内存区域的名称,在 C# 中每个变量都有自己特定的类型,这个类型确定了变量所占内存的大小、布局、取值范围以及可以对该变量执行的操作。
可以将变量当作一种通过符号(变量名)表示某个内存区域的方法,变量的值可以更改,并且可以多次重复使用。C# 中的基本变量类型可以归纳为以下几种:

类型变量名称
整型(整数类型)sbyte、byte、short、ushort、int、uint、long、ulong、char
浮点型float、double
十进制类型decimal
布尔型true、false
空类型可为空值的数据类型

3.1.1 变量使用

1、声明变量
2、初始化变量(变量赋值)
3、变量使用

3.1.2 自定义变量

使用如下:

int a;	//double b;
a = 23;	//b = 3.14;
Console.WriteLine(a);
Console.ReadKey();	//停留弹窗

3.1.2 接收用户输入

代码如下:

Console.WriteLine("输入一个整数:");
int a = int.Parse(Console.ReadLine());
Console.WriteLine("你输入的数是:"+a); 
Console.ReadKey();	//停留弹窗

运行结果:

输入一个整数:
23
你输入的数是:23

在上述代码中,int.Parse( )函数用于将字符串转换为整数类型(int)。它接受一个表示整数的字符串参数,并返回对应的整数值。因为C#默认用户输入的数据是字符串类型(string),需要使用int.Parse( )函数进行转换。
使用int.Parse( )函数需要注意以下几点:
1、字符串必须包含有效的整数表示。
2、如果字符串无法解析为整数,则会抛出FormatException异常。
3、转换结果的范围应该在int类型的表示范围内,否则会抛出OverflowException异常。

除了int.Parse( )函数,C#还提供了其他类似的类型转换方法,比如double.Parse( )用于将字符串转换为双精度浮点数,bool.Parse( )用于将字符串转换为布尔值等。
这些方法在处理类型转换时非常有用,但要确保字符串的格式与目标类型匹配,以避免转换错误。

3.2 C#常量

常量和《变量》类似,唯一不同的是常量的值在程序的编译阶段就已经确定了,而且在程序的运行期间不允许修改。常量可以是任何基本数据类型,如整数常量、浮点常量、字符串常量等等。

常量在程序中用于存储不可变的数值、字符串,或者其他类型的数据。使用常量的好处在于可以提高代码的可读性和可维护性,并且在编译时会进行常量优化,减少运行时的开销。

3.2.1 常量的使用

1、声明常量 - const
2、初始化常量(常量赋值)
3、常量使用
【示例】计算圆的周长和面积。

 const double pi = 3.14;
 double r = 5;
 Console.WriteLine("此圆的周长是:"+2*pi*r);
 Console.WriteLine("此圆的面积是:"+pi*r*r);
 Console.ReadKey();	//停留弹窗

运行程序:

此圆的周长是:31.4
此圆的面积是:78.5

需要注意: 常量只能在声明时进行初始化,并且初始化值必须是一个编译时可确定的常量表达式。常量不能在运行时修改,并且不能重复赋值。

使用常量可以提高程序的可读性和可维护性,特别在使用固定值的时候,可以减少魔法数字的出现。魔法数字是未经解释和命名的硬编码值,使用常量可以将这些值集中起来管理,提高代码的可靠性和可维护性。

3.3 C#数据类型

C#中,数据类型可以分为值类型(value types)和引用类型(reference types)。值类型直接存储数据的值,而引用类型存储数据的地址。

3.3.1 数据类型之值类型

C#中常见的值类型:
1、数值类型:
整数类型:sbyte, byte, short, ushort, int, uint, long, ulong。
浮点类型:float, double, decimal。
2、布尔类型:
bool:表示逻辑值的类型,只能取值true或false。
3、字符类型:
char:表示单个字符的Unicode字符。
4、枚举类型:
enum:用户定义的枚举类型,用于定义一组命名的常量值。
5、结构体类型(struct):
struct:用户定义的结构类型,用于封装多个相关的值。

需要注意:
1、值类型的特点是存储在栈上,比较高效,适用于存储较小的数据和简单的数值计算。在使用值类型时,注意数据的大小和范围是否满足需求,并且可以避免不必要的副本创建,以提高性能。
2、值类型在内存中分配空间并直接存储数据的值,因此它们通常具有大小已知的固定内存布局。值类型的赋值和参数传递是按值传递的,即复制整个值。这意味着在对值类型进行操作时,操作的是它们的副本,而不是原始值本身。

3.3.2 数据类型之引用类型

C#中,引用类型(reference types)是一种存储对数据对象的引用的数据类型。引用类型的变量存储了对象在内存中的地址,而不是直接存储对象的数据。

C#中常见的引用类型:
1、类类型(class):
class:用户定义的类类型,用于封装数据和方法。
2、字符串类型:
string:用于表示一个或多个字符的字符串。
3、数组类型:
数组(array):用于存储相同类型的元素的集合。
4、接口类型(interface):
interface:定义了一组方法和属性的类型,用于实现多态性。
5、委托类型(delegate):
delegate:用于定义方法的委托类型。

需要注意:
1、引用类型的变量存储的是指向实际数据对象的引用(地址),而不是直接存储数据的值。多个引用变量可以引用同一个数据对象,因此可以在不同的地方操作和修改同一个对象。引用类型的赋值和参数传递是按引用传递的,即传递引用而不是复制整个对象。
2、引用类型的特点是存储在堆上,并且具有动态分配和释放内存的能力。引用类型适合存储复杂的数据结构和大量数据。在使用引用类型时,需要注意空引用的可能性和内存管理的问题,确保值的正确性和安全性。

第4节 表达式和运算符

4.1 表达式 - 操作数与运算符组成

C#中,表达式(expression)是由操作数(operands)和操作符(operators)组成的代码片段,用于计算值。表达式可以是简单的算术运算,也可以是复杂的逻辑判断或函数调用。
表达式在程序中代码中用于计算值、进行逻辑判断、执行函数调用、进行赋值等操作。表达式的结果可以是常量、变量或其他表达式的计算结果。

4.1.2 C#中常见的表达式类型:

1、算术表达式:

加法表达式:a + b
减法表达式:a - b
乘法表达式:a * b
除法表达式:a / b
取余表达式:a % b

2、关系表达式:

等于表达式:a == b
不等于表达式:a != b
大于表达式:a > b
小于表达式:a < b
大于等于表达式:a >= b
小于等于表达式:a <= b

3、逻辑表达式:

逻辑与表达式:a && b
逻辑或表达式:a || b
逻辑非表达式:!a

4、条件表达式:

条件表达式:condition ? trueValue : falseValue

5、赋值表达式:

赋值表达式:a = b
复合赋值表达式:=+, =-, =*, /=, ...

6、函数调用表达式:

函数调用表达式:function(arg1, arg2, ...)

7、成员访问表达式:

成员变量访问表达式:object.member
成员方法调用表达式:object.Method()

8、数组和索引访问表达式:

数组元素访问表达式:array[index]

4.1.2 表达式示例

【示例】按照提示的信息输入,最后系统会打印到屏幕。

Console.WriteLine("请输入您的姓名:");  //输出
string Name = Console.ReadLine();
Console.WriteLine("请输入您的性别:");
string Gender = Console.ReadLine();
Console.WriteLine("请输入您的年龄:");
string Age = Console.ReadLine();
Console.WriteLine("您好,{0}!您是{1}生,您的年龄是{2}岁", Name, Gender, Age);
Console.ReadKey();
//Console.WriteLine("");中双引号中内容可原样输出,但是转义字符以及索引号{i}除外

运行程序:

请输入您的姓名:
程饱饱吃的好饱
请输入您的性别:
男
请输入您的年龄:
24
您好,程饱饱吃的好饱!您是男生,您的年龄是24

4.2 运算符

4.2.1 按操作数个数分类

C#中,运算符可以根据其操作数的个数分为一元二元三元运算符。
1、一元运算符(Unary Operators)
一元运算符只操作一个操作数,有以下常用:
递增运算符 (++), 递减运算符 (–), 正号运算符 (+), 负号运算符 (-), 逻辑非运算符 (!), 位取反运算符 (~) 等。

2、二元运算符(Binary Operators)
二元运算符操作两个操作数,有以下常用:
算术运算符 (+, -, *, /, %), 关系运算符 (==, !=, >, <, >=, <=), 逻辑与运算符 (&&), 逻辑或运算符 (||), 位与运算符 (&), 位或运算符 (|), 位异或运算符 (^), 左移运算符 (<<), 右移运算符 (>>) 等。

3、三元运算符(Ternary Operators)
三元运算符操作三个操作数,C#中仅有一个:
条件运算符 (condition ? trueValue : falseValue)。

4.2.2 按运算类型分类

1、算术运算符:

加法运算符:+
减法运算符:-
乘法运算符:*
除法运算符:/
取余运算符:%

2、关系运算符:

相等运算符:==
不相等运算符:!=
大于运算符:>
小于运算符:<
大于等于运算符:>=
小于等于运算符:<=

3、逻辑运算符:

逻辑与运算符:&&
逻辑或运算符:||
逻辑非运算符:!

4、赋值运算符:

简单赋值运算符:=
复合赋值运算符:+=, -=, *=, /=, %=

5、位运算符:

按位与运算符:&
按位或运算符:|
按位异或运算符:^
按位取反运算符:~
左移运算符:<<
右移运算符:>>

6、条件运算符:

条件表达式运算符:?:

7、成员访问和索引运算符:

成员访问运算符:.
索引访问运算符:[ ]

8、递增和递减运算符:

递增运算符:++
递减运算符:--

【示例】输入语文和数学成绩,打印出总成绩。
程序如下:

Console.WriteLine("请输入语文成绩:");  //输出
double Chinese = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("请输入数学成绩:");
double Math = Convert.ToDouble(Console.ReadLine());
//Convert.ToDouble - 类型转换
//Console>ReadLine();默认是string类型,但是我们声明的变量是double类型,在接收到数据后需要转换类型
Console.WriteLine("你的总成绩是{0}", Chinese + Math);
Console.ReadKey();

执行程序:

请输入语文成绩:
86
请输入数学成绩:
93
你的总成绩是179

4.2.3 对运算符 ++、-- 的使用

++在前,先加再用;++在后,先用后加。(-- 相同)
程序代码:

int var1, var2, var3;
var1 = 2;
Console.WriteLine("var1的值是"+var1);
var2 = var1++;  //先用后加,var2=2,var1=3
Console.WriteLine("var2的值是{0},此时var1的值是{1}" , var2,var1);
var3 = ++var1;	//先加后用,var1=3+1=4,var3=4
Console.WriteLine("var3的值是{0},此时var1的值是{1}" ,var3, var1);
//提示:var1没有重新赋过值,并且一直在使用
Console.ReadKey();

运行程序:

var1的值是2
var2的值是2,此时var1的值是3
var3的值是4,此时var1的值是4

4.2.4 关系运算符:>、 < 、>= 、<=、 != 、==

运算后的结果是布尔值bool,true或者false
关系运算符的运算规则:
① 操作数为数值类型,则比较两个数的大小;
② 操作数为字符类型,则比较两个字符串的Unicode编码大小;
③ 操作数为i盎格字符串,则只能用==或者!=,只能比较字符串各个位字符是否相同

4.2.5 逻辑运算符:&& || ! ^ & |

逻辑符结果
& &全true为true
ll有true为true
取反!true=false;!false=true
^有且只有一个true为true
&全true为true
l有true为true

在运用逻辑运算符表达式中需要注意运算优先级及运算特性,一下程序为例:

int a = 10;
int b = 15;
Console.WriteLine((10 == a++) || (16 == b--));      //结果为 True
Console.WriteLine("a的值为{0},b的值为{1}", a, b); //a=11,b=15
//在||运算后当前面一个表达式为true就不会运算后面表达式,b--没有执行,b=15
Console.ReadKey();

运行程序:

True
a的值为11,b的值为15

结果可见,b的值未发生变化,这是因为在 || 运算后当前面一个表达式为true就不会执行运算后面表达式,所以 b-- 不会被执行。

4.2.6 位运算符:~ 、^、 & 、| 、<<、 >>

运算符结果
~按位取反
l有1为1
&全1为1
^异或:有且仅有一个1为1
<< var3 = var1 << var2 将var1d的值左移var2位赋值给var3
>> var3 = var1 >> var2 将var1d的值右移var2位赋值给var3

如果对十进制数字进行位运算符,需要将其转为二进制数据计算后在转为十进制结果。

【示例】5 & 4 =?
5的二进制表示:101
4的二进制表示:100
5 & 4的结果位:100 即为4

【示例】4 << 1 =?(左移乘2)
4 的二进制表示:100
左移一位后表示:1000 即为8

【示例】4 >> 1 =?(右移除2)
4 的二进制表示:100
右移一位后表示:010 即为2

4.2.7 条件运算符:表达式1?表达式2:表达式3

【示例】根据输入的数量,判断输出输出语句“I have 数量 pen(s)”。
程序代码:

//输出语句“I have 数量 pen(s)”
Console.WriteLine("输入拥有的钢笔数量:");
int qty = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("I have {0} pen{1}", qty, qty > 1 ? "s" : "");
Console.ReadKey();

运行程序:

输入拥有的钢笔数量:
1
I have 1 pen

输入拥有的钢笔数量:
5
I have 5 pens

4.3 对运算符的综合运用

【示例】计算1232855秒是几天几小时几分几秒。
程序代码:

int time = 1232855;
int day = time / (24 * 3600);
int hour = time % (24 * 3600) / 3600;
int min = time % 3600 / 60;
int sec = time % 60;
Console.WriteLine("{0}秒是{1}天{2}小时{3}分种{4}秒", time, day, hour, min, sec);
Console.ReadKey();

运行结果:

1232855秒是146小时27分种35

第5节 流程控制语句

5.1 分支语句

5.1 if 语句

if 语句用于条件判断,其中包含一个布尔表达式,后面跟随着若干要执行的代码,当布尔表达式为真时,后面跟随的代码就会执行,if 语句的语法格式如下:

if(布尔表达式){
    要执行的代码;
}

if 语句流程图:
在这里插入图片描述
【示例】判断一个数是否为偶数

int num = 12;
if (num % 2 == 0)
{
	Console.WriteLine("num的值为偶数");
	//Console.ReadKey();
}
Console.ReadKey();

执行结果:

num的值为偶数

但是当num的值为奇数时,屏幕不会有任何提示,若想打印提示,可以使用if…else语句。

5.2 if…else 语句

if else 语句同样用于条件判断,它比 if 语句中多出了一个 else 语句,当布尔表达式为假时,执行 else 语句块中的代码,语法格式如下所示:

if(布尔表达式){
    表达式为真时要执行的代码;
}else{
    表达式为假时要执行的代码;
}

if else 语句的执行流程如下图所示:
在这里插入图片描述
【示例】用户输入一个数,打印出其偶数性。
程序代码:

Console.WriteLine("输入一个整数:");
int num = int.Parse(Console.ReadLine());
if (num % 2 == 0)
{
	Console.WriteLine("num的值为{0},它是偶数",num);
}
else
{
	Console.WriteLine("num的值为{0},它是奇数",num);
}
Console.ReadKey();

运行程序:

输入一个整数:
45
num的值为45,它是奇数

输入一个整数:
22
num的值为22,它是偶数

5.3 if…else if…else 语句

if else if 语句其实就是一个 if 语句后面跟随着若干个 else if else 语句,语句中可以包含多个条件表达式,程序会依次判断这些条件表达式,当条件表达式为真时则执行后面语句块中的代码,如果没有为真的条件表达式则执行 else 语句块中的代码,其语法格式如下所示:

if(布尔表达式 1){
    布尔表达式 1 为真时要执行的代码;
}else if(布尔表达式 2){
    布尔表达式 2 为真时要执行的代码;
}else if(布尔表达式 3){
    布尔表达式 3 为真时要执行的代码;
}
...
else{
    当所有布尔表达式都为假时要执行的代码;
}

需要注意的是,当布尔表达式为真,且成功执行它后面语句块中的代码后,会跳出 if else if 语句,语句中的其它部分不会再被执行。
if else if 语句的执行流程如下图所示:
在这里插入图片描述
【示例】
程序代码:

Console.WriteLine("请输入1-7判断是星期几:");
int week = int.Parse(Console.ReadLine());
//int.Parse用于将屏幕输入的语句转换为整型
if (week == 1)
	Console.WriteLine("星期一");
else if (week == 2)
	Console.WriteLine("星期二");
else if (week == 3)
	Console.WriteLine("星期三");
else if (week == 4)
	Console.WriteLine("星期四");
else if (week == 5)
	Console.WriteLine("星期五");
else if (week == 6)
	Console.WriteLine("星期六");
else if (week == 7)
	Console.WriteLine("星期日");
else
	Console.WriteLine("输入数值非1-7,重新输入");
Console.ReadKey();

执行程序:

请输入1-7判断是星期几:
5
星期五

请输入1-7判断是星期几:
9
输入数值非1-7,重新输入

5.4 switch 语句

switch 语句类似于if else if 语句,都可以根据表达式执行某个的语句块,其语法格式如下:

switch(表达式){
    case value1:
    //表达式的值为 value1 时,要执行的代码
        break;
    case value2:
    //表达式的值为 value2 时,要执行的代码
        break;
    case value3:
    //表达式的值为 value3 时,要执行的代码
        break;
    ... ...
    default:
    //没有与表达式相匹配的值时,要执行的代码
        break;
}

使用 switch 语句时必须遵守以下规则:

① switch 语句中表达式的值必须是一个整型或者枚举类型;
② 在一个 switch 语句中可以有任意数量的 case 语句,每个case 关键字后面要跟一个与表达式比较的值和一个冒号;
③ case 关键字后面的值必须与 switch中表达式的值具有相同的数据类型,并且必须是一个常量(也可以理解为是一个固定的值,不会随程序的运行发生改变);
④ 当表达式的值等于 case中的值时,就会执行 case 后面的语句,在遇到 break 关键字时停止;
⑤ 当遇到 break 关键字时,switch语句会停止运行,并跳转到 switch 语句以外的下一行代码继续运行;
⑥ 并不是每一个 case 语句后面都需要包含 break关键字,如果 case 语句为空(case 语句后面没有要执行的代码),则可以不包含 break 关键字,这时程序会继续执行后续的 case语句,直至遇到 break 关键字为止;
⑦ C# 不允许从一个 case 语句连续执行到下一个 case 语句,因此如果 case语句中包含要执行的语句,就必须包含 break 关键字或其他跳转语句;
⑧ 一个 switch 语句的末尾可以有一个可选的default(默认选项),当所有 case 语句都不能与表达式相匹配时则会执行 default 部分中的代码,而且 default 中的break 语句可以省略;

switch 语句的执行流程如下图所示:
在这里插入图片描述
【示例】根据用户输入的月份,判断2023年这个月份的天数。
程序代码:

            //判断2023年每个月份的天数
            //31天:1 3 5 7 8 10 12
            //30天:4 6 9 11
            //28天:2

            Console.WriteLine("请输入1-12判断月份天数:");
            int month = int.Parse(Console.ReadLine());
            //int.Parse用于将屏幕输入的语句转换为整型
            switch (month)
            {

                case 2: Console.WriteLine("本月有28天"); break;
                case 4:
                case 6:
                case 9:
                case 11:
                    Console.WriteLine("本月有30天"); break;
                default:
                    Console.WriteLine("本月有31天"); break;
            }
            Console.ReadKey();

运行程序:

请输入1-12判断月份天数:
2
本月有28天

请输入1-12判断月份天数:
12
本月有31

5.2 循环语句(迭代语句)

5.2.1 while循环:在条件为真时重复执行一段代码。

while 循环用于多次迭代一部分程序,特别是在迭代的次数不固定的情况下,建议使用 while 循环而不是 for 循环。while 循环的语法格式如下所示:

while(表达式){
    循环主体;         // 要执行的代码
}

需要注意的是,如果循环条件一开始就为false,那么循环体中的代码将不会执行,循环会被跳过。使用while循环时,需要注意确保在一定条件下循环终止,以避免无限循环。同时,需要适当地更新循环条件,使循环朝着正确的方向进行。其中,循环主体可以是一个单独的语句,也可以是多条语句组成的代码块,当表达式的为真时,循环会一直执行下去。

while 循环的执行流程如下图所示:
在这里插入图片描述
【示例】计算1+2+3+…+99+100的和。
程序代码:

            int i = 1;
            int sum = 0;
            while (i < 101) {
                sum += i;
                i++;
            }
            Console.WriteLine("1-100的和是"+sum);
            Console.ReadKey();

运行程序:

1-100的和是5050

5.2.2 do-while循环:先执行一段代码,然后在条件为真时重复执行。

do-while 循环是一种迭代语句,类似于 while 循环,它在循环体执行后检查条件是否为真。如果条件为真,则重复执行循环体,直到条件为假。
do-while 循环的语法格式如下:

do
{
    // 循环体代码
}
while (condition);

语法说明:
① condition 是一个布尔表达式,表示循环继续执行的条件。循环体先执行一次,然后检查条件。如果条件为真,则继续重复执行循环体;如果条件为假,则循环终止。
② 需要注意的是,do-while 循环至少会执行一次循环体代码,即使条件一开始就为假。这与 while 循环的行为有所不同,因为 while 循环会在开始之前检查条件。
③ 在使用 do-while 循环时,要确保能在循环体内改变条件,确保循环有终止的机制,以避免出现无限循环。同时,根据实际情况,可以根据循环体的执行结果来决定是否继续循环。

【示例1】计算1+2+3+…+99+100的和。
程序代码:

            int i = 1;
            int sum = 0;
            do
            {
                sum += i;
                i++;
            } while (i < 101);
            Console.WriteLine("1-100的和是"+sum);
            Console.ReadKey();

运行程序:

1-100的和是5050

【示例2】输入本金、利率和期待收益,计算多少年可以完成期待收益。
程序代码:

            //银行存款问题
            double Balance = 0;
            double Rate = 0;
            int Year = 0;
            double TargetBalance = 0;
            Console.WriteLine("请输入存款本金:");
            Balance = double.Parse(Console.ReadLine());
            Console.WriteLine("请输入当前利率百分比:");
            Rate = double.Parse(Console.ReadLine()) / 100;
            Console.WriteLine("请输入目标收益:");
            //验证输入有效性
            do
            {
                TargetBalance = double.Parse(Console.ReadLine());
                if (TargetBalance <= Balance)
                    Console.WriteLine("Eorr:目标收益小于等于本金!重新输入目标收益:");
                    
            } while (TargetBalance <= Balance);

            do
            {
                Balance *= (Rate + 1);
                Year++;
            } while (Balance < TargetBalance);
            Console.Write("将会在{0}年内,达到收益{1}元。", Year, Balance);
            Console.ReadKey();
        }

运行程序:

请输入存款本金:
50000
请输入当前利率百分比:
2.5
请输入目标收益:
48000
Eorr:目标收益小于等于本金!重新输目标收益:!
55000
将会在4年内,达到收益55190.64453125元。

5.2.3 for循环:按照特定的计数器条件重复执行一段代码。

for 循环是一种常见的迭代语句,用于在特定的计数器条件下重复执行一段代码。for 循环由三个部分组成:初始化部分、循环条件和迭代部分。

for 循环的语法格式如下:

for (initialization; condition; iteration)
{
    // 循环体代码
}

语法说明:

① initialization 是在循环开始之前执行的初始化语句,用于初始化循环计数器或其它变量。
② condition 是一个布尔表达式,表示循环继续执行的条件。只要条件为真,循环体就会继续执行;一旦条件为假,循环终止。
③ iteration 是在每次循环迭代之后执行的语句,用于更新循环计数器或变量。

for 循环的执行流程如下图所示:
在这里插入图片描述
【示例1】计算用户输入的数求其阶乘值。
程序代码:

            //for循环求阶乘
            //1!=1 2!=2*1 3!=3*2*1
            Console.WriteLine("输入要求的阶乘数值:");
            int a = int.Parse(Console.ReadLine());
            int jc = 1;
            for (int i = 1; i <= a; i++)
            {
                jc *= i;
            }
            Console.WriteLine("{0}!的结果是:{1}", a, jc);
            Console.ReadKey();
        }

运行程序:

输入要求的阶乘数值:
6
6!的结果是:720

【示例2】打印一个九九乘法表。
程序代码:

            Console.WriteLine("=========================九九乘法表==========================");
            for (int i = 1; i <= 9; i++)
            {
                for (int j = 1; j <= i; j++)
                {
                    Console.Write("{0}*{1}={2} ", j, i, i * j);
                    if (i * j < 10)
                        Console.Write(" ");
                }
                Console.WriteLine("");
            }
            Console.WriteLine("==============================================================");
            Console.ReadKey();

执行程序:

=========================九九乘法表==========================
1*1=1
1*2=2  2*2=4
1*3=3  2*3=6  3*3=9
1*4=4  2*4=8  3*4=12 4*4=16
1*5=5  2*5=10 3*5=15 4*5=20 5*5=25
1*6=6  2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7  2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8  2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9  2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
==============================================================

5.2.4 foreach循环:用于遍历集合或数组中的元素。

foreach 循环用于遍历集合或数组中的元素,它可以自动迭代集合中的每个元素,而无需手动控制迭代器或索引。foreach 循环提供了一种简洁和直观的方式来遍历集合。

foreach 循环的语法格式如下:

foreach (var item in collection)
{
    // 循环体代码
}

语法说明:

① item 是用于表示集合中当前元素的变量,在每次迭代中被赋值为集合中的下一个元素。
② collection 是要遍历的集合,可以是数组、列表、字典等可枚举的数据结构。在每次迭代中,item 变量被赋值为集合中的下一个元素,直到遍历完所有元素为止。
③ 以下是一个示例,展示了使用 foreach 循环遍历数组中的元素并求和的例子:
④ 要注意foreach 循环只用于遍历集合或数组,不提供对集合中元素的修改操作。如果需要修改集合中的元素,可以使用传统的 for 循环或其他方式进行操作。

【示例】用户输入一个语句,根据空格剪切出单词换行输出。
程序代码:

            Console.WriteLine("输入一个语句:");
            string str = Console.ReadLine();
            foreach (char word in str)
            {
                if (char.IsWhiteSpace(word))
                {
                    Console.WriteLine();    //仅换行
                }
                else
                {
                    Console.Write(word);    //遇到空格前不换行输出
                }
            }
            Console.ReadKey();

运行程序:

输入一个语句:
my name is flyer.cheng nice to meet you !
my
name
is
flyer.cheng
nice
to
meet
you
!

5.3 跳转语句

5.3.1 break语句:终止循环或switch语句的执行。

break 语句在前面switch 语句的时候已经有了简单的了解,它不仅可以用来终止 switch 语句,在循环语句中使用时还可以用来跳出循环,执行循环外的下一条语句。
如果是在嵌套循环中使用,例如在内层的循环中使用 break 语句,那么程序只会跳出内层的循环,并不会影响到外层循环的执行。
break 语句的执行原理如下图所示:
在这里插入图片描述

【示例】输出1-100的数字,每行10个,同时为3、4、5的倍数时退出循环并提示。
程序代码:

            //输出1-100的数字,每行10个,同时为3、4、5的倍数时退出
            Console.WriteLine("输出1-100的数字,每行10个,同时为3、4、5的倍数时退出:");
            for (int i = 1; i < 101; i++)
            {
                if ((i % 3 == 0) && (i % 4 == 0) && (i % 5 == 0))
                {
                    Console.WriteLine( );
                    Console.WriteLine("3、4、5公倍数倍数是{0},此时跳出循环。",i);
                    break;
                }
                   
                if (i % 10 == 0)
                    Console.WriteLine(i);
                else
                {
                    if (i < 10)
                        Console.Write(" " + i + " ");
                    else
                        Console.Write(i + " ");
                }

            }
            Console.ReadKey();

运行程序:

输出1-100的数字,每行10个,同时为345的倍数时退出:
 1  2  3  4  5  6  7  8  9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59
345公倍数倍数是60,此时跳出循环。

5.3.2 continue语句:跳过当前循环迭代,继续执行下一次迭代。

continue 语句的工作原理与 break 语句类似,但是 continue 语句并不会跳出整个循环,而是跳过本次循环继续执行下一次的循环。
continue 的执行原理如下图所示:
在这里插入图片描述
【示例】输出1-100的数字,每行10个,同时为3、4的倍数时跳过,用**取代。
程序代码:

            //输出1-100的数字,每行10个,同时为3、4的倍数时跳过,用**取代
            Console.WriteLine("输出1-100的数字,每行10个,同时为3、4的倍数时跳过:");
            for (int i = 1; i < 101; i++)
            {
                if ((i % 3 == 0) && (i % 4 == 0)) //&&(i % 5 == 0)
                {
                    if (i % 10 == 0)
                        Console.WriteLine("**" + " ");
                    else
                        Console.Write("**" + " ");
                    continue;
                }
                if (i % 10 == 0)
                    Console.WriteLine(i);
                else
                {
                    if (i < 10)
                        Console.Write(" " + i + " ");
                    else
                        Console.Write(i + " ");
                }

            }
            Console.ReadKey();

运行程序:

输出1-100的数字,每行10个,同时为34的倍数时跳过:
 1  2  3  4  5  6  7  8  9 10
11 ** 13 14 15 16 17 18 19 20
21 22 23 ** 25 26 27 28 29 30
31 32 33 34 35 ** 37 38 39 40
41 42 43 44 45 46 47 ** 49 50
51 52 53 54 55 56 57 58 59 **
61 62 63 64 65 66 67 68 69 70
71 ** 73 74 75 76 77 78 79 80
81 82 83 ** 85 86 87 88 89 90
91 92 93 94 95 ** 97 98 99 100

5.3.3 return语句:用于从方法中返回值并停止方法的执行。

跳转语句 return 用于在方法中提前返回结果并终止方法的执行。当使用 return 语句时,程序会立即退出当前方法,并返回指定的值(如果有)给调用者。

return 语句的用法有3种:返回一个值;无返回值;提前终止方法;

说明:
return用法:退出整个main函数
return语句只能出现在方法当中,当调用方法时,执行到return语句时,直接跳转到Main( )函数。
return 语句终止它出现在其中的方法的执行并将控制返回给调用方法。它还可以返回一个可选值。
④ 如果方法为 void 类型,则可以省略 return 语句

【示例】(有返回值)输入三个数,求平均值。
程序代码:

using System;
namespace return语句
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("输入三个数求平均值");
            Console.WriteLine("输入第一个数:");
            int num1 = int.Parse(Console.ReadLine());
            Console.WriteLine("输入第二个数:");
            int num2 = int.Parse(Console.ReadLine());
            Console.WriteLine("输入第三个数:");
            int num3 = int.Parse(Console.ReadLine());

            double avg = fun_avg(num1,num2,num3);
            Console.WriteLine("三个数的平均值是:" + avg);
            Console.ReadKey();
        }
		//1、return有返回值时
        static double fun_avg(int a,int b,int c) {
            return (a+b+c) / 3;
        }

    }
}

运行程序:

输入三个数求平均值
输入第一个数:
37
输入第二个数:
29
输入第三个数:
42
三个数的平均值是:36

【示例】(无返回值)输入三个数,求平均值。
程序代码:

using System;
namespace return语句
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("输入三个数求平均值");
            Console.WriteLine("输入第一个数:");
            int num1 = int.Parse(Console.ReadLine());
            Console.WriteLine("输入第二个数:");
            int num2 = int.Parse(Console.ReadLine());
            Console.WriteLine("输入第三个数:");
            int num3 = int.Parse(Console.ReadLine()); 
            fun_avg(num1,num2,num3);
            Console.ReadKey();
        }
        //2、return不带返回值时
        static void fun_avg(int a, int b, int c)
        {
            Console.WriteLine("三个数的平均值是:{0}", (a + b + c) / 3);
            return;
        }
    }
}

运行程序:

输入三个数求平均值
输入第一个数:
19
输入第二个数:
53
输入第三个数:
48
三个数的平均值是:40

程序说明:
return语句只能出现在方法当中,当调用方法时,执行到return语句时,直接跳转到Main( )函数。

5.3.4 goto语句:跳转到指定的标签位置继续执行代码。

goto 语句是一种跳转语句,用于将程序的控制转移到指定的标签处,从而改变执行流程。虽然 goto 语句在某些情况下可以提供一种跳转的方式,但由于容易造成代码结构混乱和可读性差的问题,一般不建议过多使用

goto 语句的语法:

goto label;
// ...
label: statement;

语法说明:
label 是一个标签,用于标记代码中的位置。它由一个冒号和标识符组成,标识符可以是任意有效的名称。statement 是要执行的语句。

goto 语句来实现了一个简单的循环。程序使用标签 start 标记循环的入口,在每次迭代后通过 goto start; 语句将控制转移到标签处,从而实现了循环的目的。goto 语句可以实现代码跳转,但过多使用会对代码的可读性和维护性产生负面影响。建议在大多数情况下使用结构化的控制流语句(如 ifforwhiledo-while),它们提供了更清晰和易于理解的代码结构。只在极少数情况下,当必要时再使用 goto 语句。为了提高代码的可读性和可维护性,应该遵循一致的代码风格和最佳实践,并避免滥用 goto 语句。

【示例1】打印1-5:

int i = 0;
start:
i++;
Console.WriteLine(i);
if (i < 5)
    goto start;

【示例2】模拟一个账号密码登陆场景。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace goto语句
{
    class Program
    {
        static void Main(string[] args)
        {
            int count = 1;
        login:
            Console.WriteLine("请输入用户名");
            string username = Console.ReadLine();
            Console.WriteLine("请输入密码");
            string userpwd = Console.ReadLine();
            if (username == "flyer" && userpwd == "123123")
            {
                Console.WriteLine("登录成功");
            }
            else
            {
                count++;
                if (count > 3)
                {
                    Console.WriteLine("用户名或密码错误次数超过3次!退出程序!");
                }
                else
                {
                    Console.WriteLine("用户名或密码错误");
                    goto login;//返回login标签处重新输入用户名密码
                }
            }

            Console.ReadKey();

        }
    }
}

运行程序(错误输入):

请输入用户名
fly
请输入密码
123123
用户名或密码错误
请输入用户名
flyer
请输入密码
13
用户名或密码错误
请输入用户名
flye
请输入密码
12312
用户名或密码错误次数超过3次!退出程序!

运行程序(正确输入):

请输入用户名
flyer
请输入密码
123123
登录成功

第6节 字符与字符串

6.1 字符、转义字符及字符串简介

在C#中,字符以单引号(' ')括起来,例如’a’、‘b’、'c’等。字符类型数据char只能表示一个字符。
转义字符是一种特殊的字符序列,由反斜杠(\)后面跟着一个或多个字符组成。它们被用来表示一些特殊的字符或执行一些特定的操作。

以下是一些常见的转义字符:

\n:换行符
\r:回车符
\t:制表符
\':单引号
\":双引号
\\:反斜杠

字符串由0个或多个字符组成的有限序列,是System.String类的一个引用类型,在C#中是一个基本类型,可以申明为一个变量并赋值。string类型变量可以看作是char变量的只读数组

6.3 字符串的大小写转换

ToUpper( )ToLower( )方法来转换字符串的大小写:
ToUpper( )方法将字符串中的所有字符转换为大写形式,而ToLower( )方法将字符串中的所有字符转换为小写形式。

大小写转换的示例:

string str = "Hello World";
string upperCase = str.ToUpper();      // "HELLO WORLD"
string lowerCase = str.ToLower();      // "hello world"

这两个方法会创建一个新的字符串对象,并返回转换后的副本,原始字符串对象的值不会改变。所以需要将转换后的结果赋给一个新的字符串变量。

此外,还可以使用InvariantCultureIgnoreCase属性在不考虑区域性的情况下进行不区分大小写的比较,例如:

string str1 = "Hello";
string str2 = "HELLO";
bool equalsIgnoreCase = string.Equals(str1, str2, StringComparison.InvariantCultureIgnoreCase);
// true

这里string.Equals( )方法的第三个参数指定了比较时忽略大小写的方式。

6.4 字符串的比较

字符串比较有以下几种方法:
str1 == str2:这种方式使用运算符==来比较两个字符串的内容是否相等。返回一个布尔值,如果相等则为true,否则为false。这是最常见的字符串比较方法。

//使用运算符进行字符串比较:
string str1 = "Hello";
string str2 = "World";

bool isEqual = (str1 == str2);                            // false
bool isEqualIgnoreCase = (str1.Equals(str2, StringComparison.OrdinalIgnoreCase));  // false

string.Equals(str1,str2):这种方式使用Equals( )方法来比较两个字符串的内容是否相等。返回一个布尔值,如果相等则为true,否则为false。还可以通过第三个参数指定字符串比较的规则(大小写敏感或不敏感)。

//使用Equals()方法进行字符串比较:

string str1 = "Hello";
string str2 = "World";

bool isEqual = string.Equals(str1, str2);                       // false
bool isEqualIgnoreCase = string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase);  // false

string.Compare(str1,str2)
比较str1和str2的大小关系,返回一个整数值。如果str1小于str2,则返回一个负数;如果str1大于str2,则返回一个正数;如果两个字符串相等,则返回0。

int result = string.Compare("apple", "banana");
// result < 0,因为"apple"在字母排序中小于"banana"

Compare(str1,str2, bool): 指定是否进行大小写不敏感的比较。如果bool为true,则进行大小写不敏感的比较;如果为false,则进行大小写敏感的比较。

int result = string.Compare("apple", "APPLE", true);
// result = 0,因为不区分大小写,"apple"和"APPLE"被认为是相等的

Compare(str1, index1,str2, index2, length): 比较指定位置开始的一部分字符,可以比较字符串中的子串。

int result = string.Compare("apple", 1, "banana", 3, 2);
// result < 0,因为"pp"在字母排序中小于"an"

str1.CompareTo(str2):这种方式是通过使用CompareTo( )方法比较两个字符串的大小关系。返回一个整数值,表示两个字符串的比较结果。如果str1小于str2,则返回一个负数;如果str1大于str2,则返回一个正数;如果两个字符串相等,则返回0。

6.5 字符串的格式化

字符串格式化是一种用于将变量的值插入到字符串中的技术,使其更具可读性和可维护性。C#提供了多种字符串格式化的方法,以下是其中几种常见的方式:

1、插值字符串(Interpolated Strings):
使用 $ 符号和花括号 { } 来插入变量的值到字符串中。

string name = "Flyer";
int age = 24;
Console.WriteLine($"My name is {name} and I'm {age} years old.");

2、字符串格式化方法(String.Format):
使用 String.Format 方法将提供的参数按照指定的格式转换并插入到字符串中。

string name = "Flyer";
int age = 24;
Console.WriteLine("My name is {0} and I'm {1} years old.", name, age);

3、占位符(Placeholders):
使用大括号 { } 中的数字或名称来标识要插入的变量位置,用后面提供的参数替换。

string name = "Flyer";
int age = 24;
string message = "My name is {0} and I'm {1} years old.";
string formattedMessage = String.Format(message, name, age);

4、格式化字符串(Format Strings):
使用 { } 内的格式化规范来指定要插入值的具体显示方式,如数字格式、日期格式等。

decimal price = 19.99m;
DateTime date = DateTime.Now;
Console.WriteLine($"The price is {price:C2} and the date is {date:yyyy-MM-dd}.");

【示例】打印出001-050。

 //输出格式化字符串 001-050
            for(int i=1;i<=50;i++)
            {
                string mystr = string.Format("{0:D3}",i);
                Console.Write(mystr+" ");
                if(i%10 == 0)
                    Console.WriteLine( );
            }

            Console.ReadKey();

执行程序:

001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027 028 029 030
031 032 033 034 035 036 037 038 039 040
041 042 043 044 045 046 047 048 049 050

6.6 字符串的截取

字符串截取函数:

Substring(n);
Substring(n,m);

Substring( )方法可用于从给定的字符串中返回一个新的字符串,该新字符串包含从指定索引开始的一定数量的字符。Substring( ) 方法还可以使用负数索引。例如,Substring(-5) 表示从倒数第5个字符开始截取到字符串末尾。

string str = "Hello, world!";
string substr1 = str.Substring(7); // 从索引为7的位置开始截取,返回 "world!"

string substr2 = str.Substring(7, 5); // 从索引为7的位置开始截取,截取长度为5,返回 "world"

//字符串的起始位是0

Substring( ) 方法的第一个参数是截取的起始索引,第二个可选参数是截取的长度。如果没有提供第二个参数,则默认截取到字符串的末尾。
其他的方法可以用于字符串截取或提取子字符串,例如:
Remove(startIndex):从字符串中移除从指定索引开始的所有字符,并返回结果字符串。
Remove(startIndex, length):从字符串中移除从指定索引开始,指定长度的字符,并返回结果字符串。
【示例】

//1、字符串截取
            Console.WriteLine("//1、字符串截取");
            string str = "Hello, world!";
            string substr1 = str.Substring(7); // 从索引为7的位置开始截取,返回 "world!"
            string substr2 = str.Substring(7, 5); // 从索引为7的位置开始截取,截取长度为5,返回 "world"
            //字符串的起始位是0
            Console.WriteLine("substr1的返回结果是:{0}\nsubstr2的返回结果是:{1}",substr1,substr2);
            Console.WriteLine("");
            //2、对单词格式化处理,将首字母大写,其余字母小写
            Console.WriteLine("//2、对单词格式化处理,将首字母大写,其余字母小写");
            Console.WriteLine("输入一个英文单词字符串,不区分大小写:");
            string word = Console.ReadLine();       //cHIpTIcKs
            string firstWord = word.Substring(0,1).ToUpper();   //截取首字母,转换为大写
            string otherWord =  word.Substring(1).ToLower();    //截取除首字母以外的字符串
            Console.WriteLine("处理前的单词:{0}",word);
            Console.WriteLine("处理后的单词:{0}{1}",firstWord,otherWord);
            Console.WriteLine("");

运行程序:

//1、字符串截取
substr1的返回结果是:world!
substr2的返回结果是:world

//2、对单词格式化处理,将首字母大写,其余字母小写
输入一个英文单词字符串,不区分大小写:
cHIpTIcKs
处理前的单词:cHIpTIcKs
处理后的单词:Chipticks

6.7 字符串的分割

字符串分割方法Split( )
Split( ) 方法来分割一个字符串为子字符串数组,基于指定的分隔符将字符串拆分成多个部分。
【示例1】

string str = "apple,banana,orange";
string[] fruits = str.Split(',');

foreach (string fruit in fruits)
{
    Console.WriteLine(fruit);
}

使用 Split(‘,’) 方法将字符串 str 按照逗号分隔符进行分割,将其拆分成了一个包含三个元素的子字符串数组。在 foreach 循环中逐个打印出了拆分后的子字符串。除了逗号也可以使用其他字符或字符串作为分隔符来进行字符串的切割。例如,使用空格作为分隔符,可以将 Split(’ ') 作为参数传递给 Split( ) 方法。Split( ) 方法还支持使用字符数组作为分隔符,例如 Split(new char[] { ‘,’, ‘;’ }),可以同时使用逗号和分号进行字符串的分割。

【示例2】

            string myInfo = "Flyer.Cheng-Man-24.unv_bk.CV_engger-1888888888";
            string[] SpMyInfos = myInfo.Split(new char[] { '.' ,'-'});

            foreach (string SpMyInfo in SpMyInfos)
            {
                Console.WriteLine(SpMyInfo+" ");
            }
            Console.ReadKey();

运行程序:

Flyer
Cheng
Man
24
unv_bk
CV_engger
1888888888

6.8 字符串的合并

字符串合并

1、+ 运算符:使用 + 运算符可以将两个字符串连接起来。

string str1 = "Hello";
string str2 = "World";
string result = str1 + " " + str2; // "Hello World"

2、string.Concat( ) 方法:使用 string.Concat( ) 方法可以连接多个字符串。

string str1 = "Hello";
string str2 = "World";
string result = string.Concat(str1, " ", str2); // "Hello World"

3、string.Join( ) 方法:使用 string.Join( ) 方法可以将一个字符串数组或集合中的字符串连接起来,中间使用指定的分隔符。

string[] words = { "Hello", "World" };
string result = string.Join(" ", words); // "Hello World"

4、StringBuilder 类StringBuilder 类提供了高效的字符串操作,特别适用于频繁修改字符串的情况。

StringBuilder sb = new StringBuilder();
sb.Append("Hello");
sb.Append(" ");
sb.Append("World");
string result = sb.ToString(); // "Hello World"

【示例】
程序代码:

            string str1 = "Hello ";
            string str2 = "world ";
            string str3 = "C# ";

            Console.WriteLine("使用<+>运算符连接:\n{0}\n", str1+str2+str1+str3);
            Console.WriteLine("使用<Concat>方法连接:\n{0}\n", string.Concat(str1,str2,str1,str3));
            
            string[] myStrArry = { "My", "name", "is", "flyer" };
            Console.WriteLine("使用<Join>方法连接:\n{0}\n", string.Join("**",myStrArry));

            Console.ReadKey();

运行程序:

使用<+>运算符连接:
Hello world Hello C#

使用<Concat>方法连接:
Hello world Hello C#

使用<Join>方法连接:
My**name**is**flyer

6.9 字符串的插入与填充

字符串的插入与填充

插入:Insert方法

str1.Insert(n,str2);//n是插入插入字符串str1的位置,str2是插入的内容

填充:PadRight PadLeft

str1.PadRight(n,str2);//n是填充后字符串的目标长度,str2是要填充的字符。
str1.PadLeft(n,str2);//n是填充后字符串的目标长度,str2是要填充的字符。
//如果原始字符串的长度已经大于或等于目标长度,这些方法将不会产生任何变化,并返回原始字符串。

1、PadLeft( ) 方法:
使用 PadLeft( ) 方法在字符串的开头填充指定的字符,使字符串的长度达到指定的长度。

string str = "Hello";
string paddedStr = str.PadLeft(10, '-');
Console.WriteLine(paddedStr); // 输出 "-----Hello"

2、PadRight( ) 方法:
使用 PadRight() 方法在字符串的末尾填充指定的字符,使字符串的长度达到指定的长度。

string str = "Hello";
string paddedStr = str.PadRight(10, '-');
Console.WriteLine(paddedStr); // 输出 "Hello-----"

【示例】

//1、字符串插入
            Console.WriteLine("1、字符串插入");
            string str1 = "www..com";
            string website = str1.Insert(4,"baidu");
            Console.WriteLine("插入后的网址为:\n{0}", website);

            //2、字符串填充
            Console.WriteLine("2、字符串填充");
            string str2 = "=====table";
            string info = str2.PadRight(15, '=');
            Console.WriteLine("填充后的字符串为:\n{0}", info);

            Console.ReadKey();

运行程序:

1、字符串插入
插入后的网址为:
www.baidu.com
2、字符串填充
填充后的字符串为:
=====table=====

6.10 字符串的删除

字符串的删除Remove( )方法:

str1.Remove(n);//n为str1索引号,删除此索引号后面的所有字符
str1.Remove(n,m);//n为str1索引号,m是删除字符个数,删除n索引号后面的m个字符

1、Remove( ) 方法:
使用 Remove() 方法可以从字符串中移除指定索引位置开始的一定数量的字符,返回移除后的新字符串。

string str = "Hello, World!";
string removedStr = str.Remove(7, 6); // 从索引位置 7 开始,移除 6 个字符
Console.WriteLine(removedStr); // 输出 "Hello!"

2、Substring( ) 方法:
使用 Substring() 方法可以获取字符串的一个子串,移除指定的部分。你可以选择保留子串的某一部分或反转切割后的子串。

string str = "Hello, World!";
string removedStr = str.Substring(0, 7); // 从索引位置 0 开始,截取 7 个字符
Console.WriteLine(removedStr); // 输出 "Hello, "

Remove( ) 方法和 Substring( ) 方法都返回一个新的字符串,原始字符串本身不会改变。

【示例】

            //3、字符串的移除
            Console.WriteLine("//3、字符串的移除");
            string webstr = "https://fanyi.baidu.com/?aldtype=16047#zh/en/%E7%BD%91%E5%9D%80%0A%E5%9C%B0%E5%9D%80";
            string website = webstr.Remove(23);
            Console.WriteLine("<Remove>移除后的字符串:{0}",website);
            Console.WriteLine("<Substring>截取后的字符串:{0}", webstr.Substring(0,23));
            Console.WriteLine("");

运行程序:

//3、字符串的移除
<Remove>移除后的字符串:https://fanyi.baidu.com
<Substring>截取后的字符串:https://fanyi.baidu.com

6.11 字符串修剪

6.12 字符串的复制

6.13 字符串的替换

6.14 字符串的查找

6.15 类型转换

6.16 StringBuilder类

在IntelliJ IDEA中,"Invalidate Caches"是一种修复缓存异常的方法。当IDEA中的缓存出现损坏或异常时,可以执行"Invalidate Caches/Restart"来尝试修复这些问题。这个操作会删除原来的缓存和索引,然后重新构建缓存和索引。通过这个方法,可以解决由缓存问题引起的各种奇怪行为或错误。\[1\]所以,如果你在使用IDEA时遇到了缓存相关的问题,可以尝试执行"Invalidate Caches/Restart"来解决。\[2\]\[3\] #### 引用[.reference_title] - *1* [IDEA 工具中 Invalidate Caches/Restart功能详解](https://blog.csdn.net/ranbo_Q/article/details/131175077)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [有关Idea的Invalidate Caches/Restart](https://blog.csdn.net/qq_43733781/article/details/123791274)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Idea突然不停indexing的问题 && 清理idea缓存](https://blog.csdn.net/weixin_30273175/article/details/99427649)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程饱饱吃得好饱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值