首页 > Python基础教程 >
-
C#教程之C#高级编程 第二章 核心C#
(一)第一个C#程序
创建一个控制台应用程序,然后输入代码,输入完毕后点击F5
Console.WriteLine();这条语句的意思:把括号内的内容输出到界面上;
Console.ReadKey();这条语句的意思:一般就是用来在程序运行到此处时等待键盘输入,以此来达到不关闭界面的效果,方便我们观察输出结果
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace ConsoleApp1 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Console.WriteLine("Hello World"); 14 Console.ReadKey(); 15 } 16 } 17 }
点击F5后弹出输出界面如下:
简单解释以上代码:
- C#以英文分号(;)结束语句;
- 用花括号({})把语句组成块;
- C#区分大小写 。
(二)变量
在C#声明变量使用语法:首先变量类型,然后空格,再是变量名,最后以分号结束。
例子:
以下语句声明了一个变量名为x,变量类型为int的变量
int x;
例子:
以下语句同时声明了x,y两个变量,类型变量同时为int类型
int x,y;
1、类型的初始化
C#编译器需要用某个初始值对变量进行初始化,之后才能在操作中引用该变量
例子:
以下语句对声明的变量进行了初始化(赋值)
int x = 10; int y = 20, z = 30;
例子:
以下语句在没有初始化的情况下,对变量进行调用是错误的(编译器会报错)
int x; Console.WriteLine(x);
上面的语句修改为以下语句才能正常运行
int x = 10; Console.WriteLine(x);
2、类型推断
类型推断使用 var 关键字。在使用var关键字进行变量声明时,一定要初始化,因为编译器需要根据赋值进行类型推断。
例子:
以下两行语句是完全等价的
int x = 10; var x = 10;
3、变量的作用域
变量的作用域是可以访问该变量的代码区域。一般情况下,确定作用域遵循以下规则:
- 只要类在某个作用域内,其字段(也成为成员变量)也在改作用域内;
- 局部变量存在于表示声明该变量的块语句或方法结束的右花括号之前的作用域内;
- 在for、while或类似语句中声明的局部变量存在于该循环体内。
4、常量
常量是其值在使用过程中不会发生变化的变量。常量的关键字是 const 。
例子:
以下代码声明了一个名为a的常量
const int a = 10;
常量具有如下特点:
常量必须在声明时初始化。指定了其值后,就不能改写了。
常量的值必须能在编译时用于计算。
常量总是静态的。
(三)预定义数据类型
1、值类型和引用类型
概念上的区别:值类型直接存储其值,引用类型存储值的引用
内存存储的区别:值类型存储在堆栈中,而引用类型存储在托管堆上
例子:
因为int是值类型,以下语句会在内存的两个地方存储值20
int x = 20; int y = 20;
假设我们已经定义了一个类(引用类型)People,并且有一个int类型的Age属性
1 People people1 = new People(); 2 people1.Age = 20; 3 People people2 = people1; 4 Console.WriteLine("修改people1.Age之前,people2.Age的值:" + people2.Age); 5 people1.Age = 21; 6 Console.WriteLine("修改people1.Age之后,people2.Age的值:" + people2.Age); 7 8 Console.ReadKey();
运行以上代码,结果如下
根据以上结果我们可以看到people1.Age的修改对people2.Age造成了影响,这是因为引用类型存储的是引用,当people1赋值给people2时,people1和people2就指向了相同的引用,只要其中有一个对引用内容进行了修改,那么所有指向该引用的变量都会发生修改。
2、预定义的值类型
1.整形
C#支持8个预定义整数类型
名称 |
CTS类型 |
说明 |
范围 |
类型后缀 |
sbyte |
System.SByte |
8位有符号整数 |
|
|
short |
System.Int16 |
16位有符号整数 |
|
|
int |
System.Int32 |
32位有符号整数 |
|
|
long |
System.Int64 |
64位有符号整数 |
|
L |
byte |
System.Byte |
8位无符号整数 |
|
|
ushort |
System.Uint16 |
16位有符号整数 |
|
|
uint |
System.Uint32 |
32位有符号整数 |
|
U |
ulong |
System.Uint64 |
64位有符号整数 |
|
UL |
2.浮点型
名称 |
CTS类型 |
说明 |
位数 |
范围 |
类型后缀 |
float |
System.Single |
32位单精度浮点数 |
7 |
|
F |
double |
System.Double |
64位双精度浮点数 |
15/16 |
|
3.decimal类型
decimal类型是高精度的浮点数,小数的位数可由用户自定义,但因decimal不是基本类型,所以在计算时使用会有性能损失.
名称 |
CTS类型 |
说明 |
位数 |
范围 |
类型后缀 |
decimal |
System.Decimal |
高精度浮点数 |
28 |
|
M |
4.bool类型
bool和整数值不能相互隐式互换。不能用0来表示False,也不能用非零来表示True.
名称 |
CTS类型 |
说明 |
范围 |
bool |
System.Boolean |
高精度浮点数 |
true/false |
5.字符类型
为了保存单个字符的值,C#支持char数据类型
名称 |
CTS类型 |
值 |
Char |
System.Char |
表示一个16位的(Unicode)字符 |
3、预定义的引用类型
C#支持两种预定义的引用类型
名称 |
CTS类型 |
说明 |
object |
System.Object |
根类型,CTS中的其他类型都是从它派生而来的(包括值类型) |
string |
System.String |
Unicode字符串 |
string与引用类型的常见行为有些区别。例如,字符串是不可改变的。
例子:
string str1 = "字符串1"; string str2 = str1; Console.WriteLine("修改str1之前,str2的值:"+str2); str1 = "字符串2"; Console.WriteLine("修改str1之后,str2的值:" + str2);
运行代码,结果如下:
我们可以看到,str1的修改没有对str2的修改。造成这样结果的原因是:字符串虽然是字符串,但因为其不可改变性,在我们对str1进行修改时,会在堆中重新分配一个新的string对象。
(四)流控制
它们不是按代码在程序中的排列位置执行顺序执行的
1、条件语句
条件语句可以根据条件是否满足或根据表达式的值控制代码的执行分支。
1.if语句
测试特定条件是否满足
例子:
以下代码表示当条件满足时运行花括号内的代码
if (条件) { }
例子:
以下代码同时设置多个条件,当条件满足时运行对应位置花括号内的代码
int i = 0; if (i<=0) { Console.WriteLine("运行【if (i<=0)】位置代码"); } else if (i<=1) { Console.WriteLine("运行【else if (i<=1)】位置代码"); } else { Console.WriteLine("运行【else】位置代码"); }
运行代码,结果如下
注意:
- if括号中条件的表达式必须等于布尔值;
- 程序只运行从上到下最先满足条件位置的代码。
- 添加到if子句中的else if语句不受数量限制,但else的数量只能为0或1
2.switch语句
switch..case语句适合于从一组互斥的分支中选择一个执行分支
例子:
以下代码会在 i 满足case后面值的时候,运行此case以下最近的break以上这段区间内的代码
int i = 0; switch (i) { case 0: Console.WriteLine("i=0"); break; case 1: Console.WriteLine("i=1"); break; case 2: Console.WriteLine("i=2"); break; default: break; }
运行代码,结果如下
注意:
- case的值不能相同,且必须是常量表达式;不允许使用变量
- case子句可以为空(没有运行代码和break),就可以直接跳到下一条case上
- case子句的排放顺序无关紧要
- case的值可以是字符串
2、循环
C#提供了4种不同的循环机制(for、while、do...while和foreach),在满足条件之前,可以重复执行代码块。
1.for循环
C#的for循环提供的迭代循环机制是在执行下一次迭代前,测试是否满足某个条件。语法如下:
for (初始化器; 条件; 迭代器) { }
初始化器:在执行第一次循环前要计算的表达式
条件:在每次执行新循环前要测试的表达式,当此表达式为false时,迭代停止
迭代器:每次迭代完要计算的表达式
for循环是预测试循环。for循环非常适合于一个语句或语句块重复执行预定次数。典型用法:
for (int i = 0; i < 10; i++) { Console.WriteLine(i); }
运行代码,结果如下:
2.while循环
于for循环相同,while也是一个预测试循环。其语法如下:
while (条件) { }
while循环适用于:在循环前,不知道要重复的次数
例子:
bool condition = true; while (condition) { Console.WriteLine("循环内容"); condition = false; }
运行代码,结果如下:
3.do...while循环
do...while循环是while循环的后测试版本。do...while循环适用于:至少要将循环体执行一次的情况:
例子:
bool condition = false; do { Console.WriteLine("循环内容"); } while (condition);
运行代码,结果如下:
4.foreach循环
foreach循环可以迭代集合中的每一项(现在不必考虑集合的概念,知道集合是一种包含了一堆东西的东西就行)。
例子:
我们假定CustomerList是一个集合
foreach (var item in CustomerList) { Console.WriteLine(item); }
3、跳转语句
1.goto语句
名声不好不介绍
2.break语句
break用于退出for、foreach、while或do...while以及switch语句中某个case语句。
3.continue语句
continue与用于退出for、foreach、while或do...while当前迭代,开始执行下一次迭代,不是退出循环(退出循环是break干的事情)
4.return语句
return语句用于退出类的方法,把控制权返回方法的调用者。
(五)枚举
枚举是用户定义的整形类型。枚举使代码易于维护、更清晰、易于输入。声明方式:
例子:
public enum TimeOfDay { Morning = 0, Afternoon = 1, Evening = 2 }
我们在switch语句中使用上面的枚举:
TimeOfDay timeOfDay = new TimeOfDay(); switch (timeOfDay) { case TimeOfDay.Morning: Console.WriteLine("Morning"); break; case TimeOfDay.Afternoon: Console.WriteLine("Afternoon"); break; case TimeOfDay.Evening: Console.WriteLine("Evening"); break; default: break; }
可以获取枚举的字符串表示:
TimeOfDay timeOfDay = new TimeOfDay(); Console.WriteLine(timeOfDay.ToString());
运行代码,结果如下:
从字符串中获取枚举值: