.NET 基础串讲

时间:2023-03-08 17:11:21

C#基础

.NET介绍

—计算机发展史

第一代语言:机器语言 0101

第二代语言:汇编语言, 用一些简洁的英文字母、符号串来替代一个特定指令的二进制串

第三代语言:接近于数学语言或人的自然语言,同时又不依赖于计算机硬件,编出的程序能在所有机器上通用

—编译运行过程:

C#语言—公共语言规范(CLS)的编译器—MSIL(中间语言或程序集)

—公共语言运行库(CLR)中编译器—操作系统执行代码

—两次编译过程用途:

第一次是为了将不同语言编译成中间语言形成程序集;

第二次为了CLR针对不同操作系统做优化。

转义符

改变了字符的原始含义。

引号——\“”换行——\n    水平制表——\t     问号——\?

反斜线——\\     加多个反斜线(防止转义)——@“字符串”

格式化字符串

变量

程序运行在哪里?

程序处理的是什么?

1、定义

—内存中开辟的一块用于存储数据的空间

—可以存放单词、数值、日期以及属性。

2、声明

—变量类型 变量名称;

—也可以一次声明多个变量。string str1, str2;

3、命名规则

—有字母、数字和下划线组成,且不能以数字开头。

—不能使用保留关键字(蓝色)。

4、建议命名规则

【望文生义】

—以小写字母开头。

—如果包括多个单词,建议除第一个单词外其他单词的首字母大写。

—增加类型前缀便于理解。

5、变量的赋值

—在使用前必须赋值。

—赋值的数据类型和变量声明时的类型必须相同

—同一变量名只能声明一次,但可以多次赋值。

6、数据类型

1)整形

2)非整型(小数)

—非整形变量赋值要加上后缀,如果不加默认为double

3)非数值型

—Char 字符,存储单个字符,使用单引号。

—Bool类型  可以直接赋值true真false假,或者赋表达式做判断。

7、占位符

运算符

1、算数运算符

+  —   *  /  %  ++ --

—i++、++i

i++,后缀增量操作。表达式结果是操作数增加之前的值,后加:后自增。

++i,前缀。表达式结果是操作数加1之后的值,先加:先自增。

2、比较运算符

— >  <  >=  <=  ==  !=

3、逻辑运算符

—&&——与   一假俱假   相当于“并且”  都得是真的

—||——或   一真俱真   相当于“或者”  有一个是真的就行

—!——非   原来是真,非后为假

4、快捷运算符

+= -= *= /= %=

数据类型转换

变量声明后,类型固定了,只能赋值某种类型的数值,如果要赋值其他类型的值需要转换类型。

1、隐式转换(数值类型间转换):由小范围(空间)到大范围的数值类型转换。不会失败,不会丢失精度,一般发生在数值类型间。

2、显式转换(强制转换):(数值类型间转换)存在风险,由程序员决定是非转换。还可能会丢失精度。

语法: 新类型 名称=(待转类型名)名称

.NET默认不检测强制转换错误,使用checked代码块可以检测强制转换错误。

3、parse(转出)将字符串转换对应的类型:内置的数据类型都提供了parse方法,用来实现字符串和对应类型的转换。

int a=int.Parse(“1”);

Double d=double.Parse(“1”);

4ToString(转入)从其他类型到字符串:

5、Convert转换:任意两种类型之间的转换 int i2 = Convert.ToInt32("9");

常量

—内容不发生变化的值

—使用const声明; 如:

—建议命名全部大写以区分

方法

1、定义:方法就是对一系列语句的命名,表示一个行为或功能。

2、作用:代码的重用,实现模块式开发

3、语法

如Public、private             声明静态:static     /*给一个参数返回一个结果值*/

访问级别 [可选修饰符] 返回类型 方法名称(参数类型 参数名称)

{

//方法体

Return 结果;

}

无返回值声明为void              参数列表

4、调用语句:方法名称(参数)

5、返回值:理解为方法的结果

—void代表无返回值。

—如果方法有返回值,方法体中必须有return语句;没有返回值,有没有都可以。

—Return关键字后必须返回相同类型的数据。

—Return后面的语句不再执行。

—调用方法时,如果需要结果,声明相应类型变量接收返回值数据。

6、参数列表:方法设计者需要调用者传递的信息

—定义方法时叫形参

—调用方法是叫实参

