【C#学习记录】一、面向对象前的基础知识
学习C#记录
学习视频地址:https://b23.tv/BV1FJ411W7e5
前言
学习C#的记录,记录的基本都是我不会的或者容易忘记的
一、转移字符
1.常见转移字符
\n 换行
mac系统能够识别,但是对于Windows的应用,需要使用/r/n这种写法
\b回车
字符串中,首尾部分使用是无效的
\t制表符
用于排列格式输出,经常用于排版
"双引号
这里双引号可以替换成/,用于保持符号的文本意思
2.@符号
1、取消\字符串中的转义作用
string path = @“F:\a\b\c.txt”;
Console.WriteLine(path);
Console.ReadKey();
2、保留原格式输出
string filetxt = @"今天天气好晴朗
处处好风光";
Console.WriteLine(filetxt);
Console.ReadKey();
二、快捷键
注释:ctrl+k+c
取消注释:ctrl+k+u
对齐代码:ctrl+k+d
F1:转到MSDN
撤销:ctrl+z
保存:ctrl+s
智能提示:ctrl+j
折叠代码:#region #endregion
shift+home:向左边全选
shift+end:向右边全选
三、类型转换
1.类型相同直接转
int 和double
小转大,显式转换
大转小,隐式转换
2.类型不同用Convert/Parse
使用转换工厂Convert进行转换,不过一定要注意,转换的条件就是面上要过得去
string s1 = "123";
double d = Convert.ToDouble(s);
int n = Convert.ToInt32(s);
这里字符串s1如果是“abc”,那就不能转换了
这里面一个经典用法是,将用户输入的字符串转换成我们需要的数字
Console.WriteLine("输入成绩");
string strGrade = Console.ReadLine();
Console.WriteLine("您的成绩是:{0:0.00}",Convert.ToInt32.(strGrade));
Console.WriteLine("您的成绩是:{0:0.00}",int.Parse(strGrade));
这里格式化输出的格式为{0:0.00}占位符为0,保留两位小数
Convert.ToInt32()和int.Parse()效果一样
3.TryParse
TryParse尝试转换,转换成功返回bool 1,失败返回bool 0
int number = 0;
bool b = int.TryParse("123abc", out number);
Console.WriteLine(b);
Console.WriteLine(number);
Console.ReadKey();
4.所有类型都能转换成字符串string类型
int n1 = 3;
double d1 = 0.01;
public enum Number
{
a,
b,
c
}
Number number = Number.a
Console.WriteLine("{0},{1},{2}",n1.ToString(),d1.ToString(),number.ToString());
5.枚举类型的转换
public enum Season
{
春,
夏,
秋,
冬
}
string s1 = "0";
Season season = (Season)Enum.Parse(typeof(Season),s1);
Console.WriteLine("{0}",season);
上述输出结果为春
- 1.枚举类型默认是跟int类型相互兼容的,所以可以通过强制类型转换的语法互相转换。
- 2.当转换一个枚举中没有的值的时候,不会抛异常,而是直接将数字显示出来。
- 3.枚举类型同样也可以跟string类型相互转换,如果将枚举类型转换成string类型,则直接调用ToString(),
如果将字符串转换成枚举类型,则需要下面这样一行代码:
(要转换的枚举类型)Enum.Parse(typeof(要转换的额枚举类型),"要转换的字符串");
如果转换的字符串是数字,则就算枚举中没有,也不会抛异常。
如果转换的字符串是文本,如果枚举中没有,则会抛异常。
四、产生随机数
Random r = new Random();
int rNumber = r.Next(1,10);
注意,这里是左闭右开区间,也就是说上面代码只能产生1到9的随机数
五、枚举
1.语法
[public] enum 枚举名
{
值1,
值2,
......
}
2.应用场景
对于某些需要统一的名称时,防止每个人定义的变量名不一样,例如:
char gender = '男';
string s1 = "male";
string ss1 = "爷们";
上面的例子中,不同的人定义的性别可能不一样
如果按照下面这样定义
public enum Gender
{
男,
女
}
static void Main(string[] args)
{
int n = 10;
Gender gender = Gender.男;
Console.WriteLine("{0},(int)Gender.女");
}
上面的gender是Gender类型的,但是它不是一个类
3.应用注意点
1、枚举声明到命名空间的下面,main的上面,表示所有的类都能使用这个枚举
2、枚举也是一个变量类型,和int,double,string等一样
3、枚举类型默认可以跟int类型互相转换,枚举类型跟int类型是兼容的
int类型强转成枚举类型
int n1 = 1;
Gender gender = (Gender)n1;
上面n1=1可以输出,但是如果n1 = 3,则结果输出还是3
4、所有类型都可以转换成string类型
5、string类型转换为对应的枚举类型
- 1.枚举类型默认是跟int类型相互兼容的,所以可以通过强制类型转换的语法互相转换。
- 2.当转换一个枚举中没有的值的时候,不会抛异常,而是直接将数字显示出来。
- 3.枚举类型同样也可以跟string类型相互转换,如果将枚举类型转换成string类型,则直接调用ToString(),
如果将字符串转换成枚举类型,则需要下面这样一行代码:
(要转换的枚举类型)Enum.Parse(typeof(要转换的额枚举类型),"要转换的字符串");
如果转换的字符串是数字,则就算枚举中没有,也不会抛异常。
如果转换的字符串是文本,如果枚举中没有,则会抛异常。
六、结构
结构可以帮助我们一次性声明多个不同类型的变量。
1.语法结构
结构也命名在命名空间后面Main前面。
[public] struct 结构名
{
public 类型名 变量名;//成员
public 类型名 变量名;
......
}
2.应用举例
public struct Person
{
string _name;
int _age
char _gender;
}
public enum Gender
{
男;
女;
}
Person zsPerson;
zsPerson._name = "张三";
zsPerson._age = 18;
zsPerson._gender = Gender.男;
Person lsPerson;
lsPerson._name = "李四";
lsPerson._age = 18;
lsPerson._gender = Gender.女;
3.注意事项
- 结构体内为字段,变量在程序运行期间只能存一个值,而字段可以存很多值,字段前面加下划线与变量进行区分
七、数组
一次性存储多个相同类型的变量。
1.语法结构
数组类型[] 数组名=new 数组类型[数组长度];
2.应用举例
int[] nums = new int[10];//推荐
int[] numsTwo = {1,2,3,4,5,6}//推荐
int[] numsThree = new int[3]{1,2,3}//不推荐
int[] numsFour = new int[]{1,2,3}//不推荐
3.注意事项
- 初始默认值
int | string | bool |
---|---|---|
0 | null | false |
注意null和“”的区别,null表示没有在内存里面开空间,“”在内存里面开空间了,值为空 |
八、排序
Array.Sort(nums);
对数组进行排序,升序,没有返回值
Array.Reverse(nums);
对数组进行反序,反转数组,没有返回值
九、方法
1.语法结构
[访问修饰符] [static] 返回值类型 方法名([参数列表])
{
方法体;
}
2.使用注意点
-
我们在Main()函数中,调用Test()函数,我们管Main()函数称之为调用者,管Test()函数称之为被调用者。
- 如果被调用者想要得到调用者的值:
1)、传递函数
2)、使用静态字段来模拟全局变量。
如果调用者想要得到被调用者的值:
1)、返回值
-
不管是形参还是实参,都在内存中开辟了空间
-
方法的功能一定要单一
-
方法中最忌讳的就是出现提示用户输入的字眼
3.高级参数out ref param
1.out
当返回值有多个,并且类型不一的时候,用out参数
public static void Test(int[] nums,out int max,out int min,out int sum,out int average)
{
//out参数要求在方法的内部给其赋值
max = nums[0];
min = nums[0];
for(int i = 0;i < nums.Length; i++)
{
if(max<nums[i])
{max = nums[i];}
if(min>nums[i])
{min = nums[i];}
sum = sum + nums[i];
}
average = sum/nums.Length;
}
public static bool MyTryParse(string s, out int result)
{
try
{
result = Convert.ToInt32(s);
return true;
}
catch
{
result = 0;
return false;
}
}
2.ref
能够将一个变量带入一个方法中进行改变,改变完成后,再将值带出方法。
ref要求变量在方法外进行赋值,但方法内不要求赋值
int n1 = 5;
int n2 = 9;
test(ref n1,ref n2);
public static void test(ref int n1,ref int n2)
{
n1 = n1-n2;
n2 = n2+n1;
n1 = n2-n1;
}
3.params
将实参列表中跟可变参数数组类型一致的元素都当作数组的元素去处理
string name = "zhangsan";
Test(name,88,99,100);
public static void Test(string name,params int[] score)
{
int sum = 0;
for(int i = 0;i<score.Length;i++)
{
sum = sum + score[i];
}
}
注意
-
params可变参数必须是形参列表中的最后一个元素
-
params参数在形参列表中只能有一个,唯一性
4.方法的重载
方法的重载指的就是方法的名称相同,但是参数不同
这里严谨的说法应该是方法的签名不同,签名指方法的参数类型和个数
方法的返回值和重载没有关系
5.方法的递归调用
飞行棋项目练习
今天终于完成了面向对象前的学习部分,跟着视频敲了一遍项目代码,觉得老师的思维方式真的是很有条理,是一种很好的面向工程的思维方式。有时间自己独立敲一遍这个项目,现将代码记录如下:
// See https://aka.ms/new-console-template for more information
namespace _飞行棋游戏
{
class Program
{
//地图
public static int[] Maps = new int[100];
//存储玩家A和玩家B的坐标
public static int[] PlayerPos = new int[2];
//存储玩家A和玩家B的姓名
public static string[] PlayerNames = new string[2];
//两个玩家的标记
static bool[] Flags = new bool[2];
static void Main(string[] args)
{
GameShow();
#region 输入玩家姓名
Console.WriteLine("请输入玩家A的姓名");
PlayerNames[0] = Console.ReadLine();
while (PlayerNames[0]=="")
{
Console.WriteLine("玩家A的姓名不能为空,请重新输入");
PlayerNames[0] = Console.ReadLine();
}
Console.WriteLine("请输入玩家B的姓名");
PlayerNames[1] = Console.ReadLine();
while (PlayerNames[1] == ""||PlayerNames[0]==PlayerNames[1])
{
if(PlayerNames[1]=="")
{
Console.WriteLine("玩家B的姓名不能为空,请重新输入");
}
else
{
Console.WriteLine("玩家B的姓名不能和玩家A相同");
}
PlayerNames[1] = Console.ReadLine();
}
#endregion
//玩家姓名输入OK之后,我们首先应该清屏
Console.Clear();//清屏
GameShow();
InitialMap();
DrawMap();
while(PlayerPos[0]<99&&PlayerPos[1]<99)
{
if (Flags[0]==false)
{
PlayGame(0);
}
else
{
Flags[0] = false;
}
if (PlayerPos[0]>99)
{
Console.WriteLine("{0}赢了{1}", PlayerNames[0], PlayerNames[1]);
break;
}
if (Flags[1]==false)
{
PlayGame(1);
}
else
{
Flags[1] = false;
}
if (PlayerPos[1] > 99)
{
Console.WriteLine("{0}赢了{1}", PlayerNames[1], PlayerNames[0]);
break;
}
}
Win();
Console.ReadKey();
}
/// <summary>
/// 绘制游戏头
/// </summary>
public static void GameShow()
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("**************************");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("**************************");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("**************************");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("*********飞行棋项目*******");
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("**************************");
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("**************************");
Console.ForegroundColor = ConsoleColor.White;
}
/// <summary>
/// 初始化地图
/// </summary>
public static void InitialMap()
{
int[] luckyturn = { 6, 23, 40, 55, 69, 83 };//幸运轮盘☉
for (int i = 0; i < luckyturn.Length; i++)
{
Maps[luckyturn[i]] = 1;
}
int[] landMine = { 5, 13, 17, 33, 38, 50, 64, 80, 94 };//地雷☆
for (int i = 0; i < landMine.Length; i++)
{
Maps[landMine[i]] = 2;
}
int[] pause = { 9, 27, 60, 93 };//暂停▲
for (int i = 0; i < pause.Length; i++)
{
Maps[pause[i]] = 3;
}
int[] timeTunnel = { 20, 25, 45, 63, 72, 88, 90 };//时空隧道卍
for (int i = 0; i < timeTunnel.Length; i++)
{
Maps[timeTunnel[i]] = 4;
}
}
/// <summary>
/// 绘制地图
/// </summary>
public static void DrawMap()
{
Console.Clear();
GameShow();
Console.WriteLine("{0}用A表示\r\n{1}用B表示", PlayerNames[0],PlayerNames[1]);
Console.WriteLine("图例:幸运轮盘:☉ 地雷:☆ 暂停:▲ 时空隧道:卍");
//第一横行
for (int i = 0;i < 30;i++ )
{
DrawStringMap(i);
}
Console.WriteLine();
//第一竖行
for (int i = 30; i <35 ; i++)
{
for (int j = 0; j < 29; j++)
{
Console.Write(" ");
}
DrawStringMap(i);
Console.WriteLine();
}
//第二横行
for (int i = 64; i >= 35 ; i--)
{
DrawStringMap(i);
}
Console.WriteLine();
//第二竖行
for (int i = 65; i < 70; i++)
{
DrawStringMap(i);
Console.WriteLine();
}
//第三横行
for (int i = 70; i < 100; i++)
{
DrawStringMap(i);
}
Console.WriteLine(); //画完地图后需要换行
}
/// <summary>
/// 绘制关卡
/// </summary>
/// <param name="i"></param>
public static void DrawStringMap(int i)
{
if (PlayerPos[0] == PlayerPos[1] && PlayerPos[1] == i)
{
Console.Write("<>");
}
else if (PlayerPos[0] == i)
{
//shift+空格,切换全角
Console.Write("A");
}
else if (PlayerPos[1] == i)
{
Console.Write("B");
}
else
{
switch (Maps[i])
{
case 0:
Console.ForegroundColor = ConsoleColor.White;
Console.Write("□");
break;
case 1:
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write("☉");
break;
case 2:
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("☆");
break;
case 3:
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("▲");
break;
case 4:
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("卍");
break;
}
}
Console.ForegroundColor = ConsoleColor.White;
}
/// <summary>
/// 玩游戏
/// </summary>
public static void PlayGame(int playerNumber)
{
Random r = new Random();
int rNumber = r.Next(1, 7);
Console.WriteLine("{0}按任意键开始掷骰子", PlayerNames[playerNumber]);
Console.ReadKey(true);
Console.WriteLine("{0}掷出了{1}", PlayerNames[playerNumber],rNumber);
PlayerPos[playerNumber] += rNumber;
Console.ReadKey(true);
Console.WriteLine("{0}按任意键开始行动", PlayerNames[playerNumber]);
Console.ReadKey(true);
//玩家A有可能踩到了玩家B 方块 幸运轮盘 地雷 暂停 时空隧道
if (PlayerPos[playerNumber] == PlayerPos[1- playerNumber])
{
Console.WriteLine("玩家{0}踩到了玩家{1},玩家{1}退6格", PlayerNames[playerNumber], PlayerNames[1 - playerNumber]);
PlayerPos[1 - playerNumber] -= 6;
Console.ReadKey(true);
}
else//踩到了关卡
{
switch (Maps[PlayerPos[playerNumber]])
{
case 0:
Console.WriteLine("玩家{0}踩到了方块,安全", PlayerNames[playerNumber]);
Console.ReadKey(true);
break;
case 1:
Console.WriteLine("玩家{0}踩到了幸运轮盘,请选择 1--交换位置 2--轰炸对方", PlayerNames[playerNumber]);
string input = Console.ReadLine();
while (true)
{
if (input == "1")
{
Console.WriteLine("玩家{0}选择跟玩家{1}交换位置", PlayerNames[playerNumber], PlayerNames[1- playerNumber]);
int temp = PlayerPos[playerNumber];
PlayerPos[playerNumber] = PlayerPos[1- playerNumber];
PlayerPos[1- playerNumber] = temp;
Console.WriteLine("交换完成!!!按任意键继续游戏!!!");
Console.ReadKey(true);
break;
}
else if (input == "2")
{
Console.WriteLine("玩家{0}选择轰炸玩家{1}", PlayerNames[playerNumber], PlayerNames[1- playerNumber]);
PlayerPos[1- playerNumber] -= 6;
Console.WriteLine("玩家{0}退了6格", PlayerNames[1- playerNumber]);
Console.ReadKey(true);
break;
}
else
{
Console.WriteLine("只能输入1或者2,请重新输入");
input = Console.ReadLine();
}
}
break;
case 2:
Console.WriteLine("玩家{0}踩到了地雷,退6格", PlayerNames[playerNumber]);
Console.ReadKey(true);
PlayerPos[playerNumber] -= 6;
break;
case 3:
Console.WriteLine("玩家{0}踩到了暂停,暂停一回合", PlayerNames[playerNumber]);
Flags[playerNumber] = true;
Console.ReadKey(true);
break;
case 4:
Console.WriteLine("玩家{0}踩到了时空隧道,前进10格", PlayerNames[playerNumber]);
Console.ReadKey(true);
PlayerPos[playerNumber] += 10;
break;
}
}
ChangePos();
Console.Clear();
DrawMap();
}
/// <summary>
/// 限定玩家位置,当玩家坐标改变时候调用
/// </summary>
public static void ChangePos()
{
if (PlayerPos[0]<0)
{
PlayerPos[0] = 0;
}
if (PlayerPos[0] > 99)
{
PlayerPos[0] = 99;
}
if (PlayerPos[1] < 0)
{
PlayerPos[1] = 0;
}
if (PlayerPos[1] > 99)
{
PlayerPos[1] = 99;
}
}
/// <summary>
/// 胜利标志
/// </summary>
public static void Win()
{
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
Console.WriteLine("⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞⊞");
}
}
}
总结
以上是面向对象课程之前的基础知识的小集合,后面的博文从面向对象开始记录
本文来自博客园,作者:翻兽,转载请注明原文链接:https://www.cnblogs.com/xuzhq/p/15900731.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?