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”);
4、ToString(转入)从其他类型到字符串:
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);