—实参与形参要一一对应

—确定参数的原则:自己能确定的数据自己内部解决,自己确定不了的数据通过参数传递。

7、方法尽可能小,以便完成一个独立的工作。

8、可以调用同一个类或者其他类中的方法;内部也可以调用其他方法。

参数

1、值参数

—方法默认值传递,传递的是变量的副本。

—值类型参数传递给方法时,传递的是数据的副本而不是数据本身。

—方法内部对形式参数的修改,不会影响方法外的实际参数。

2、引用参数

—将引用类型的对象传递给方法时,引用类型的变量不直接包含其数据;它包含的是对其数据的引用(地址),即引用指向原始对象而不是副本。ref是关键字。

—方法内修改形式参数,会影响实际参数。

—在方法中修改外面已有变量时使用,更侧重于改变一个。

/*添加了ref,两个参数就一致了。*/

3、输出参数

—Out关键字会导致参数通过引用来传递。这与ref关键字类似。若要使用out参数,方法定义和调用方法都必须使用out关键字。

—侧重于输出一个值。

4、区别

Ref要求变量必须在传递前进行初始化(赋初值)。而作为out参数传递的变量不必在传递之前进行初始化,但是在离开方法之前,必须为变量赋值,有赋值操作。

5、用途

方法需要返回多个值时使用。

TryParse

—通过Bool表达式配合TryParse使用,防止类型转换失败。

—语法:    TryParse(待转字符串,out 转出的变量名)

方法重载

—方法签名:方法的访问级别、可选修饰符 、返回值、名称和任何方法参数,统称为方法的“签名”。

—方法重载:在同一个作用域中,两个方法的名称相同,参数列表(个数、类型)不同称为方法重载(OverLoad)。用来解决同一类型的问题。[out与ref的区别不可以构成]

—作用:减少记忆量,方便使用,便于理解

选择语句

If语句

If(bool表达式)

{

//表达式为真,执行

}

else

{

//表达式为假执行

}

—C#规定,每个else部分分总属于前面最近的那个缺少对应的else部分的if语句。

—注意:Else可有可无;

单行语句可以不写{},但是提倡单行也要写;

If条件后不能加分号;

Switch-case语句

—多路判断语句

—计算条件表达式并对照多个常数值进行检查

1、注意

—Break不能少

—Switch()中的变量可以是int、string、bool、char、枚举类型,

但必须有一个定值。

—每个case标签后是常量表达式的值,不必连续,也不必按特定

顺序排列,但不能相同,否则会出现错误。

—每个case标签之后的语句数不限,有多个语句,也可以不用{}。

—default标签可选。意思是其余的结果。

2、区别

—相同点:都可以用来实现多路分支。

—不同点

多重if结构用来实现两路、三路分支比较方便,Switch结构实现三路以上分支比较方便。

If结构用来判断一个值是否在某个区间的情况,在使用switch时,case语句后面必须是常量表达式

循环语句

For语句

要求只在对特点条件进行判断后才允许执行循环,用于将某个语句或语句块重复执行预定次数的情形。

For(初始值;条件;增减变量)

{

…………z

}

—首先赋初值,只执行一次。

—判断条件表达式是否满足,如果是执行{}内语句,如果不是,退出循环。

—每次执行完循环体内的语句都要执行增减变量。

—break用于退出循环

—continue用于跳出当前循环并开始本for的下一次循环。

—可以有死循环for(;;)

例子:

While语句

While(条件true)

{

//退出条件

//语句

}

—执行一个语句或语句块,直到指定的表达式计算为false退出循环。

—先判断表达式是否满足条件,是,执行语句;否,退出。

—大多数情况下,while语句可以和for语句互换,while常用语计算次数不确定的情形。

Do While语句

Do

{

//循环体

}

While(条件)

—重复执行{}内的语句,直到指定的表达式为false退出。

—与while区别:循环体至少执行一次。

循环嵌套

例子:正三角

例子:倒三角                                           正三角:

例子:乘法表

数组

—定义:存放一组类型相同的变量,是一种空间连续的数据结构。

—这些变量都可以通过计算索引(位置)进行访问。

数组属性

—数组的索引从零开始,具有n个元素(变量)的数组的索引时从0到n-1(因为从0开始).

—数组元素可以使任何类型,包括数组类型(数组嵌套)。

