1 C#编程概述
- C#程序由一个或多个 类型声明 组成
- 命名空间(namespace) 是与某个名称相关联的一组 类型声明。
1.1 Main(程序的起始点)
每个C#程序必须有一个类带有 Main 方法(函数),每个C#程序的可执行起始点在 Main 中的第一条指令,一共有4种形式:
static void Main { .. }
static void Main(string[] args) { .. }
:允许运行程序时从命令行输入实参static int Main { .. }
:通常报告程序的执行成功与否,0
表示成功static int Main(string[] args) { .. }
2 类型、存储和变量
2.1 类型概述
C#程序就是一组类型声明,可以把类型想象成一个用来创建数据结构的模板,通过实例化类型而创建的对象被称为类型的对象或类型的实例,在C#程序中,每个数据项都是某种类型的实例。
- 像
short
,int
和long
等这样的类型称为 简单类型,这种类型只能存储一个数据项 - 比如数组(array)类型就可以存储多个同类型的数据项,这些数据项称为数组元素
- 还有一些类型可以包含多个不同类型的数据项,这些数据项个体称为成员,分别有数据成员和函数成员
2.2 栈和堆
在理清栈堆之前,要先理清几个数据结构:
- 链表,链表是一种特殊的数据结果,能有动态的存储一种结构类型数据,这里又要注意的是:《链表与数组的区别》,链表有节点组成,每个节点包含两部分数据,第一部分是节点本身的数据,另一部分是指向下一个节点的指针,对于单向链表,链表中存在两个特殊的节点,分别是“头节点”和“尾节点”,头节点本身没有数据只有指针,而尾节点只有数据没有指针。
- 队列,队列是链表的扩展,它是 操作受限 的线性表,队列采用的是先进先出的原则,即仅限与在表的一端进行插入,另一端进行删除元素,允许删除的那端叫做 “队头”,允许插入的那段叫做 “队尾”,这两个操作叫做入队和出队
- 堆栈,堆栈也是 操作受限 的线性表,它采用的后进先出原则,此时允许插入或删除动作的那端叫做 “栈顶”,反之叫做 “栈底”,不含元素的空表叫做 “空栈”
2.2.1 栈
栈是一个内存数组,是一个LIFO(Last-In First-Out)的数据结构,数据的写入称为入栈(push),删除数据称为出栈(pop),栈存储几个类型的数据:
- 某些类型变量的值
- 程序当前的执行环境
- 传递给方法的参数
2.2.2 堆
堆是一个内存区域,在堆里可以分配大块的内存用于存储某些类型的数据对象,与栈不同,堆里的内存可以任意顺序地存入和移除
2.2.3 值类型和引用类型
数据项的类型定义存储数据需要的内存大小及组成改类型的数据成员,同时还决定了对象在内存中的存储位置(栈或堆)。
类型被分为两种:
- 值类型:只需一段单独的内存,用于存储实际的数据,可以存放在堆或栈中
- 引用类型:需要两段内存;
- 第一段存储实际的数据,它总是位于堆中
- 第二段是引用,指向数据在堆中的存放位置,可以存放在堆或栈中
2.3 变量
C#提供四种变量:
- 本地变量:在方法的作用域保存 临时数据,不是类型的成员
- 字段:保存和类型实例相关的数据,是类型的成员
- 参数:用于从一个方法到另一个方法传递数据的临时变量,不是类型的成员
- 数组元素:同类数据项构成的有序集合的一个成员,可以本地变量,也可以为类型的成员
字段和本地变量的区别
- 生存期不同:前者实例创建时开始,实例不再被访问结束;后者在块中被声明的那点开始,在块完成执行后结束
- 隐式初始化:前者初始化该类型的默认值;后者没有隐式初始化,使用会直接报错
- 存储区域:前者所有字段都存储在堆中(不管是值类型还是引用类型),后者则分为值类型和引用类型的正常存储
3 字符串
3.1 输出时,格式化数字字符串
在打印字符串的时候,会使用 {}
花括号的形式实现格式化字符串;
在花括号内添加 格式说明符,语法如下:
{index,alignment:format}
,alignment
:可选,注意是,alignment
,指定字段宽度,以及是否是左对齐或左对齐,正数为右对齐,负数为左对齐:format
:可选,注意是:format
,有冒号,此为标准数字格式说明符,有以下字符:
C/c
(后跟精度说明符):货币D/d
(后跟精度说明符):十进制F/d
(后跟精度说明符):定位小数点G/g
(后跟精度说明符):转为科学计数法或定点X/x
:十六进制N/n
(后跟精度说明符):与定位相似,但每三个数字为一组,中间有逗号或空格分隔符P/p
(后跟精度说明符):百分比R/r
:类型转化,与原始值一样E/e
:科学计数法
3.2 String
类
C#预定义的字符串类型 string
代表了.NET的 System.String
类。字符串是Unicode字符串数组,字符串是不可变的,使用 string
方法都不能改变字符串本身,实质上只是返回了另一个 字符串副本。
string
类型的成员:
Empty
:属性,String.Empty
表示空字符串,同样类似的还有Environment.NewLine
转行Format
:可以用于像输出字符串那样格式化地创建字符串对象length
:属性,返回字符串长度Concat
:静态方法,返回连接的字符串Contains
:方法,返回字符串是否存在某个子字符串Trim
:实例方法,返回去掉空格的字符串Format
:静态方法,返回格式化后的字符串Insert
:方法,接受一个字符串和一个位置作为参数,返回一个插入后的字符串Remove
:方法,从对象字符串中移除一组字符串Replace
:方法,替代对象字符串中一组字符串Split
:方法,按参数拆解对象字符串成数组Substring
:方法,获取对象字符串的子字符串,第一个参数是开始截取的序号,第二个参数是截取长度ToLower
:方法,返回小写ToUpper
:方法,返回大写Parse
:这是所有预定义类型的静态方法,它接受一个字符串并把它转换为该类型的实际值,eg:double.Parse("2.1");
TryParse
:直接使用Parse
,如果字符串不能成功转化的话会抛出异常,而使用TryParse
方法即可以避免这种情况,它接受两个参数,一个是希望转换的字符串,一个是 指向目标类型变量的引用的out
参数,如果转换成功,会返回true
3.3 StringBuilder
类
StringBuilder
类可以帮助你动态、有效的产生字符串,而避免产生过多的副本,StringBuilder
类是BCL的成员,位于 System.Text
命名空间中,StringBuilder
是Unicode字符串的可变数组。
这样,与 String
类型不同,StringBuilder
类使用方法后,StringBuilder
对象的确被修改了。而要获取 StringBuilder
对象的相关字符串内容,要使用 ToString
方法即可。
using System;
using System.Text;
class Program
{
static void Main()
{
StringBuilder sb = new StringBuilder("Hi");
sb.Replace("Hi", "Hello");
Console.WriteLine(sb.ToString());
}
}
4 时间类型
4.1 DateTime
结构
使用 DateTime
结构的 Now
静态属性可以得到一个当前系统时间对象 DateTime
,除了使用构造函数创建 DateTime
对象以外,还可以使用 它的ParseExact
方法或 Parse
方法将字符串转化为日期,还有可以使用 Convert
类的 ToDateTime(string)
方法,其中 ParseExact
语法(它也有好几个重载,具体看msdn)是:
public static DateTime ParseExact(string s,string format,IFormatProvider provider)
其中:
s
:表示要在的日期format
:表示s
的日期格式provider
:表示用于提供有关s
区域新特定格式信息的IFormatProvider
例子:
privat void btn_click(object sender, EventArgs e){
string s = string.Format("{0}/{1}/{2}", txtYear.Text, txtMonth.Text, txtDay.Text);
DateTime test = DateTime.ParseExact(s, "YYYY/MM/dd", null);
}
4.1.1 DateTime
对象格式化字符串
DateTime.Now.ToString("d")
输出:2018/4/25
DateTime.Now.ToString("D")
输出:2018年4月25日
DateTime.Now.ToString("f")
输出:2018年4月25日 23:07
DateTime.Now.ToString("F")
输出:2018年4月25日 23:07:21
DateTime.Now.ToString("g")
输出:2018/4/25 23:07
DateTime.Now.ToString("G")
输出:2018/4/25 23:07:21
DateTime.Now.ToString("R")
输出:Wed, 25 Apr 2018 23:07:21 GMT
DateTime.Now.ToString("y")
输出:2018年4月
DateTime.Now.ToString("dddd")
输出:星期三
DateTime.Now.ToString("yy年M月d日H时m分s秒")
输出:18年4月25日23时7分21秒
DateTime.Now.ToString("yyyy年MM月dd日HH时mm分ss秒")
输出:2018年04月25日23时07分21秒
4.1.2 DateTime
的常用属性及方法
DateTime.IsLeapYear(int Year)
:该方法用于返回当年的总天数是366还是365,接受一个int
类型的年份,返回true
表示天数是366DateTime.Now.AddDays(double day)
:该方法可以将制定的天数添加到DateTime
对象的值上并返回,数值可以为负,注意参数是双精度Double
值DateTime.Now.Add(TimeSpan timespan)
:返回添加时间段的DateTime
对象
4.2 TimeSpan
类
两个 DateTime
对象相减会得出一个 TimeSpan
类,当然也可以使用构造函数创建。
TimeSpan
有只读属性 days
、Hours
、Minutes
、Seconds
(以上都数值都可为正负),同时使用它的 Add
方法可以将两个 TimeSpan
对象相加。
5 Regex
类
正则表达式在程序设计中有着重要的位置,常用于处理字符串信息。其中C#使用到的就是 Regex
类,使用时 System.Text.RegularExpressions
命名空间。
5.1 IsMatch
方法
Regex
类的 IsMatch
方法用于指示当前选定的字符串是否匹配设置的正则表达式,其语法如下:
public static bool IsMatch(string input, string pattern)
其中:
input
:字符串对象,表示套搜索匹配项的字符串pattern
:字符串对象,表示要匹配的正则表达式模式bool
:返会布尔值
5.2 Replace
方法
Regex
类中的 Replace
方法作用如同 String
类中的 Replace
方法,只是在以正则表达式作为替代模板,语法:
public static string Replace(string input, string pattern, string replacement)
input
:被搜索的源字符串pattern
:正则表达式模板replacement
:替代字符串
5.3 Split
方法
同理还有 Split
方法,用于拆分字符串,返回字符串数组,语法:
public static string[] Split(string input, string pattern)
input
:字符串对象,表示要拆分的字符串pattern
:字符串对象,表示要匹配的正则表达式
6 Math
类
Math
类的常用方法:
Math.Pow
:返回指定数字的指定次幂,语法public static double Pow(double x, double y)
Math.Max(int value1, int value2)
:返回较大的那一个数值,同理Math.Min
Math.DivRem(int a, int b, int result)
:a为被除数,b为除数,result为余数,返回值为商Math.Sqrt
:返回平方根,语法public static double Sqrt(double d)
,若 d 为负数,则返回NaN
Match.Round
:作用是舍入到指定精度,语法public static double Round(double value, int digits)
,其中digits
为返回值的有效数字位数,返回值的依据是返回最接近value
的值,优先返回偶数
7 可空类型
可空类型总是基于另一个叫做基础类型的已经被声明的类型。
可以在任何 值类型 创建可空类型,即不能在 引用类型 上创建了可空类型,要创建可空类型变量只需在基础类型的名称后面添加 ?
符号,例如:
int? myNInt = 28;
int? myNInt2 = null;
- 可空类型使用
HasValue
属性或直接与null
比较,可以得出布尔值表示该可空类型是否含有数值 - 直接使用
value
属性等于直接访问可空类型转换基础类型返回的数值,此时要先检查可空类型是否为null
,否则会抛出异常(结构的可空形式只能通过value
属性,它不直接暴露任何成员) - 基础类型转换成可空类型是 隐式的,可空类型转换基础类型是显式的
可空类型实例可以使用 空接合运算符 ??
达到类似使用三元运算符一样的效果,当数值为 null
时,默认设置另一个数值。