C#基础语法学习笔记(传智播客学习)
最近在学习C#开发知识,跟着传智播客的视频学习了一下,感觉还不错,整理一下学习笔记。
C#基础语法学习笔记
- 1.背景知识
- 2.Visual Studio使用
- 3.基础知识
- 4.变量
- 5.运算符与表达式
- 6.程序调试
- 7.判断结构
- 8.循环结构
- 9.常量、枚举类型
- 10.结构体类型
- 11.数组
- 12.方法
- 13.outref用法
- 14.常用方法
1.背景知识
/*
背景知识:
(背景:.net是微软的)
一、.net与C#
1. .net:又叫dotnet,指.Net Framework框架.是一种技术,一种平台
2. C#: C sharp(锋利的), 是一种编程语言(控制计算机,和计算机进行交互的语言),可以基于.net 平台进行开发应用
关系: .net是一种平台,在.net平台上可以用C#语言进行.net相关程序的开发
3.Java: Java即是一种技术,又是一种语言
二、.net能干什么?
1.Winform: 在.net这个平台上开发的桌面应用程序叫做 Winform应用程序开发 (桌面应用程序:通过安装到桌面)
2.ASP.NET: 在.net这个平台上开发的web(浏览器)应用程序(网站) 叫做ASP.NET (web应用程序:通过打开浏览器输入网址访问)
3.wp7 :windows phone ,这.net这个平台上进行的手机嵌入式开发 (嵌入式开发应用程序:工业化控制设备)
两种服务模式:
1.C/S :客户机(Client)/服务器(Server) :桌面应用程序 (单机的不需要服务器的不算,因为只有C,没有S,像QQ这种是C,还需要S)
2.B/S :浏览器(Browser)/服务器(Server):一般是web应用程序
三、开发工具:Visual Studio
是微软的一个IDE(Integrated Development集成开发环境),也可以在记事本中写,但是太麻烦了 ,工欲善其事必先利其器。
MSDN:开发工具的帮助文档
*/
2.Visual Studio使用
/* Visual Studio使用
*
* 一.创建项目
* 文件->新建->项目->选择要创建项目的类型(目前一般是.net的控制台应用)
*
* 项目名称
* 项目位置
* 解决方案:解决方案包含项目,解决方案中可以包含多个项目(意思是这些个项目是用于解决这个方案的)
*
*二、界面排版
*
* 1.菜单栏
* 所有功能都会在菜单栏
* 2.工具栏
* 常用的工具功能,便捷
*
* 3.解决方案资源管理器
*
* 解决方案中可以包含多个项目,项目可以包含多个文件,文件中是我们写的程序
* 在文件中,可以有命名空间(定义命名空间前需要引用命名空间),命名空间中可以包含类,类中可以包含方法
* (在C#中类文件是以.cs结尾的)
*
* 程序的执行过程:
* Main方法是我们程序的入口方法,当我们执行一个程序时,会首先找到Main方法,从Main的第一句开始执行,
* 当Main方法执行完成后(即执行到Main方法的反大括号),程序就结束了
* 一般情况下,一个项目只有一个Main方法,或者也可以没有
*
* 4.重置开发环境
* 可以使我们的开发工具恢复至默认状态
* 菜单工具->导入导出设置->重置所有设置->不保存当前所有设置->C#开发设置->完成
*
* 一般的窗口不小心关闭了,在视图中找
*
* 三、保存/打开项目
* .sln :解决方案文件,记录着解决方案中都有哪些项目
* .csproj:项目文件,记录着项目中都有哪些文件
* 项目在哪忘了,右击解决方案->在文件资源管理器中打开文件夹
*
* 1.打开项目:
* 先找到项目路径,不要打开.cs文件,直接双击打开.cs文件,只是打开了一个类,只能看不能运行,右边也没有解决方案
* 建议用vs打开.sln解决方案文件(可以打开该解决方案下的所有项目),也可以打开.csproj文件(只能打开这一个项目)
*
* 2.保存项目
* Ctrl+s:只保存当前界面下的文件
* Ctrl+shift+s:保存所有文件
*
* 四、设置vs的字体大小及行号显示
*
* 1.设置vs字体大小:工具->选项->环境->字体和颜色
* 2.行号显示:工具->选项->文本编辑器->所有语言->行号
*
* 五、在同一解决方案下创建多个项目
* 直接从头打开vs创建项目话会再弄一个新的解决方案
* 如果想在同一解决方案下创建多个项目,需要先打开解决方案,然后新建就会出现选项 或者打开解决方案后右击添加
*
* 六、启动项目设置
* 当有多个项目时,运行会运行右侧黑色加粗的项目
* 想更改三种方法:
* ①工具栏有个选择框
* ②在右侧找到要启动的项目,右击设置为启动项目
* ③在右侧右击解决方案选择属性->启动项目->单启动项目/当前选择是现在打开的项目
*
* 七、项目的加载与卸载
* 同一解决方案下,有时候打开着多个项目,如果其他项目有错,运行当前项目可能受影响。
* 这时候可以右击其他项目选择卸载(不是删除),等需要时再重新加载即可。
*
*/
using System; //引用命名空间
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _2.Visual_Studio知识 //定义一个叫 _2.Visual_Studio知识 的命名空间
{
class Program //定义了一个名称为Program的类
{
static void Main(string[] args) //这是一个方法叫Main
{
}
}
}
3.基础知识
/*
* 基础知识
*
* 一、框架及执行过程
using System; //引用命名空间
namespace XXX //定义一个叫XXX的命名空间
{
class XXXX //定义了一个名称为XXXX的类
{
static void Main(string[] args) //这是一个方法叫Main
{
//在这里编写程序
}
}
}
* 程序的执行过程:
* Main方法是我们程序的入口方法,当我们执行一个程序时,会首先找到Main方法,从Main的第一句开始执行,由上往下一句一句执行
* 当Main方法执行完成后(即执行到Main方法的反大括号),程序就结束了
* 一般情况下,一个项目只有一个Main方法,或者也可以没有
*
* 二、输出
*
* 运行代码:点击小绿按钮或者调试->开始调试
* 小技巧:
* (1)vs有的会有智能提示,回车或tab键会出来
* (2)输入cw,再按两下tab键,可以快速打出Console.WriteLine(); 语句
*
* 1.Console.WriteLine("大号"); //在屏幕中换行输出
* 2.Console.Write("111");//在屏幕中不换行输出
* 3.Console.ReadKey();//当程序执行到Console.ReadKey();时,程序会停到这里,等待用户从键盘上键入一个键,用户键入这个键之后,程序才继续执行
//如果没有这一句,会一闪立马就关了
* 4.Console.Clear();//对控制台输出的清屏
*
*
* 总结:
* (1)C#区分大小写
* (2)C#中每一个语句都必须以分号;结束
* (3)这个生成的程序在项目文件夹->bin->Debug->.exe文件,其他文件都是和调试相关的
* (4)程序要先 生成(编译)后运行,直接点那个启动是把这两步和在一起了。生成是先看看对不对,所以按F6经常生成一下,F5是先 生成后运行
*
* 三、注释
* 注释:对写的程序进行解释,是给人看的
*
* 1.单行注释 //
* 2.多行注释 /*开始 *斜杠结束
* 除了多行注释语句,还可以用工具中的注释选中的行(快捷键先ctrl+e,再按一下c)
* 3.文档注释 ///
* 用于对类和方法进行注释,在类或方法前面连续输入三个/,会自动生成一段注释
*
* 四、计算机使用的基本技巧
*
* 1.常用的定位快捷键:
* (1)Home键:跳到这一行的最前面
* (2)End键:跳到这一行的最后面
* (3)Ctrl+Home键:跳到这一页的最前面
* (4)Ctrl+End键:跳到这一页的最后面
* (5)PageUp键:上翻页(如果代码过多,就不需要用鼠标了)
* (6)PageDown键:下翻页
* (7)shift键:帮助选中多个字符(和其他定位键组合使用,光标经过的地方都会被选中),不用再通过鼠标选中了
* 2.一段文字的删除习惯:
* 不要一个一个的删,再先选中再一起删
* (快速选中一行:Home+shift+End)
* Backspace:删除当前光标前面的
* Delete:删除当前光标后面的
*
* 3.全选/复制/粘贴/剪切
* Ctrl+A/C/V/X
* 注意:对话框的内容的复制?
*
* 4.插入、覆盖模式的困惑
* 有时候误点了Insert会出现一个小黑框,就是进入了覆盖模式,右下角会出现一个OVR就是覆盖模式的意思
* 再点一个Insert就会突出覆盖模式,进入插入模式
*
* 5.学会使用Ctrl+Z的撤销操作
* 6. ,.;()的全角还是半角问题
* 敲代码都是在英文状态下的半角模式
*
* 7.遇到异常、报错不要慌
* 按住F6出现编译错误,不要慌,先去看一下
*
* 8.#regin #endregion
* 这对指令可以折叠一段代码,前面会有一个+号就可以折叠(#regin后可以加注释)
*
#region 测试用
Console.WriteLine("你好世界!");
Console.ReadKey();
#endregion
*
*
* 五、了解.net
* .net是一种多语言的开发平台,开发.net可以用多达几十种语言进行开发(多语言、单平台(但是可以跨微软的平台))
* Java:是一种单语言的平台,但是可以跨平台(单语言、多平台)
*
* MSIL:微软中间语言 Microsoft Intermediate Language
* CLR:公共语言运行时 Common Language Runtime
* CLS: 公共语言规范 Common Language Specification
* CTS: 通用类型系统 Common Type System
* JIT: 即时编译器 Just In Time
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _3.基础知识
{
/// <summary>
/// 这个类中有一个Main方法,是我们程序的入口方法
/// </summary>
class Program
{
/// <summary>
/// 程序运行时,从这里开始执行代码
/// </summary>
/// <param name="args">
static void Main(string[] args)
{
Console.WriteLine("大号"); //在屏幕中换行输出
Console.Write("111");//在屏幕中不换行输出
Console.WriteLine("你是大傻der");
Console.ReadKey();//当程序执行到Console.ReadKey();时,程序会停到这里,等待用户从键盘上键入一个键,用户键入这个键之后,程序才继续执行
//如果没有这一句,会一闪立马就关了
#region 测试用
Console.WriteLine("你好世界!");
Console.ReadKey();
#endregion
}
}
}
4.变量
/*
* 变量
*
* 1、概念
* 变量代表着一块内存空间,我们可以通过变量名称向内存 存/取数据.有变量就不需要我们记忆复杂的内存地址
*
* 2、变量的定义(声明)
* 数据类型 变量名
*
* (1)数据类型
* (数值类型) int 整型
* double 浮点型
* decimal 也是浮点型:一般用于存储金钱 decimal money =1000.25m (后面有个m只是表示是decimal类型)
* (非数值类型)char 单个字符类型:只能存储一个字符,并且存储的这个字符要求用单引号引起来
* string 字符串类型:就是把0个或1个或多个字符连接起来,要求用双引号引起来
* 注意:
* ①在C#开发环境中,直接写一个有小数点的数字,这个数字是double类型的
* ②在一个小数后面加一个m或者M,就是告诉编译器这个数字是decimal类型
*
* (2)变量的命名规则
* 1°必须以 字母 _ 或 @ 符号开头(不能以数字开头)
* 2°后面可以跟任意字母、数字、下划线
* 3°注意:
* ①变量名不能与C#中的关键字重复
* ②在C#中,是区分大小写的
* ③在相同的作用域内,同一变量名不能重复定义
* 4°变量名要有意义,见名知意
* 5°C#变量名编码规范——Camel命名法:首个单词的首字母小写,其余单词的首字母大写 例:studentName
* 6°Pascal命名规范:每个单词的第一个字母都大写 例:StudentName
* 7°如果使用到英文单词的缩写,全部用大写!
*
* (3)声明变量的三种方式:
* 变量一定要先定义,再赋值,后使用
* ①先定义,再赋值 int a; a=3;
* ②定义变量时直接赋值 int a=3;
* ③一次声明多个同类型的变量,多个变量名称中间用逗号分隔,最后以分号结束
* int a,b,c; a=1; b=2; c=3;
* int a=1,b=2,c=3;
*
*
*
* 3、变量的赋值输出
* 变量名 = 值
*
* (1)赋值符:
* 赋值运算符和赋值表达式
* a =a +1;
* 注意:
* ①这里的 = 等号时赋值运算符,赋值的意思,而不是数学意义上的相等
* ②变量可以重复赋值,一旦给一个变量赋了新值,那么变量中的老值就不复存在了
*
* (2)连接符:
* +号在C#中有两种意义:
* ①加法:两边参与运算的是数值类型,则表示是数学中的加法运算
* ②连接:可以连接两个字符串,这里的+表示连接的意思
+ 字符串变量 相当于 + 字符串变量.Tostring()
+连接的两个变量,如果一边是字符串,另一边会自动调动字符串.Tostring()方法
*
* (3)占位符:
* 占位符由{数字}组成,数字由0开始编号
* 在Console.WriteLine("")中,第一个变量/字符串可以使用占位符
* 注意:
* ①索引(从0开始)必须大于或等于0,且小于参数列表 的大小
* ②用逗号分开的叫参数,Console输出的永远是第一个参数的内容,后面的参数只是用于替换前面占位符的值
*
* 4、例:借助第三变量交换变量
* int t;//定义第三变量
t = a;
a = b;
b = t;
*
* 5、字符串类型:
* (1)Console.ReadLine();
* 作用:用于接收用户的输入
* 注意:
* 用于让用户从键盘上输入一句话,让程序执行到下面这句话,就会暂停,按回车程序将继续执行
* 输入的数据默认是字符串类型,所以要定义一个字符串变量来存储用户输入的值
* (2)字符串转义
* 1°什么时候用?
* 当我们需要在字符串中输入一些特殊字符时,比如:半角引号、换行、退格,就需要使用转义字符
* 2°概念:
* 转义字符是一个字符,它是由一个\和一个字母来组成具有特殊意义的一个字符
* 3°常用的转义字符:
* \n :换行
* \b :backspace 退格
* \t :tab键 制表符(由多个空格组成的一个字符,具有行与行之间的对齐功能)
* \\ :表示一个\
* @ :在字符串前面加一个@符号有两种意义:
* ①字符串中如果有\ ,则不再理解为转义符
* ②使字符串可以换行
* (如果字符串前面加了@符号,在字符串上用两个双引号代表一个双引号)
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 变量
{
internal class Program
{
static void Main(string[] args)
{
}
}
}
5.运算符与表达式
/*
* 运算符与表达式
*
* 一、算术运算符与算术表达式
*
* 1、算术运算符
* ① + 加
* ② - 减
* ③ * 乘
* ④ / 除 :整除
* ⑤ % 取余、取模 :取余数
* 注意:
* 它们是二元运算符,要求参与运算的两个操作数的类型必须相同,并且经过运算后的结果与操作数的类型相同
* ++ :自增1 (有前加和后加)
* -- :自减1 (有前减和后减)
* 这两个是一元运算符 (如何区分一元还是二元?看有几个操作数, + 左右有两个操作数,所以是二元;++旁边只有一个操作数,所以是一元)
* 在C#中,一般情况下,一元运算符的优先级大于二元运算符
*
* 例:
c = a++: 先将 a 赋值给 c,再对 a 进行自增运算
c = ++a: 先将 a 进行自增运算,再将 a 赋值给 c
c = a--: 先将 a 赋值给 c,再对 a 进行自减运算
c = --a: 先将 a 进行自减运算,再将 a 赋值给 c
* 2、算术表达式:
* 由算术运算符连接起来的式子
* 3、优先级
* 先算乘除,后算加减,有括号先算括号里的,相同级别的从左至右运算
* (如果要改变计算的优先级,用小括号,小括号可以无限制套用,但是一定要成对出现)
* 在C#中,一般情况下,一元运算符的优先级大于二元运算符
*
*
* 4、类型转换
* (1)自动类型转换(隐式转换):
* 1°发生隐式转换的条件:
* ①两种类型兼容:参与运算的两个数据类型必须相兼容(例:int和double兼容,都是数值类型)
* ②目标类型大于源类型:必须一边的数据类型表示范围小,一边的表示范围大,并且把小的转向大的不丢失精度(从int到double)
*
* 2°注意:
* 在自动转换中,转换不会都是丢失精度的,如果丢失精度,那么这个转换肯定不会自动完成
* 常见到,参与运算的两个操作数一个是int,一个是double,那么int类型会自动转换成double类型
* 所以:两个int类型的运算想得到double类型,*1.0就可以了
*
* (2)强制类型装换(显式转换):
* 1°背景:
* 当需要丢失精度的转换,系统是不会帮我们自动转换的,需要程序员来写代码完成转换,就是强制类型转换
* (如double3.14到int3的转换,会丢失0.14的精度)
* 2°语法:
* (数据类型名) 待转换的值
* 例:
* int b = (int)3.14
*
* 3°条件:
* 强制类型转换,数据类型一定要相兼容(兼容的意思只都是数值类型,比如字符串和数值就不兼容)
*
* (3)字符类型的转换——借助类方法
*方式一: Convert:不再仅是内存级别的转换,而是考虑数据意义的转换。Convert是一个加工、改造的过程
* ①Convert.ToInt32(待转字符串) :将字符串变成整数
* ②Convert.ToDouble(待转字符串):将字符串变成浮点数
* ③Convert.ToString(): 一切类型都可以转换成string类型
方式二:将字符串类型装换为对应的数值类型
Console.Parse(String);
int.Parse(String)
double.Parse(String)
例:
string s = "123";
//int a = Convert.ToInt32(s);
int a = int.Parse(s);
* 二、复合运算符
* += :a+=3 等价于 a=a+3
* -=
* *=
* /=
* %=
* 注意: >= 大于等于号中间不能有空格
*
* 三、关系运算符和关系表达式
* 1、关系运算符
* 在C#中,有6个关系运算符,用于比较两个事物之间的关系(所以为二元运算符)
* >
* <
* == 等于
* != 不等于
* >=
* <=
*
* 2、关系表达式
* 由关系运算符连接起来的式子
* 3、bool类型(布尔)
* (1)bool值有两个
* 真:true
* 假:false
* (2)关系运算的结果是布尔类型的
*
*
* 四、逻辑运算符和逻辑表达式
*
* 1、逻辑运算符
* ① && 并且(逻辑与):两边都是真才是真
* ② || 或者(逻辑或):两边只要有一个真才是真
* ③ ! 取反(逻辑非):真变假,假变真
*(!是一元运算符,&& ||是二元运算符)
*
* 2、逻辑表达式
* 有逻辑运算符连接起来的式子
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 运算符与表达式
{
internal class Program
{
static void Main(string[] args)
{
int a = 5, b = 6;
int c = a++ * --b;
// b=b-1 (b是前减 )
// c=a*b (相乘赋值给c )
// a=a+1 (a是后加)
Console.WriteLine(c);
Console.ReadKey();
}
}
}
6.程序调试
/*
* 程序调试:
* debug能力才是最重要的
*
* 编译错误:一般是语法错误,编译器通不过会直接提示,以后通不过多读,需要经验积累
* 运行错误(逻辑错误):能编译通过,但是自己敲到代码不符合需求逻辑,需要找出错误地方就需要程序调试
*
* 对于运行错误有以下两种调试方法:
*
*(1)利用编辑器自带调试功能:三步走
* ①设置断点:在最前面的灰色处点一下就可以设置。断点:当程序运行到我们设置的断点处,程序就会停止
* ②单步运行:点击启动调试,按F10一步一步执行观察变量
* (F10是逐过程:遇到方法时不会进入方法体中执行
* F11是逐语句:遇到方法时能够进入方法体中执行
* 跳出:可以跳出正在执行的方法
* F5继续:不会调试当前语句,直接跳到下一条语句
* )
* ③观察变量:观察的是左下的变量列表,也可以选中一块右击快速监视
*(2)输出大法:(推荐)
* 利用输出语句,在认为错误的代码块中加输出语句,如果输出不符,说明这块代码不对,用于确定错误位置
*
*注意:
写代码时尽量不要重现一大段重复代码,这就是叫代码冗余
尽量不要让代码冗余
标志旗帜法 经常用来解决代码冗余
例:
string username;
string password;
do
{
Console.WriteLine("请输入用户名:");
username = Console.ReadLine();
Console.WriteLine("请输入密码:");
password = Console.ReadLine();
if (username != "admin" || password != "888888")
{
Console.WriteLine("用户名或密码错误,请重新输入!");
}
} while (username != "admin"||password!="888888");
Console.WriteLine("登录成功");
Console.ReadKey();
修改后:
string username;
string password;
bool flag = false;
do
{
flag = false;
Console.WriteLine("请输入用户名:");
username = Console.ReadLine();
Console.WriteLine("请输入密码:");
password = Console.ReadLine();
if (username != "admin" || password != "888888")
{
Console.WriteLine("用户名或密码错误,请重新输入!");
flag=true;
}
} while (flag);
Console.WriteLine("登录成功");
Console.ReadKey();
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 程序调试
{
class Program
{
static void Main(string[] args)
{
int i = 1;
while(i<=10)
{
Console.WriteLine(i);
i++;
}
Console.ReadKey();
}
}
}
7.判断结构
/*
* 判断结构(分支结构):语句在满足条件下执行
*
* 一、if单分支
* 1、形式:
* if(条件)
* {
* 语句1;
* 语句2;
* 语句3;
* }
*
* 2、执行过程:
* 首先判断条件的结果,如果条件为true,则执行语句.如果条件为false,则跳过语句,执行后面的语句
*
* 3、注意:
* (1)if后面括号中的条件(是关系、逻辑表达式),要能计算成一个bool类型的值
* (2)和if语句有关系的语句只有后面大括号中的内容
*
* 二、if-else双分支
* 1、形式:
* if(条件)
* {
* 语句; //1
* }
* else
* {
* 语句;//2
* }
*
* 2、执行过程:
* 如果条件结果为true,执行if后语句1,否则条件为false,执行else后语句2
* 根据判断条件结果,总要执行一个
*
*
* 三、if-else-if多分支
* 1、形式:
* if(条件1)
* {
* //1
* }
* else if(条件2)
* {
* //2
* }
* else
* {
* //3
* }
* 2、执行流程:
* 第一个条件不成立才会进入下一个,一旦有一个条件成立,就会执行当前后的语句,执行完跳判断
* 3、注意:
* 判断语句也可以进行嵌套
* if()
* {
* if()
* {
*
* }
* else
* {
*
* }
* }
*
* 四、switch-case语句
*
* 1、形式:
*
* switch(表达式)
* {
* case 值1:
* 语句1;
* break;
*
* case 值2:
* 语句2;
* break;
*
* //...
*
* default:
* 语句;
* break;
* }
*
* 2、执行过程:
* 首先计算表达式,然后根据计算结果匹配case后面的值
* 如果有匹配项,则执行匹配后面的语句,知道break语句跳出判断
* 如果所有的case值都不匹配,那么有default则执行default后面的语句,直到break结束
* 如果没有default,则跳出switch-case什么都不执行
*
* 3、if-else-if与switch-case语句的比较
* (1)相同点:
* 都可以实现分支结构
* (2)不同点:
* switch-case:一般只能用于等值比较
* if-else-if:可以处理范围
*
*
* 4、例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 第三题
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("请输入俩数和一个运算符:");
int a=Convert.ToInt32(Console.ReadLine()); //输入
int b=Convert.ToInt32(Console.ReadLine());
string c=Console.ReadLine();
switch(c)
{
case "+":
Console.WriteLine(a + b);
break;
case "-":
Console.WriteLine(a - b);
break;
case "*":
Console.WriteLine(a * b);
break;
case "/":
if (b == 0)
{
Console.WriteLine("0不能做除数");
}
else
{
Console.WriteLine(a/ b);
}
break;
default:
Console.WriteLine("不能识别运算符");
break;
}
Console.ReadKey();
}
}
}
*
*
* 五、三元表达式
* 1、作用:可以代替if-else,有时使用更简便
* 2、形式:
* 表达式1 ? 表达式2: 表达式3
* 例:
* int a=100,b=20;
* int max = a>b? a:b
* Console.WriteLine(max);
*
* 3、执行过程:
* 首先计算表达式1,表达式1应该是一个能够计算成bool类型的值 (相当于if后的条件)
* 如果表达式1的值为true,则表达式2的值作为整个表达式的值
* 如果表达式1的值为false,则表达式3的值作为整个表达式的值
* 4、注意:
* 表达式2和表达式3的类型一定要相同或者相容(能够发生自动转换)
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 判断
{
internal class Program
{
static void Main(string[] args)
{
}
}
}
8.循环结构
/*
* 循环结构:语句在满足条件下执行多次
*
* 一、while循环
* 1.特点:先判断,再执行
* 2.形式:
while(循环条件)
{
循环体;
}
* 3.执行过程:
* 先判断循环条件,如果条件为true,则执行循环体,循环体执行完,再去执行循环条件;
* 如果条件为false,则跳出循环,循环结束
*
* 二、do-while循环
* 1.特点:先执行,再判断
* 2.形式:
do
{
循环体;
}while(循环条件);
*
* 3.执行过程:
* 先执行循环体,
* 执行完循环体再判断循环条件是否成立,如果条件为true,则执行循环体,如果条件为false,则跳出循环
*
* 注意:
* 假如循环条件一开始就不成立,对于while循环,一次都不会执行,对于do-while循环体会执行一次
* 所以:do-while循环体至少会执行一次,while循环体可能一次都不会执行
* 所以一般要求先输入一次的循环一般都考虑用do-while循环
*
* 扩展:
* (1)try-catch的使用:
* 1.作用:检测异常,可以用try-catch来调试代码块
* 2.格式:
try //检测
{
//有可能出现异常的代码
}
catch
{
//出错后的处理
}
*
*3.执行过程:
*如果try中的代码没有出现异常,则不会执行catch中的代码
*如果try中的代码出现异常,则程序立即跳到catch中
*4.常用于输入出现异常时
*例:
try
{
int age = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("你刚刚输入的年龄为:"+age);
}
catch {
Console.WriteLine("输入错误!");
}
Console.ReadLine();
*
*
*(2)通过循环限制只能输入某些值
例:
while(answer!="y"&&answer!="n")
{
Console.WriteLine("只能输入y和n,请重新输入!");
answer=Console.ReadLine();
}
*
* 三、for循环
* 1.特点:一般用于已知循环次数的循环
* 2.形式:
for(1循环初始化;2循环条件;3用于改变循环变量的值)
{
4循环体;
}
*
* 3.执行过程:
* 首先执行1循环变量初始化,用于定义循环变量和对循环变量赋初值
* 然后执行2循环条件,如果为true,执行4循环体,如果为false,跳出循环
* 然后4循环体执行完,再去执行3用于改变循环变量的值
* 然后再执行2循环条件,依次类推
*
* 注意:1 2 3 4都可以省略,如果省略2循环条件,将是一个死循环
*
* 4.循环的嵌套
* 例:输出九九乘法表
for (int i = 1; i <= 9; i++)//外层循环:循环9次
{
//写在这里的代码属于外层循环
for (int j = 1; j <= i; j++) //内层循环:外层循环每执行1次,内层循环执行i次
{
//写在这里的代码属于内层循环
}
//写在这里的代码属于外层循环
}
* 总结:
* 三种循环可以相互转化,没有说用哪个循环对错,只能说用哪个循环更方便一些、逻辑更清晰一些
* 已知循环次数的一般用for循环,
* 循环条件比较复杂,跟循环次数无关的一般用while和do-while循环
*
* 四、break和continue 跳转语句
* 1.break:
* (1)可以用于switch-case判断中,用于跳出switch
* (2)用于循环中,立即跳出(终止)break所在的循环,一般和if配合使用
* 2.continue:
* 用于循环中,结束本次循环,继续下一次循环
* 3.goto:
* 不建议使用,来回跳,因为会破坏结构不便于阅读,要慎重使用
*
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 循环
{
class Program
{
static void Main(string[] args)
{
//格式1:
//for(int i=1;i<=9;i++) //i控制行
//{
// for(int j=1;j<=i;j++) //j控制列
// {
// Console.Write("{0}*{1}={2} ", j,i,i*j);
// }
// Console.WriteLine();
//}
//Console.ReadKey();
//格式2:
//for(int i = 1; i <= 9; i++) //外层循环:i控制行数
//{
// for (int j = i; j <= 9; j++) //内层循环:j控制列数,表示第i行的第j个式子
// {
// Console.Write("{0}*{1}={2} ", i, j, i * j);
// }
// Console.WriteLine();
//}
//Console.ReadKey();
}
}
}
9.常量、枚举类型
/*
* 常量、枚举类型
*
* 一、常量
* 常量与变量对应,常量是指值不可以改变的(变)量
* 1、定义:
* const 数据类型 常量名 = 常量值;
* 和变量定义形式很像,只是在前面加上了一个const修饰符
*
* 例:
* const double PI = 3.14; //定义常量赋初值
PI = 3.1415;//错误
*
* 注意:
* 在定义时赋值,在其他时候不允许修改这个值
*
* 2、常量的作用
* ①可以重复使用
* ②在写程序的时候,可以防止被恶意的修改掉
*
* 二、枚举类型
*
* 1、概念:
* 枚举类型:可以自己重新定义一种类型,在定义这种类型的时候一起定义了这种类型所有的值
*
* 2、定义:
enum 自己起的类型名称
{
值1,
值2,
...
值n
};
* 注意:
* 枚举的定义一般和类的定义在同一个级别,这样在同一个命名空间下的所有类就都可以使用这个枚举了。(方法中/类中也可以)
*
* 3、作用
* ①限制用户不能随意赋值,只能在定义枚举时列举的值中选择(枚举变量 = 枚举类型名.值)
* ②不需要死记每一个值是什么,只需要选择相应的值(在vs中,使用枚举类型先点空格,会提示作用,方便程序员使用)
*
* 4、注意:
* ①枚举类型内的值不需要加双引号
* ②定义枚举类型时,其中的值不能是int类型
* ③枚举类型都可以强制转换成int类型
* ④枚举类型的值在定义时是有一个默认编号的,依次从0开始
* sex = Gender.女;
Console.WriteLine(sex);
Console.WriteLine((int)sex);
* 注意:可以在枚举类型中的值中修改编号,修改一个值的编号,后面的会是前面的编号+1,但是尽量出现重复编号
* enum Gender
{
男=0, //编号是0
女, //编号是1
a=1, //编号是1,尽量不要出现这种情况
b //编号是2
}
*
* ⑤如何把一个字符串转换成字符类型?
* //枚举类型 枚举变量 = (自枚)(Enum.Parse(typeof(自枚),"待转换的字符串");
* 注意:如果让用户输入枚举的值,最好使用try-catch防止输入的不是枚举列表中的值
*
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 常量_枚举
{
/// <summary>
/// 定义了一个类型叫Gender的枚举类型,他的值有两个:男和女
/// </summary>
enum Gender
{
男, //枚举类型内的值不需要加双引号
女
}
internal class Program
{
static void Main(string[] args)
{
Gender sex; //定义Gender类型的变量,变量名叫sex
Console.WriteLine("请输入你的性别:");
//sex = Gender.女; //赋值,不能赋枚举之外的值
//Console.WriteLine(sex);
//Console.WriteLine((int)sex);
//枚举类型 枚举变量 = (自枚)(Enum.Parse(typeof(自枚),"待转换的字符串");
string s = Console.ReadLine();
try
{
sex = (Gender)(Enum.Parse(typeof(Gender), s));
switch(sex)
{
case Gender.男:
Console.WriteLine("男性");
break;
case Gender.女:
Console.WriteLine("女性");
break;
}
}
catch
{
Console.WriteLine("你输入的性别有误上!");
}
Console.ReadKey();
}
}
}
10.结构体类型
/*
* 结构体类型
* 注意:C#中的结构比C语言中的结构体扩展了很多用法,只看C的结构体的话就局限了
* C#中的结构体成员不仅可以是变量,还可以是方法
*
* 1.作用
* 可以解决:
* ①比如为了存储一个人的信息,要声明一组变量,当我们要存储n个人的信息时,就要声明n组变量 的问题
* (解决了变量名重复定义的问题)
* ②存储一个信息的这几个变量间没有关系,容易记乱
* (不会再把变量记混了)
*
* 2.定义
*
* 访问修饰符 struct 自己起的结构体类型名称
* {
* //定义结构成员:可以是变量,也可以是方法
* //注意:定义结构体成员前也要加访问修饰符
*
* } //{}后没有分号;
*
* 定义好一个结构后,就可以直接声明相应的变量了,
* 声明好变量后,通过变量名.成员名 来访问结构的成员
*
* 3、扩展——计算机的单位
* 0~255 一共256个数 2的八次方=256 是一个字节
*
* 二进制表示 0 和 1
* 计算中的最小单位叫 “位” ,bit , 比特, 0101就是4个比特 b
* 一个一个位处理太慢了,就把8个二进制位分成一组,那么8个二进制位叫做字节Byte B ,B是计算机能够处理的处理的最小单位
* 1KB(千字节) =1024B
* 1MB(兆字节) = 1024KB
* 1GB(吉字节) = 1024MB
* 1TB(太字节) = 1024GB
*
* Bps 传输速度 bit per second
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 结构
{
public enum Gender
{
男,
女,
}
public struct Person
{
public string name;
public Gender sex;
public int age;
}
class Program
{
static void Main(string[] args)
{
Person onePerson;
onePerson.name = "zhangsan";
onePerson.age = 20;
onePerson.sex = Gender.男;
Person secPerson;
secPerson.name = "lisi";
secPerson.age = 26;
secPerson.sex = Gender.女;
Console.WriteLine("随意输出一个{0}", secPerson.name);
Console.ReadKey();
}
}
}
11.数组
/*
* 数组
*
* 一、数组的作用
* ①可以帮我们一次声明多个同类型的变量
* ②这些变量在内存中是连续存储的
*
* 二、数组的声明(定义)、赋值与取值、遍历、输出
*
* 1、形式:
* ① 数据类型[] 数组名 = new 数据类型[数组长度]
* 例:int[] score = new int[5]; //声明了一个长度为5的数组,数组名叫score
* 通俗点说:声明了一个数组,里面包含了5个int类型的变量,数组名叫score,里面5个int类型的变量叫做数组的元素
* 并且对这5个元素从0依次开始编号到4 score[0]~score[4]
* 注意:
* int、double、decimal等类型的数值数组一旦声明,里面的每一个元素都被初始化成0,
* 而char类型的字符数组、string类型的字符串数组编译器不会对其进行初始化,为Null空
int[] score = new int[5]; //声明了一个长度为5的数组,数组名叫score
score[0] = 10;
score[4] = 20;
Console.WriteLine(score[0]);
Console.WriteLine(score[4]);
Console.WriteLine(score[3]);
Console.ReadKey();
*
* ② 数据类型[] 数组名 = {下标为0的元素值,下标为1的元素值,......}; //中间元素用逗号,隔开
* 例:int[] score = {1,3,8}; //score数组长度为3,其中score[0]=1,score[1]=3,score[2]=8
* string[] names={"zhangsan","lisi","wangwu"};
*
* ③ 数据类型[] 数组名 = new 数据类型[]{} 例:int[] score = new int[]{1,3,8};
* 数据类型[] 数组名 = new 数据类型[数组长度]{下标0,下标1...} 例:int[] score = new int[3]{1,3,8};
* 例: int[] score = new int[5]{1,2,3}//错误
*
* 2、如何访问数组:
* 通过下标(索引)来访问数组:数组名[下标],下标从0开始
* 例:score[0] = 10;
* 注意:
* 数组长度:通过 数组名.Length 可以获得数组的长度(即数组中有几个元素)
*
* 3、数组的赋值与取值:
* for(int i=0;i<score.length;i++)
* {
* console.writeline("请输入第{0}个人的成绩",i);
* score[i]=Convert.ToInt32(Console.ReadLine());//对数组中的元素进行赋值
* sum+=score[i];// 遍历数组,求数组中所有元素的和
* }
* 4、数组的遍历:
* for(int i=0;i<score.length;i++)
* 三、数组的应用
* 1、前后交换
* int=temp;
* temp=a[i];
* a[i]=a[a.Length-1-i];
* a[a.length-1-i]=temp;
*
* 2、冒泡排序
* (1)思路:
* 让数组中的n个元素依次进行两两比较(第i个数与第i+1个数比较),
* 经过n-1趟的两两比较,第t趟的比较次数是n-t,每趟比较完都让当前最值排到当前最后
* 核心点:
* ①
* 趟数:n个数需要排n-1趟,
* 每趟次数:第t趟的比较次数是n-t次(趟数i是从0开始数,所以t=i+1
* ②要从大到小排序,两两比较的时候使用<;从小到大排序用>
*
* (2)模板:
* for(int i=0;i<n.length-1;i++)// 控制比较趟数:共n-1趟(i+1表示当前是第几趟)
* {
* for(int j=0;j<n.Length-(i+1);j++)//控制每趟的两两比较次数:每趟比较 n-t次,t表示当前是第t趟,因为i是从0开始数,t=i+1
* {
* if(n[j]<n[j+1]) // 从大到小,用<,从小到大,用>
* {
* //交换变量
* int temp = n[j];
* n[j]=n[j+1];
* n[j+1]=temp;
* }
* }
* }
*
* 四、二维数组
* int[,] a = new int[3, 4] //二维数组初始化
{
{ 100,90,80,70},
{ 90,90,80,60 },
{ 50,70,40,80},
};
for(int i=0; i <3; i++) //求和遍历二维数组,并且输出平均值
{
int sum = 0;
for(int j=0;j<4;j++)
{
sum += a[i, j];
}
Console.WriteLine("{0}班的平均分是{1}",i+1,sum/4.0); //除以4.0防止精度缺失
}
Console.ReadKey();
}
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 数组
{
internal class Program
{
static void Main(string[] args)
{
//int[] score = new int[5]; //声明了一个长度为5的数组,数组名叫score
//score[0] = 10;
//score[4] = 20;
//Console.WriteLine(score.Length);
//Console.WriteLine(score[0]);
//Console.WriteLine(score[4]);
//Console.WriteLine(score[3]);
//Console.ReadKey();
int sum = 0;
//定义数组
int[] score = new int[10];
//对数组中的元素进行赋值
for(int i=0;i<score.Length;i++)
{
Console.WriteLine("请输入第{0}个人的成绩",i+1);
score[i] = Convert.ToInt32(Console.ReadLine());
//sum+=score[i];
}
//遍历数组,求数组中所有元素的和
for (int i = 0; i <score.Length; i++)
{
sum += score[i];
}
//输出:输出数组中的每一个元素的值
for (int i = 0; i <score.Length; i++)
{
Console.WriteLine("第{0}个人学生的成绩为{1}分", i + 1, score[i]);
}
Console.Clear(); //清屏
//输出平均成绩
Console.WriteLine("{0}个人的平均成绩为:{1}", score.Length, sum / score.Length);
Console.ReadKey();
}
}
}
12.方法
/*
* 方法、参数、返回值
*
* 一、方法(函数)
* 在C#中函数、方法统一称为方法,有的人称静态为函数,非静态的为方法,在这我们统一称为方法
* 方法就一堆代码进行重用的一种机制。方法就是一段代码,这段代码可能有输入的数据叫做参数,可能会有返回的执行结果叫做返回值
*
* 1、作用:
* 用来复用代码的,当我们在一个程序中反复的写了同样的代码,那一般情况下,我们可以把需要重复写的代码定义在一个方法中,用的时候只需要调用就行了
* 比如Console.WriteLine();就是一个方法
*
* 2、定义:
* [访问修饰符] [static] 返回值类型 方法名([参数列表]) //[]内的表示可以省略
* {
* 方法体;
* [return 返回值];
* }
*
* 注意:
* (1)方法一般要定义在类中,一般写在Main()方法后面
* (2)如果方法没有返回值,则返回值类型写void
* (3)方法的命名规则:方法名开头大写,参数名开头小写,参数名、变量名要有意义
* (4)如果方法没有参数,()不能省略
*
* 3、方法的调用:
* (1)对于静态方法(有static修饰的都是静态方法):
* ①不在同一个类中,通过 类名.方法名();调用
* ②如果是在本类中调用本类的方法,可以只写方法名(); 也可以通过类名.方法名();调用
*
* 4、return可以立即退出本方法
*
* 二、参数
* 1、变量的作用域(声明周期)
* 在方法中定义的变量成为局部变量,其作用域从定义开始,到其所在的大括号(语句块)结束为止
* 注意:
* ①字段:一个变量一旦定义在方法外,类的里面,就叫做类的字段,这个变量就可以被本类的所有方法所访问
* 但是要注意,静态方法只能访问静态字段
* ②由const修饰的常量不能定义为静态的
*
* 2、在一个方法中想要访问另一个方法中的变量,怎么办?
* 通过 参数和返回值
*
* 3、形参和实参
* 在方法名后面的括号内定义变量,叫作这个方法的参数,这里定义的变量用于接收调用者传过来的数据
* 注意:
* ①如果一个方法一旦有参数,那么调用者就必须传参数,并且传参数的个数、类型与对应位置上的个数、类型必须一致
* ②参数的作用域就是下面的方法体中
* ③当形参是数组的时候,我们传数组名
*
* 三、返回值
* 当调用者想访问我们方法中的变量时,可以通过返回值返回
* 只要在方法中使用了返回值,那么在调用方法中,前面就应该用一个变量来接收方法的返回值
* 例:
* string s = Console.Readline();
* int x = Convert.ToInt32("32");
*
* 注意:
* ①一个方法可以多个参数,但是只能有一个返回值,也可以没有
* ②一旦一个方法有返回值,那么在这个方法中,就必须通过return语句返回一个值,并且这个值要与返回值类型是相同的
*
* 四、例:ReadInt()用法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ReadInt__用法
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("请输入一个数:");
int x = ReadInt();
Console.WriteLine(x);
Console.ReadKey();
}
public static int ReadInt()
{
int number = 0;
do
{
try
{
number = Convert.ToInt32(Console.ReadLine());
return number;
}
catch
{
Console.WriteLine("输入有误,请重新输入!");
}
}
while (true);
}
}
}
*
*
* 五、方法的重载
* 一般在同一个类中,方法名相同,但方法的参数的个数不同,或者对应位置上的参数类型不同,才能构成方法的重载
* 注意:
* 方法重载和返回值没有关系
*
*
*
*
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 方法
{
internal class Program
{
static void Main(string[] args)
{
//string s = "123";
int a = Convert.ToInt32(s);
//int a = int.Parse(s);
//调用者
Add1(10, 20); //实参
int b = Add2(10, 20);
Console.WriteLine(b);
Console.ReadKey();
}
//被调用者
public static void Add1(int a, int b) //形参
{
Console.WriteLine("a+b={0}", a + b);
}
public static int Add2(int a, int b)
{
return a + b;
}
}
}
13.outref用法
/*
*
* out的用法
* 作用:当一个方法想返回多个值的时候,可以通过out实现
* 例:下方代码
* 实现步骤:
* (1)在方法的参数类型前加out,那么传参数的时候也必须在number前加out
* 表明这个参数不是传入的,而是用来传出值的
*
* (2)如果参数是以out形式传入的,那么在传入前可以不赋初值
*
* (3)在方法中对于由out修饰的参数,必须赋值,并且必须在使用前赋值
*
* out和ref:
* out用于传出值,方法中必须对out修饰的传数进行赋值
* ref可以理解成双向的,既可以传入,又可以传出
* 在传参数的过程中,如果参数有out或ref修饰的话,那么改变方法中的参数变量的值,调用者方法中的变量的值也会相应的改变
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace outref用法
{
internal class Program
{
static void Main(string[] args)
{
int number;
int result = Test(out number);
Console.WriteLine("number={0} result={1}", number, result);
Console.ReadKey();
}
static int Test(out int a)
{
a = 10;
a = a + 1;
return 200;
}
}
}
14.常用方法
/*
* 常用类和方法;
* 1、Math类
* Math.Round(); //四舍五入函数
* Math.Sqrt(); //开平方函数
* 例1:输入等边三角形的边长求面积,保留2位小数
using System; namespace 求等边三角形面积
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("请输入等边三角形的边长:");
string a=Console.ReadLine(); //输入边长为字符串类型
double x = Convert.ToDouble(a); //转化为浮点型
double ans = Math.Round(x * x * Math.Sqrt(3) / 4.0 , 2); //计算面积公式,并保留两位小数
Console.WriteLine(ans); //输出面积
Console.ReadKey();
}
}
}
*
* 例2:编一个程序,输入一个正数,对该数进行四舍五入到个位数的运算。
* 例如,实数12.56经过四舍五入运算,得到结果13;而12.46经过四舍五入运算,得到结果12。
using System;
namespace 第六题
{
internal class Program
{
static void Main(string[] args)
{
double a=Convert.ToDouble(Console.ReadLine()); //输入
Console.WriteLine(Math.Round(a,0)); //四舍五入到个位输出
Console.ReadKey();
}
}
}
* 2、Random类 随机数
* 例:编写一个掷骰子100次的程序,并输出各个点数出现的次数
using System;
namespace 第6题
{
internal class Program
{
static void Main(string[] args)
{
int[] a = new int[7];
Random random = new Random(); //定义随机数对象
for(int i=0;i<100;i++)
{
int res=random.Next(1,7); //能随机生成[1,7)范围内的数,注意不会到7,即区间范围是[1,6]
a[res]++; //利用"桶"的思想
}
Console.WriteLine("掷骰子100次后:");
for(int i=1;i<=6;i++)
{
Console.WriteLine("{0}出现的次数为{1}", i, a[i]);
}
Console.ReadKey();
}
}
}
*/