—数组类型是从抽象基类型Array派生的引用类型。

—可以对c#中的所有数组使用foreach遍历。

数组类型

一维数组

多维数组(有行还有列或者高)

交错数组

声明赋值数组的语法

●数组声明后必须赋值才能使用。

●访问数组,通过索引,使用for、foreach循环遍历。

●For循环可以读取、设置元素值,不必访问所有元素。

●循环遍历的方法:foreach和for

Foreach循环,不能对元素赋值,按顺序依次遍历,不能跳跃,拿不到索引。

数组常用方法及属性

1、 Length 长度

获取32位整数,该整数表示Array的所有维数中元素的总值。

语法:数组名称.Length

2、 Rank 维度

获取Array的维数。

语法:数组名称.Rank

3、 Array.Clear()清除元素值

将数组中的元素设置为0、null或fasle,具体取决于数组元素的数据类型。

语法:Array.Clear(被清除坐标数组名称,起始坐标,结束坐标)

4、 Array.copy 复制

将一个数组的一部分元素复制到另一个数组中,从索引0开始复制一定长度的元素。

语法:Array.Copy(被复制的数组名,复制到的数组名, 元素个数);

5、 CopyTo 复制

将源数组元素内容复制到目标数组,从目标数组的某个索引处开始到结束复制,目标数组长度必须大于等于源数组长度。

语法:源数组名称.CopyTo(目标数组名,目标数组开始复制的元素位置)

注意:目标数组长度必须大于源数组;

从设定的起始元素起替换目标数组元素,目标数组大于源数组的的内容将保留

6、 Clone 克隆

克隆是将已知数组复制给新定义的数组,所以需要声明新数组用于接收;

克隆必须进行强制转换,即:(数组类型[])

语法:新定义的数组=(数组类型[])目标数组名.Clone();

7、 Array.IndexOf() 正向查找第一个匹配项的索引(元素位置)

Array.LastIndexOf(  ) 反向查找第一个匹配项的索引

返回一对数组或部分数组中某个值第一个匹配项的索引,找不到返回-1。

语法:Array.IndexOf(数组名称,元素)

8、Array.Sort() 排序

语法:Array.Sort(数组名称)

9、Array.Reverse()  反转

反转数组中元素的顺序

语法:Array.Reverse(需要反转的数组名称)

练习:冒泡排序

两两比较,大的放到后

2  8  6  1

第一轮:

2 6 1 8  比较3次   4-1

第二轮:

2 1 6 8  比较2次   4-2

第三轮:

1 2 6 8  比较1次   4-3

4个数比较

4-1轮

每轮:元素总数-当前轮数(i+1)

二维数组

●二维数组就像具有行和列的表格。

●二维数组具有两个索引,分别代表行(前面)、列(后面)。

●int[,] score=new int[5,2];

声明初始化赋值

读取赋值

名称[行,列]

属性

练习:5个学生参加了2门课的考试,统计出每个学生平均成绩,2门课的平均成绩。

交错数组

●交错数组就是元素为数组的数组(数组的嵌套)。

●交错数组元素大小可以不同(元素就是数组,指的是交错数组中的数组大小可以不同)。

●声明一个由5个元素组成的一维数组,其中每个元素都是一个一维整数数组。

●Int[][] score =new int [5][]                   5为外围数组(行)   []为内在数组

练习:录入学生个数,考试科目数量,及相应成绩

Params参数数组

●通过关键字params定义参数数组

●用于方法参数不固定的场合

●可以传递数组,也可以传递类型相同的多个变量。

作用

●在对数组长度未知(可变)的情况下进行函数声明。

注意

●数量不限。

●参数数组必须是方法声明中的最后一个参数。

●方法最多只能有一个参数数组。

●只能在一维数组上使用params关键字。

●Console.WriteLine中使用占位符,就是使用参数数组实现的。

数据类型

值类型

●直接存储值。(数据存储在栈中)

●一个值类型变量赋给另一个值类型变量时,会复制一个数据副本给它(在栈中产生2个数据)。

改变值类型不影响其他数值。(因为是2个数据,互不影响)

引用类型

●存储对数据的引用地址。(变量定义在栈中,而数据实际存储在堆中,数据只是引用到变量)

●赋值时只复制对对象的引用地址,而不复制对象本身。(实际数据只有一份)

●两个引用类型的变量可以指向同一对象。

改变一个引用类型的变量可能会影响其他对象。(因为是一份数据)

类型归属

●值类型:枚举,结构(基础类型)

●引用类型:类(包括数组,字符串),接口,委托

String类型

●String是特殊的引用类型。(因为引用类型存在堆中,可以存大量内容,所以string定义为引用类型)

字符串常量具备字符串池特性(字符串变量拼接后形成新对象)

●String再赋值后(s1=“二毛”),不会影响s1的值。但是原数据就会是垃圾。

●String赋值后的值,是不可以改变的(所以才会产生垃圾)。

●可变字符字符串:stringBuilder。

stringBuilder在原有字符串上修改,string创建新的字符串替换。

原因

内存的栈可存放数据小,运行速度快 ; 堆可存储空间大,但是运行速度慢。所以值类型在栈,引用类型在堆。

声明与释放引用类型变量

使用关键字 null 进行释放数据(赋值空字符串)。

释放之后就形成了垃圾,会被自动回收。

比较值类型

在做==和!= 比较时,比较的是存储的数值(真实数据)。

比较引用类型

在做=和!= 比较时,比较的是引用的位置是不是同一个,而不是所引用的值。

枚举类型

●定义:列举某个数据的所有取值。

●作用:增强代码的可读性,限定取值。

●适用性:取值范围较小。

●使用enum关键字定义枚举数据类型。

●语法:  enum 名字{值1,值2,值3,值4}

●每个枚举元素都是有枚举值。默认情况下,第一个枚举的值为0,后面每个枚举的值一次递增1,可以修改值,后面的枚举数的值一次递增。

●枚举元素默认基础类型为int,准许使用的枚举类型有byte、sbyte、short、ushort、int、uint、long或ulong。

●类型转换

//string类型转换为枚举

Sex s1 = (Sex)Enum.Parse(typeof(Sex), "男");

//枚举转换为字符串

string str = Sex.女.ToString();

//int类型转换为枚举

Sex s2 = (Sex)3;

//枚举类型转换为int类型

int i = (int)Sex.男;

●标志枚举

可以同时赋值多个枚举值

[Flags]//标志枚举

enum Sex

{

男=1,  //000001

女=2,  //000010

未知=4 //000100

}

Sex s3 = Sex.男 | Sex.女;

//System.Drawing.FontStyle

●判断标志枚举值中是否包含某项值

bool b = (s2 & Sex.男) == Sex.男;

//  00011

//  00001

//  00001

字符串操作

属性

●使用s.Length属性来获得字符串中的字符个数。

●字符串的内容一旦声明就不可变。所以只能读取,不能修改。

●如要修改字符串内容,先创建一个新的字符串,用s.ToArray()方法得到字符串的char数组,对数组进行修改后再调用new string(char[])这个构造函数来创建char数组的字符串。一旦字符串被创建,那么char数组的修改也不会造成字符串的改变。

●StringBuilder 可变字符串。

String 类常用函数

●字符串中插入字符.Insert();

●查找字符中是否有该字符,返回bool值。

●ToLower();得到字符串的小写形式。

●ToUpper();得到字符串的大写形式。

●查找字符串位置

●取子串

●Trim();移除字符串两头的空白字符。用于避免用户错误的录入。

●两个字符串(si、s2)忽略大小写的比较。

●将字符串按照指定的char分隔符拆分为字符数组,和拼接

●将字符串按照指定的char分隔符拆分成字符数组后忽略空字符

●替换字符串中个别内容,使用replace。

●取子串

练习:

1、字符串反转:“我要学习”

string str = "我要学习";

char[] toChar = str.ToArray();

Array.Reverse(toChar);

string toStrint = new string(toChar);

Console.WriteLine(toStrint);

2、单词反转:I want to learn

string str = "I want to learning";

string[] toArry= str.Split(' ');

Array.Reverse(toArry);

string toString=string.Join(" ", toArry);

Console.WriteLine(toString);

奇数字符大写偶数字符小写:

string str = " I want to learning ";

string result = string.Empty;

char temp='\0';

for (int i = 0; i < str.Length; i++)

{

if (i % 2 == 0)

{

temp =char.ToUpper(str[i]);

}

else

{

temp =char.ToLower(str[i]);

}

result += temp;

}

Console.WriteLine(result);