c#基础
注释符
单行注释 //
多行注释 /要注释的内容/
文档注释 ///用于注释函数和类
快捷键
功能 | 快捷键 |
---|---|
注释 | ctrl+k+c |
取消注释 | ctrl+k+u |
对齐代码 | ctrl+k+d |
帮助文档 | F1 |
智能提醒 | ctrl+j |
折叠代码 | #region(名字)#endregion |
快速折叠 | ctrl+k+s 输入#region |
向左边全选 | shift+hone |
向右边全选 | shift+end |
变量
decimal 储存金钱
两个命名规范
Camel:要求变量名中首单词的首字母小写,其余每个单词的首字母都要大写。多用于给变量命名
pascal:要求标识符中每个单词的首字母都要大写,其余字母小写,多用于给类 方法命名
转移符
符号 | 意思 |
---|---|
\n | 换行 |
\b | 回退一格 |
\t | tab键 |
@
- 取消在字符串中的转义
- 将文本按照编辑的原格式输出
类型转换
- 自动类型转换
- 强制类型转换 (待转换的类型)要转换的值 (int)double值
- 类型不兼容
类型不兼容
用Convert
面上要过的去
string s="123";
double d =Convert.ToDouble(s);
int n=Convert.ToInt32(s);
Console.WriteLine(d);
Console.WriteLine(n);
逻辑运算符
逻辑与(&&)的优先级要高于逻辑或(||)
if-else
if(a<b)
{
Console.WriteLine(b);
}
else
{
Console.WriteLine(a):
}
try-catch
如果try中的代码没有出现异常,那么catch中的代码不会执行
如果太try中的代码出现了异常,那么这行出现异常的代码以及后面的{代码}就都不会执行,
而是直接跳到catch中执行代码
//语法上没有错误,在程序运行的过程中,由于某些原因程序出现了错误,不能正常运行
bool b = true;
int number = 0;//声明了一个变量
Console.WriteLine("请输入以个数字");
try
{
//abc
number = Convert.ToInt32(Console.ReadLine());//赋值
}
//之间不能写代码,try-catch必须紧密相连
catch
{
Console.WriteLine("输入的内容不能够转换成数字");
b = false;
}
//我们如果要执行下面的这行代码,需要满足某些条件
//让代码满足某些条件去执行的话,使用bool类型
if (b)
{
Console.WriteLine(number * 2);
}
注:之间不能写代码,try-catch必须紧密相连
利用bool值处理不希望输出的代码
bool b=true;
...
{
b=false;
}
if(b)
{
}
switch-case
一般只能用于等值比较
switch(变量或者表达式的值)//与case值得数据类型一样
{
case 值1:
case 值2:
case 值3:要执行的代码;//值1、2、3所执行的代码都是一样的
break;
case 值4:要执行的代码;
break;
case 值5:要执行的代码;
break;
case 值6:要执行的代码;
break;
...
default:要执行的代码;//与以上所以得case不匹配
break;
}
while
while(循环条件)
{
循环体;
}
do-while
do
{
循环体;
}while(循环条件);
break与continue
break
- switch-case中
- 跳出当前循环
continue
立即结束本次循环,并判断循环条件,如果成立,则进入下一次循环,否则退出循环
for
for(表达式1;表达式2;表达式3)
{
循环体;
}
类型转换
Convert
用Convert进行转换,成功就ok,失败就抛异常
.Parse
和Convert效果一样,Convert的实质就是调用.Parse,失败抛异常
- int.Parse
- double.Parse
.TryParse
int.TryParse
尝试这将一个字符串转换成int类型
int number;
bool b=int.TryParse("123",out number);
Console.WriteLine(b);
Console.WriteLine(number);
True
123
int number;
bool b=int.TryParse("123a",out number);
Console.WriteLine(b);
Console.WriteLine(number);
False
0
三元表达式
表达式1?表达式2:表达式3;
随机数
//产生随机数
//1、创建能够产生随机数的对象
Random r = new Random();
//2、让产生随机数的这个对象调用方法来产生随机数
int rNumber = r.Next(1, 10);//范围区间[1,10)
Console.WriteLine(rNumber);
常量
const 变量类型 变量名 = 值 //常量不能够被重新赋值
枚举
[public] enum 枚举名//中括号中的东西可以省略
{
值1,
值2,
值3,
.......
}
public:访问修饰符,公开的公共的,哪都可以访问。
enum: 关键字,声明枚举的关键字
枚举名:要符合Pascal命名规范
枚举就是一个变量类型,(int double string decimal)
只是枚举声明、赋值、使用的方式跟那些普通的变量类型不一样
namespace _01.net.demo1
{
//声明了一个枚举 Gender
public enum Gender
{
男,
女//可加逗号,但最后一项不加逗号可以区分第几项
}
internal class Program
{
static void Main(string[] args)
{
Gender gender = Gender.男;
Console.WriteLine(gender);
}
}
}
将枚举声明在命名空间的下面,类的外面,表示这个命名空间下,所有的类都可以使用这个枚举。
数据类型之间的转换
枚举与int之间的转换
namespace _01.net.demo1
{
//声明了一个枚举 Gender
public enum QQState
{
OnLine,
OffLine,
Leave=5,
Busy,
QMe
}
internal class Program
{
static void Main(string[] args)
{
#region 枚举转int
QQState state = QQState.OnLine;
//枚举类型默认可以和int类型相互转换 枚举类型跟int类型是兼容的
int n = (int)state;
Console.WriteLine(n);
Console.WriteLine(state);
Console.WriteLine((int)QQState.OffLine);
Console.WriteLine((int)QQState.Leave);
Console.WriteLine((int)QQState.Busy);
Console.WriteLine((int)QQState.QMe);
#endregion
#region int转枚举
int n1 = 6;
QQState state1=(QQState)n1;
Console.WriteLine(state1);
#endregion
}
}
}
我们可以将一个枚举类型的变量跟int类型和string类型相互转换。
枚举类型默认是跟int类型相互兼容的,所以可以通过强制类型转换的语法相互转换。
当转换的一个枚举中没有的值的时候,不会抛异常,而是将数字显示出来。
枚举与string相互转
所有的类型都能转换成string类型
QQState state = QQState.OnLine;
string s =state.ToString();
Console.WriteLine(s);
将string转换成枚举类型
string s = "1";
QQState state = (QQState)Enum.Parse(typeof/*获取该枚举的类型*/(QQState), s);
Console.WriteLine(state);
枚举同样可以跟string类型相互转换,如果将枚举类型转换成string类型,则直接调用ToString()
如果将String转换成枚举类型则需要下面这样一行代码:
(要转换的枚举类型)Enum.Parse(typeof(要转换的枚举类型),"要转换的字符串")
如果转换的String是数字,则就算枚举中没有,也不会抛异常
如果转换的String是文本,如果枚举中没有,则会抛异常
结构
可以帮助我们一次性声明多个不同类型的变量
[public] struct 结构名
{
成员;//字段
}
变量在程序运行期间只能存储一个值,而字段可以存储多个值。
namespace _01.net.demo1
{
public struct Person
{
public/*让外界访问*/ string _name;//字段
public int _age;//用下划线区分字段和变量
public Gender _gender;
}
public enum Gender
{
男,
女
}
internal class Program
{
static void Main(string[] args)
{
Person zsPerson;
zsPerson._name = "张三";
zsPerson._age = 21;
zsPerson._gender = Gender.男;
Console.WriteLine(zsPerson._gender);
}
}
}
在定义结构时,如果向让外界访问,则必须加public
用下划线区分字段和变量
数组
一次性存储多个相同类型的变量
数组类型[] 数组名=new 数组类型[数组长度];
数组名[i]= ;
数组类型[] 数组名={1,2,3,6,4,5}
初值
int—0 string—null bool—false
在用最小值和最大值时
int max = int.MinValue;//int可以定义的最小值
int min = int.MaxValue;//int可以定义的最大值
冒泡排序
将一个数组中的元素按照从大到小或者从小到大的顺序进行排序
int [] nums={9,8,7,6,5,4,3,2,1,0};0 1 2 3 4 5 6 7 8 9
第一趟比较:8 7 6 5 4 3 2 1 0 9 交换了9次——i=0 j=nums.Lenqth-1-i
第二趟比较:7 6 5 4 3 2 1 0 8 9 交换了8次——i=1 j=nums.Length-1-i
第三趟比较:6 5 4 3 2 1 0 7 8 9 交换了7次——i=2 j=nums.Length-1-i
第四趟比较:5 4 3 2 1 0 6 7 8 9 交换了6次——i=3 j=nums.Length-1-i
第五趟比较:4 3 2 1 0 5 6 7 8 9 交换了5次
第六趟比较:3 2 1 0 4 5 6 7 8 9 交换了4次
第七趟比较:2 1 0 3 4 5 6 7 8 9 交换了3次
第八趟比较:1 0 2 3 4 5 6 7 8 9 交换了2次
第九趟比较:0 1 2 3 4 5 6 7 8 9 交换了1次
int[] nums = {9,8,7,6,5,4,3,2,1,0};
for(int i=0;i<nums.Length-1;i++)//表示躺数
{
for(int j=0;j<nums.Length-1-i;j++)//比较与交换
//for(int j=0;j<nums.Length-1;j++)//少了-i少进行几次无用的比较,效率更高
{
if (nums[j] > nums[j+1])
{
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
for(int i=0;i<nums.Length;i++)
{
Console.WriteLine(nums[i]);
}
利用函数实现
int[] nums = {9,8,7,6,5,4,3,2,1,0};
Array.Sort(nums);//只能针对数组进行有一个升序的排列
Array.Reverse(nums);//对数组进行反转
for(int i=0;i<nums.Length;i++)
{
Console.WriteLine(nums[i]);
}
函数
[public] static 返回值类型 函数名([参数列表])
{
函数体;
}
public:访问修饰符,公开的,公共的,哪都可以访问。
static:静态的
返回值类型:int double…如果不需要返回值,写void
函数名:Pascal 每个单词的首字母都大写,其余字母小写
参数列表:完成这个函数所必须要提供给这个函数的条件。如果没有参数,小括号也不能省略
函数的调用
类名.函数名([参数]);
namespace _01.net.demo1
{
internal class Program
{
static void Main(string[] args)
{
int a1 = 1;
int a2 = 2;
int max = GetMax(a1, a2);//实参
Console.WriteLine(max);
}
/// <summary>
/// 计算两个整数的最大值并且将最大值返回
/// </summary>
/// <param name="n1">第一个整数</param>
/// <param name="n2">第二个整数</param>
/// <returns>将最大值返回</returns>
public static int GetMax(int n1, int n2)//形参
{
int max= n1 > n2 ? n1 : n2;
return max;
}
}
}
如果所写的函数与Main()函数同在一个类里,类名可以省略
return
- 在函数中返回要返回的值
- 立即结束本次函数
函数的调用问题
我们在Main()函数中,调用Test()函数,我们管Main()函数称之为调用者,管Test(函数称之为被调用者。
如果被调用者想要得到调用者的值:
- 传递参数。
- 使用静态字段来模拟全局变量。
internal class Program
{
//字段 属于类的字段
public static int _number=10;
}
<练习>读取输入的整数,封装成函数,
多次调用(如果用户输入的是数字,则返回,否则提示用户重新输入)
namespace _01.net.demo1
{
internal class Program
{
static void Main(string[] args)
{
//读取输入的整数,封装成函数,
//多次调用(如果用户输入的是数字,则返回,否则提示用户重新输入)
Console.WriteLine("请输入一个数字");
string input = Console.ReadLine();
int number = GetNumber(input);
Console.WriteLine(number);
}
/// <summary>
/// 对主函数里传入的string类型数据进行int转换,若无法转换,则重新输入
/// </summary>
/// <param name="s">用户输入的字符串</param>
/// <returns>用户输入的数字</returns>
public static int GetNumber(string s)
{
while (true)
{
try
{
int number = int.Parse(s);
return number;
}
catch
{
Console.WriteLine("请重新输入");
s = Console.ReadLine();
}
}
}
}
}
- 如果调用者想要得到被调用者的值:返回值
- 不管时形参还是实参,都是在内存中开辟了空间的。
- 方法的功能一定要单一
- 方法中最忌讳的就是出现提示用户输入的
参数out ref params
out参数
如果你在一个方法中,返回多个相同类型的值的时候,可以考虑返回一个数组
但是,如果返回多个不同类型的值的时候,返回数组就不行了,那么这个时候
我们就可以考虑使用out参数。
out参数就侧重于在一个方法中可以返回多个不同类型的值。
out参数要求在方法的内部必须为其赋值
namespace _01.net.demo1
{
internal class Program
{
static void Main(string[] args)
{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int max=0;//函数中会进行赋值,所以可以不在主函数中赋值;
int min;
int sum;
int avg;
bool b;
string s;
double d;
Test(numbers, out max, out min, out sum, out avg,out b,out s,out d);
Console.WriteLine(max);
Console.WriteLine(min);
Console.WriteLine(sum);
Console.WriteLine(avg);
Console.WriteLine(b);
Console.WriteLine(s);
Console.WriteLine(d);
}
/// <summary>
/// 计算一个整数数组的最大值、最小值、平均值、总和
/// </summary>
/// <param name="nums">要求值的数组</param>
/// <param name="max">多余返回的最大值</param>
/// <param name="min">多余返回的最小值</param>
/// <param name="sum">多余返回的总和</param>
/// <param name="avg">多余返回的平均值</param>
public static void Test(int[] nums,out int max,out int min,out int sum,out int avg,out bool b,out string s,out double d)
{
//out参数要求在方法的内部必须为其赋值
max = nums[0];
min = nums[1];
sum = 0;
for(int i = 0; i < nums.Length; i++)
{
if(nums[i] > max)
{
max=nums[i];
}
if(nums[i] < min)
{
min=nums[i];
}
sum+=nums[i];
}
avg = sum / nums.Length;
b = true;
s = "123";
d = 3.14;
}
}
}
ref参数
能够将一个变量带入一个方法中进行改变,改变完成后,再将改变后的值带出方法。
要求方法外必须为其赋值,而方法内可以不赋值。
<练习>使用方法来交换两个int类型的变量
namespace _01.net.demo1
{
internal class Program
{
static void Main(string[] args)
{
//使用方法来交换两个int类型的变量
int a1 = 1;
int a2 = 2;
Change(ref a1, ref a2);
Console.WriteLine(a1);
Console.WriteLine(a2);
}
public static void Change(ref int num1,ref int num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}
}
}
params可变参数
将实参列表中跟可变参数数组类型一致的元素都当做数组的元素去处理。
参数数组必须是形参列表的最后一个元素
namespace _01.net.demo1
{
internal class Program
{
static void Main(string[] args)
{
Test("张三",14,99,88,77);
}
public static void Test(string name,int id ,params int[] score)
{
int sum=0;
for(int i=0; i<score.Length; i++)
{
sum += score[i];
}
Console.WriteLine("{0}这次考试的总成绩是{1},学号是{2}",name, sum,id);
}
}
}
方法的重载
概念:方法的重载指的就是方法的名称相同,但是参数不同。
参数不同,分为两种情况
- 如果参数的个数相同,那么参数的类型就不能相同
- 如果参数的类型相同,那么参数的个数就不能相同
方法的重载和返回值没有关系
namespace _01.net.demo1
{
internal class Program
{
static void Main(string[] args)
{
int sum1 = M(1,2);
double sum2=M(1.1,1.2);
string sum3 = M("张三","罗翔");
Console.WriteLine(sum1);
Console.WriteLine(sum2);
Console.WriteLine(sum3);
}
public static int M(int n1,int n2)
{
return n1 + n2;
}
public static double M(double n1,double n2)
{
return n1 + n2;
}
public static string M(string n1,string n2)
{
return n1 + n2;
}
public static int M(int n1,int n2,int n3)
{
return n1 + n2 + n3;
}
}
}
方法的递归
方法自己调用自己
namespace _01.net.demo1
{
internal class Program
{
static void Main(string[] args)
{
TellStory();
}
public static int _i = 0;//利用静态字段来模拟全局变量来解决i的值不断重置的问题
public static void TellStory()
{
Console.WriteLine("从前有座山");
Console.WriteLine("山里有座庙");
Console.WriteLine("庙里有个老和尚和小和尚");
Console.WriteLine("有一天,小和尚哭了,老和尚给小和尚讲了一个故事");
_i++;
if (_i >= 5)
{
return;
}
TellStory();
}
}
}
方法的练习
提示用户输入两个数字,计算这两个数字之间所有整数的和, (1)用户只能输入数字 (2)计算两个数字之间和 (3)要求第一个数字必须比第二个小,否则重新输入namespace _01.net.demo1
{
internal class Program
{
static void Main(string[] args)
{
//提示用户输入两个数字 计算这两个数字之间所有整数的和
//用户只能输入数字
//计算两个数字之间和
//要求第一个数字必须比第二个小,否则重新输入
Console.WriteLine("请输入第一个数字");
string strNumberOne = Console.ReadLine();
int numberOne = GetNumber(strNumberOne);
Console.WriteLine("请输入第二个数字");
string strNumberTwo = Console.ReadLine();
int numberTwo = GetNumber(strNumberTwo);
//判断第一个数字是否小于第二个数字
JudgeNumber(ref numberOne,ref numberTwo);
//求和
int sum = GetSum(numberOne, numberTwo);
Console.WriteLine(sum);
}
public static int GetNumber(string s)
{
while (true)
{
try
{
int number = Convert.ToInt32(s);
return number;
}
catch
{
Console.WriteLine("输入有误!!!请重新输入");
s = Console.ReadLine();
}
}
}
public static void JudgeNumber(ref int n1,ref int n2)
{
while (true)
{
if (n1 < n2)
{
//符合题意
return;
}
else
{
Console.WriteLine("第一个数字不能大于或者等于第二个数字,请重新输入第一个数字");
string s1 = Console.ReadLine();
n1 = GetNumber(s1);
Console.WriteLine("请重新输入第二个数字");
string s2 = Console.ReadLine();
n2 = GetNumber(s2);
}
}
}
public static int GetSum(int n1, int n2)
{
int sum = 0;
for(int i=n1 ; i<=n2; i++)
{
sum += i;
}
return sum;
}
}
}