cs文件结构
结构展示
1、IED最右侧是“解决方案资源管理器”,如下图所示
解决方案资源管理器显示了项目相关文件的名称以及内容。双击文件名即可在“代码和文本编辑器”中显示该文件的内容。
2、写代码之前先了解一下“解决方案资源管理器”列出的文件,他们是作为项目的一部分由Visual Studio 2022自动创建。
- 解决方案“TextHello” 解决方案文件位于最顶级,每一个应用程序都有一个。一个解决方案可包含一个或多个项目,Visual Studio 2022 利用解决方案文件来组织项目。在项目资源管理器中查看“文档”文件夹会发现实际的名称是TextHello.sln.
- TextHello C#项目文件。每个项目文件都引用一个或多个包含项目源代码以及其他类容(比如图片)的文件。一个项目的所有源代码都必须使用相同的编程语言。在文件资源管理器中,该文件的实际名称是TextHello.csproj。
- properties 这是TextHello项目中的一个文件夹。展开会发现AssemblyInfo.cs文件。AssemblyInfo.cs适用于程序添加“特性”的特殊文件,比如作者的姓名和写程序的日期等等。还可以利用特性修改程序运行的方式。
- 引用 该文件夹包含对已编译好的代码库的引用。编辑C#代码时,这些引用会转换成库,并获得唯一的名称。Microsoft .NET Framework将这种库成为程序集。开发人员利用程序集打包自己开发的有用功能,并分发其他程序员以供使用。展开“引用”文件夹会看到 Visual Studio 2022在项目中添加的一组默认程序集的引用。利用这些程序集可访问.NET Framework的大量常用功能。
- App.config 应用程序配置文件。由于可选,所以并非肯定存在。可在其指定设置,让应用程序在运行时修改其行为,例如修改运行应用程序的.NET Framework版本。
- Program.cs 由模板生成的C#源代码文件。项目最初创建时,“代码和文本编辑器”现实的就是该文件。
C#语法基础
注意:
- C#是区分大小写的
- 每个语句后面都要加上分号;
- 文件名和类名是可以不一样的
C#是一种面向对象的编程语言,在面向对象的程序设计方法中,程序由各种方法组成。相同种类的对象通常具有相同的类型。
比如我和你都是人 属于同一类型
关键字
关键字是指对编辑器有特殊意义的预定义保留标识符,他们不能再程序中用作标识符。
- using关键字
再任何C#程序中的第一句都是
using System;
using关键字用于再程序中包含命名空间。一个程序可以包含多个using语句。
- class关键字
class关键字用于声明一个类。
注释
c#的注释方式:
块注释
/*
多行注释
也叫做块注释
*/
单行注释
//单行注释 行注释
文档注释
/// <summary>
/// 打游戏的方法
/// </summary>
public void palyGames()
{
Console.WriteLine("playGames");
}
使用变量、操作符、表达式
标识符
是对程序的各个元素进行标识的名称,这些元素包括命名空间、类、方法和变量。在C#中必须遵循以下规则:
- 只能使用字母(大小写)、数字和下划线。
- 标识符必须以字母或下划线开头。
变量
变量是容纳值的一个存储的位置,可将变量想象成计算机内存中容纳时临时信息的容器。
命名规范
- 不要以画线开头
- 不要创建仅大小写不同的标识符。
- 名称以小写字母开头。
- 在包含多个单词的标识符中,从第二个单词起,每个单词的首字母大写(nameClass)。
- 不要以匈牙利记号法。
声明变量
C#语言 能存储和处理许多类型的值,整数,浮点数,字符串等。声明变量时必须指定数据类型。
变量类型 变量名 = 变量初始值;
int age;//int 是C#基本元数据类型之一。
age = 22;//变量声明好之后就可以进行赋值。
// = 是赋值操作符,作用是将右侧的值赋值给左侧的变量。
Console.WriteLine(age);
C#变量基元数据类型如图:
注意:不能使用未被赋值的变量,否则会报错。 如下:
测试1:实现两个变量的值互换
int a = 10;
int b = 20;
int temp = 0;
temp = a;//10
a = b;//20
b = temp;//10
Console.WriteLine(a);
Console.WriteLine(b);
Console.ReadKey();//以任意键结束
使用算术运算符
我们所学过的+ - * / 被称为操作符和运算符。对值进行“操作”和“运算”来生成新值。
在下例中,moneyPaidToConsultant变量最终容纳的值是750和20的乘积。
long moneyPaidToConsultant;
moneyPaidToConsultant = 750 * 20;
Console.WriteLine(moneyPaidToConsultant);
操作符和类型
不是所有操作符都支持所有类型。操作符能不能应用于某个值要取决于值的类型。
如:可对char int long float double decimal 类型的值使用任何操作符。但除了+,不能对String类型的值使用任何算术操作符。对于bool类型的值,则所有的额=操作符都不能够使用。
操作符+可用于链接字符串。
Console.WriteLine( "12" + "1");//121而不是13
字符串插值
C#不鼓励使用+操作符链接字符串。
之所以要链接字符串,通常是为了生成插入了变量值的一个字符串。如
string name = "join";
string message = "Hello" + name;
Console.WriteLine(message);//Hellojion
使用插值则为:
string name = "jion";
string message = $"Hello {name}";
Console.WriteLine(message);//Hello jion
开头的$表明这是插值字符串,{和}之间的任何表达式都要求值并置换。无前置$符号,字符串{name}将按字面意思处理。
还有一个操作符 “取余”,使用百分号%表示。9除以2等于4余1 所以输出 1
int a = 9%2;
Console.WriteLine(a);//1
优先级控制
2+3*4
- 如果是先加后乘,那么结果为20
- 如果先乘后加,那么结果为14
在C#中乘法类操作符优先级是高于加法类操作符的 所以2+3*4 = 14
可用圆括号覆盖优先级规则,强制操作符按照你希望的方式绑定。
(2 + 3) * 4
最终结果为20
声明隐式类型的局部变量
前面说过通过指定数据类型和标识符来声明变量如
int a;
前面说过变量使用前必须赋值。可以在同一个语句中声明并初始化变量。如
int a = 1;
也可以
int a = b * 99;
赋给变量的值必须具有和变量相同的类型。例如,只能将int值赋值给int变量。此外,还可以使用var关键字代替类型名称:
var name = "jion";
var num = 123;
var tag = true;
name num tag 成为隐式类型的变量。var关键字告诉编辑器根据变量的初始化表达式推断变量类型。name为 string类型 而num和tag是 int 和bool类型。必须注意,var只是在声明变量是提供一些方便。但变量一经声明,就只能将编译器推断的那种类型的值赋值给他。
测试2:用户输入两个数让他们相加并打印结果
Console.WriteLine("请输入第一个数字");
string str = Console.ReadLine();
Console.WriteLine("请输入第二个数字");
string str2 = Console.ReadLine();
//int.Parse()是将字符串转成数字类型实现相加
// 不同类型的数据转换成同一类型
//转字符串使用 .ToString()
int sum = int.Parse(str) + int.Parse(str2);
Console.WriteLine("他们的和是:"+ sum);
Console.ReadKey();
使用判断语句
逻辑操作符
逻辑与(&&)逻辑或(||)。这两个称为逻辑操作符。作用是将两个布尔表达式或者值合并成一个布尔结果。这两个二元操作符与相等/关系操作符相似的地方是结果也为true或false。不同的地方是操作的值(操作数)本身必须是true或false。
只有两个操作数的两个布尔表达式都为true,&&操作符的求值结果才为true。例如:
bool num;
num = (args >= 0) && (args <= 100);
两个操作数任何一个为true,操作符||的取值就是true,他判断两个条件是否成立
bool num;
num = (args < 0) || (args > 100)
短路求值
操作符&&和||都支持短路求值。假设操作符&&的左边操作数求值为false,那么整个表达式的结果就是false。如果操作符||的左操作数求值为true,那么整个表达式的结果就是true。
//假设args小于0 那么操作符左侧的表达是为false。所以整个式子的结果就为false
(args >= 0) && (args <= 100);
//假设args小于0 那么操作符左侧的表达式为true。所欲结果为true。
(args < 0) || (args > 100)
语法如下:
if(条件true或false){
条件为true执行花括号里面的程序
}
else if () {
}
else {
}
测试:根据输入的值判断成绩
/根据输入的值判断成绩
Console.WriteLine("请输入你的成绩1-100");
string cj = Console.ReadLine();
int cj1 = int.Parse(cj);
if (cj1 >= 90)
{
Console.WriteLine("非常优秀");
}
else if (cj1 >= 80 && cj1 < 90)
{
Console.WriteLine("优秀");
}
else if (cj1 >= 60 && cj1 < 80)
{
Console.WriteLine("良好");
}
else
{
Console.WriteLine("不合格");
}
Console.ReadKey();
测试:根据输入的1-7判断星期几
Console.WriteLine("请输入1-7的数字");
string d = Console.ReadLine();
int day = int.Parse(d);
if (day == 1)
{
Console.WriteLine("星期一");
}
else if (day == 2)
{
Console.WriteLine("星期二");
}
else if (day == 3)
{
Console.WriteLine("星期三");
}
else if (day == 4)
{
Console.WriteLine("星期四");
}
else if (day == 5)
{
Console.WriteLine("星期五");
}
else if (day == 6)
{
Console.WriteLine("星期六");
}
else if(day == 7)
{
Console.WriteLine("星期天");
}
else
{
Console.WriteLine("请规范输入");
}
使用switch语句
语法
switch (控制表达式)
{
case 常量表达式:
语句
break;
case 常量表达式:
语句
break;
default :
语句
break;
}
前面的if可修改成
Console.WriteLine("请输入1-7的数字");
string d = Console.ReadLine();
int day = int.Parse(d);
switch (day)
{
case 1:
Console.WriteLine("星期一");
break;
case 2:
Console.WriteLine("星期二");
break;
case 3:
Console.WriteLine("星期三");
break;
case 4:
Console.WriteLine("星期四");
break;
case 5:
Console.WriteLine("星期五");
break;
case 6:
Console.WriteLine("星期六");
break;
case 7:
Console.WriteLine("星期日");
break;
default :
Console.WriteLine("请规范输入");
break;
}
switch语句规则
- switch的控制表达式只能是某个整型(int,char long)或string。其他类型只能使用if语句
- case标签必须是常量表达式,如42(控制表达式是Int),'4'(控制表达式是char),"4"(控制表达式是string)。要想在运行时计算case的值,就只能if语句。
- case标签必须唯一,不允许两个case标签具有相同的值。
方法
以下是addValues方法的定义,他不返回任何值,left为一个int参数
void addValues (int left, int right)
{
}
注意:关键字void来指定方法,要求他不返回任何值。
如果希望方法返回数据(返回类型不是void),必须在方法内部写return语句。为此先写return,然后再添加计算返回值的表达式,最后写分号。表达式的类型和方法返回类型相同。也就是说假如函数返回Int值,则return语句必须返回int,否则无法编译:
int addValues (int left, int right)
{
return left + right;
}
return 通常放在方法尾部,因其导致方法结束,控制权返回调用方法的那个语句,return后的任何语句都不执行(如果return语句之后有其他的语句,编译器会发出警告)
如果不希望方法返回数据(返回Viod),可利用return语句的一个变体立即从方法中退出。
void showRes(int anwer)
{
Console.WriteLine( $"The anwer is {anwer}");
return;
}
如果方法什么都不返回可省略return ,但一旦执行到方法尾部的结束大括号,方法就会自动结束。
语法糖
有的方法十分简单我们就可以进行简化。以下是addValue和showRes的简化版本,它和之前的方法并无二致。
int addValues(int left, int right) => left + right;
void showRes(int anwer) => Console.WriteLine($"The anwer is {anwer}");
主要区别是使用=>操作符引用构成方法主体的表达式,而且没有return语句。表达式的值自动作为返回值。如果表达式不返回值,则有viod方法。
调用方法
C#调用方法语法如下:
result = methodName (argumentList)
- methodName(方法名)必须与要调用的方法名称完全一致。
- result = 这个是可选。如指定,result变量将包含方法返回值。如果返回类型是void,就必须省略。
- agrumentList(实参列表)提供由方法接受的数据。必须为每个参数(形参)提供参数值(实参),而且每一个实参都必须兼容于形参的类型。如果方法有两个或多个参数,参数与参数之间用逗号分隔。xian
int addValues(int left, int right)
{
return left + right;
}
addValues(12, 13);//方法的调用
int arg1 = 1;
int arg2 = 2;
addValues(arg1, arg2);
下面举例错误的调用方式:
addValues;//编译错误,无圆括号
addValues();//编译错误,无足够实参
addValues(12);//编译错误,无足够实参
addValues("9", "0");//编译错误,类型错误
addValues方法返回int值,可在允许使用int值的地方使用:
int res = addValues(123, 123);//作为赋值操作符的右操作数
showRes(addValues(12, 2));//作为实参传递给另一个方法调用
使用复合赋值和循环语句
int anwser = 0;
anwser = anwser + 10;
Console.WriteLine(anwser);
anwser = anwser + 10;等同于 anwser+=10;
int anwser = 0;
anwser += 10;
Console.WriteLine(anwser);
任何算术操作符都可以像这样写。
a = a + 1 | a += 1 |
a = a - 1 | a -= 1 |
a = a * 1 | a *= 1 |
a = a / 1 | a /= 1 |
a = a % 1 | a %= 1 |
操作符+=还可以用于字符串如
string name = "join";
string gee = "hello ";
gee += name;
Console.WriteLine(gee);// hello join
while语句
while语句语法允许在条件为true时反复触发:
while(booleanExprssion)
statement
先求值布尔表达式booleanExprssion为true时就运行statement,再次求值booleanExprssion仍为true继续运行statement。再次求值。。。。如此反复,直到求值为false推出while循环。
- 表达式必须是布尔表达式
- 布尔表达式必须放在圆括号内
- 首次求值布尔表达式如果为false那么语句一次都不运行
- 要在while语句的控制下执行两个或更多的语句,必须用大括号将语句分组成代码块。
int i = 0;
while (i<10)
{
Console.WriteLine(i);
i++;
}
for语句
语法
for (initialization; Boolean expression; UpdateRowSource control varianble)
statement
改写以上while循环写法
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
for循环的三个部分都可以省略,如省略布尔表达式,布尔表达式就默认为true。以下示例:
for (int i = 0; ; i++)
{
Console.WriteLine("根本停不下来!!!");
}
省略初始值和更新部分会得到一个看起来很奇怪的for循环,如下所示:
int i = 0;
for (; i < 10; )
{
Console.WriteLine(i);
i++;
}
do语句
while语句和for语句都在循环开始时测试贝尔表达式,意味着如果首次测试布尔表达式为false,循环主体一次都不执行。do语句则不同,他的布尔表达式在每次循环之后求值,所以主体至少运行一次。
语法如下:
do
statement
while(booleanExpression)
控制台输出0-9
int i = 0;
do
{
Console.WriteLine(i);
i++;
}
while (i < 10);
管理错误和异常
try
{
}catch (Exception ex)
{
}
代码运行时会尝试执行try块内的所有语句,如果没有任何语句产生异常,这些语句将一个接一个运行,直到全部完成。但一旦出现异常,就跳出try块,进入catch处理程序中执行。
紧接着try块写一个或多个catch处理程序来处理可能发生的错误。每个catch处理程序都捕捉并处理特定类型的异常,可在try块后面写多个catch处理程序,try块中的任何语句造成错误,“运行时”都会生成并抛出异常。
try
{
int leftHandside = int.Parse(lhsOperand.Text);
int rightHandSide = int.Parse(rhsOperand.Text);
int answer = doCalculation(leftHandSide, rightHandSide );
result.Text = answer.ToString();
}
catch (FormatException fEX)
{
}
如果try块抛出异常,但没有对应的catch处理程序。在这种情况下,int.Parse语句会抛出OverflowException异常。而catch处理程序目前只能捕捉FormatException异常。如果try块某个方法的一部分,那个方法将立即退出。并返回调用它的方法。
小结练习
简易的ATM程序
bool flag = true;
bool flag2 = true;
//当前账户的余额
int balance = 0;
while (flag)
{
Console.WriteLine("请输入账号");
string username = Console.ReadLine();
Console.WriteLine("请输入密码");
string password = Console.ReadLine();
if (username == "zhangsan" && password == "zs123")
{
flag = false;
Console.WriteLine("欢迎回来!");
while (flag2)
{
Console.WriteLine("请选择:1、存钱 2、取钱 3、查询余额 4、退出");
string num = Console.ReadLine();
switch (int.Parse(num))
{
case 1:
Console.WriteLine("请输入存钱的金额:");
string cunMoney = Console.ReadLine();
balance += int.Parse(cunMoney);
break;
case 2:
Console.WriteLine("请输入取钱的金额:");
string quMoney = Console.ReadLine();
if (int.Parse(quMoney) > balance)
{
Console.WriteLine("余额不足!!!");
break;
}
balance -= int.Parse(quMoney);
break;
case 3:
Console.WriteLine($"你的余额为{balance}");
break;
case 4:
Console.WriteLine("欢迎下次回来!");
flag2 = false;
break;
}
}
}
else
{
Console.WriteLine("账号或密码错误请重新登陆!");
}