WPF-CSharp入门
配置环境
安装 .NET(长期支持版本)
安装后cmd输入dotnet --version
,得到版本信息即安装成功。
1 | C:\Users\gcnanmu>dotnet --version |
如果提示
Could not execute because the application was not found or a compatible .NET SDK is not installed.
Possible reasons for this include:
- You intended to execute a .NET program:
The application ‘–version’ does not exist.- You intended to execute a .NET SDK command:
It was not possible to find any installed .NET SDKs.
Install a .NET SDK from:
https://aka.ms/dotnet-download查看
C:\Program Files (x86)\dotnet
和C:\Program Files\dotnet
是否都存在dotnet.exe
。如果都存在,将C:\Program Files (x86)\dotnet
中的重命名。反之检查是否安装.NET SDK
在VsCode中安装插件
打开Code Runner
插件的设置,找到Code-runner: Executor Map
,点击打开settings.json
,添加"csharp": "dotnet run"
。如下
1 | "code-runner.executorMap": { |
设置之后就可以右键Run Code
直接运行cs文件。
新建文件夹,在当前目录下执行
1 | dotnet new console |
运行结果
1 | PS D:\C#> dotnet run "d:\C#\Program.cs" |
项目结构
1 | C# |
只需在Program.cs
中编写代码即可
在VsCode中,可以使用
region
来折叠代码块
1
2
3
// code here在 C# 9.0 及更高版本中,引入了顶级语句(Top-level Statements)的概念,顶级语句允许你在没有显式定义命名空间和类的情况下编写代码。这对于编写小型示例程序或脚本非常方便。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 // 之前
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
int i = 0;
Console.WriteLine(i.GetType().Name); // Output: Int32
Console.WriteLine(typeof(int)); // Output: System.Int32
}
}
}
1
2
3
4
5 // 现在
int i = 0;
Console.WriteLine(i.GetType().Name); // Output: Int32
Console.WriteLine(typeof(int)); // Output: System.Int32在简单的程序中,不需要显式地定义
namespace
、class
和Main
方法,编译器会自动为你生成这些结构,使代码更简洁。
注释
和C++基本相同,特殊的///
方式用于class与函数(上方)做说明并显示文档。
1 | namespace Program |
控制台输入与输出
API都在Console
中
输出:
Console.WriteLine();
输出内容自动换行,只能有一个参数,多给参数不打印。Console.Write();
输出内容不换行,不支持空参
1 | Console.WriteLine("\"Hello World\""); |
输入:
Console.ReadLine();
- 等待输入,直到回车结束Console.ReadKey();
- 等待键盘输入,按下任何键都会结束并打印键值
1 | Console.Write("请输入你的姓名:"); |
变量
变量类型
C#的变量类型:
类型 | 关键字 | 说明 |
---|---|---|
有符号整数类型 | int、short、long、sbyte | sbyte 的范围是-128-127(八位补码),其余和C语言相同(C#超过范围编译器会报错) |
无符号整型 | byte、uint、ushort、ulong | u的意思是unsigned ,即无符号整数,参见计算机组成原理。byte 的范围是0-255(八位无符号整数) |
浮点数类型 | float、double、decimal | 有效数字:从左往右第一个非零数字(超过有效数字会自动四舍五入)float 7/8位有效数字double 15-17位有效数字decimal 27-28位有效数字 |
特殊类型 | bool、char、string | bool - true or falsechar - 一个字符 只能用单引号string - 只能用双引号 |
浮点数赋值的特殊点
1 |
|
多个变量同时赋值(可以不赋值)
1 | int a1 = 1, a2 = 2, a3 = 3, a4 = 4; |
小练习
1 |
|
结果是
1 | name: gcnanmu |
可以使用
变量.GetType()
的方式获取变量的类型
1
2
3
4 int i = 0;
Console.WriteLine(i.GetType().Name); // Output: Int32
Console.WriteLine(typeof(int)); // Output: System.Int32
变量大小
使用sizeof获取变量大小(默认是字节)
1 | // 单位为字节 |
总结:
类型 | 大小 |
---|---|
byte | 1 |
short | 2 |
int | 4 |
long | 8 |
float | 4 |
double | 8 |
decimal | 16 |
bool | 1 |
char | 2 |
特殊点:
- C#的
char
字节数为2 - string类型无法使用
sizeof
变量命名规范
必须遵守的规则:
- 不能重名
- 不能使用关键字
- 不能以数字开头
- 不能由特殊符号(除了下划线)
命名规范
- 驼峰命名 - 首字母小写,之后单词的开头大写 如
yourName
、myName
、myAddress
- 帕斯卡命名法 - 所有的单词字母都大写(常用在函数和类)如
YourName
、MyName
、MyAddress
C#区分大小写
常量
两个特点
- 必须初始化
- 后续不可被修改
1 | const string myName = "gcnanmu"; |
转义字符
可以使用\
来取消转义,可以用来打印特殊的符号
名称 | 用法 |
---|---|
换行 | \n |
制表符 | \t |
退格 | \b |
警报音 | \a |
结束 | \0 |
可使用@
取消转义字符
1 | string str = @"\n"; |
可在""
前加上$
来进行字符串插值,将变量包裹在{}
中
1 | string str = "World"; |
类型转换
隐式转换
- 大范围装小范围的变量
long->int->short->sbyte
无法将float和double转化为decimal
bool、char、string之间不存在隐式转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14int i = 1;
short s = 1;
long l = 1;
byte b = 1;
// 无法将类型“int”隐式转换为“byte”。
b = i;
decimal d = 1;
float f = 1;
double db = 1;
// 无法将类型“float”隐式转换为“decimal”
d = f;
// 无法将类型“double”隐式转换为“decimal”
d = db;
- 无符号与有符号的转化
无符号数无法装有符号的
有符号的可以装无符号的,前提是有符号数的范围必须涵盖无符号的表示范围
1
2
3
4
5
6
7int i = 1;
long l = 1;
uint i2 = 1;
// 无法将类型“uint”隐式转换为“int” uint的整数表示范围超过了int
// i = i2;
// 没报错
l = i2;
浮点数可以装无符号和有符号整数,因为浮点数的范围足够大
double -> float -> 所有的整数
decimal -> 所有的整数
整数不能装浮点数
bool、string没有办法和其他类型隐士转化
char类型可以转化为ASCII码存入整形
1
2
3
4char a = 'a';
int i = a;
Console.WriteLine(i);// 97
显示转化
遵循计算机组成原理
- 高位->低位 : 高位截断
- 地位->高位 : 高位补符号位
- 无符号->有符号:只更改最高位的解释
使用()变量名
的方式进行转化
特殊的
char
与数值类的转化1
2
3
4
5int a = 'A';
char b = (char)a;
Console.WriteLine(a); // 65
Console.WriteLine(b); // Abool
和string
不能通过括号进行强制转化,可通过类型.Parse()
将字符串转化为其他类型,但是要合法合规1
2
3
4
5
6
7
8
9
10
11
12
13string str = "1";
int i = int.Parse(str);
string str2 = "true";
bool b = bool.Parse(str2);
// 打印i的类型
Console.WriteLine(i.GetType().Name); // Int32
Console.WriteLine(i); // 0
// 打印b的类型 字符串只能是false或者true
Console.WriteLine(b.GetType().Name); // Boolean
Console.WriteLine(b); // TrueConvert
方法进行转化1
2
3
4
5
6
7
8
9bool t = true;
int a = Convert.ToInt32(t);
Console.WriteLine(a); // 1
char c = Convert.ToChar(int.Parse("65"));
Console.WriteLine(c); // A1
2
3
4
5
6
7
8int i = 1;
// 特殊的ToSingle
float f = Convert.ToSingle(i);
Console.WriteLine(f);
string str = Convert.ToString(i);
Console.WriteLine(str);.toString()
转string
类型1
2
3string str = 1.ToString();
Console.WriteLine(str); // 1
异常捕获
作用:出错不会导致程序异常执行结束,转而执行catch
语句,finally
无论是否错处都会执行
用法:和JavaScript
并无区别
1 | try |
运算符
算术运算符
+
、-
、*
、\
、%
1 | sbyte s1 = 12; |
运算的优先级和数学基本运算一致,可通过括号改变优先级
复合运算符
+=
、-=
、*=
、%=
1 | int i = 3; |
++
、--
1 | int a = 1; |
1 | int b = 1; |
字符串拼接
拼接方式:
使用
+
进行拼接1
2
3string s= "12";
s += "34";
Console.WriteLine(s); // Output: 12341
2
3
4string s = "2";
s =1 + s + 3 + true;
Console.WriteLine(s); // 123True1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21string s = "123" ;
// 先计算算数表达式,再拼接字符串
s += 1 + 2 + 3 + 4 + 5;
Console.WriteLine(s); // 12315
string s1 = "1" ;
// 先计算算数表达式,再拼接字符串
s1 += "" + 2 + 3 + 4 + 5;
Console.WriteLine(s1); // 12345
string s2 = "12";
s2 += 1 + 2 + "" + 4 + 5;
Console.WriteLine(s2); // 12345
string s3 = "12";
s3 = s3 + (3 + 4);
Console.WriteLine(s3); //"127"固定语法
string.Format()
,使用替代符来占位1
2
3
4// 替代符从0开始
string s = string.Format("Hello {0}", "World");
Console.WriteLine(s);// Hello WorldConsole.WriteLine()
与string.Format()
写法相同(少参数报错)1
Console.WriteLine("Hello, My name is {0} , I am {1}", "John Doe", 12);// Output: Hello, My name is John Doe , I am 12
条件运算符
>
、<
、==
、!=
、<=
、>=
,返回一个bool
值
常用于数值的比较
1 | bool res = 5 > 3; |
条件运算符的优先级低于算术运算符
1
2
3
4 bool result;
// 先算3 + 2 = 5 再算 5 - 2 + 3 = 6 最后比较 5 > 6
result = 3 + 2 > 5 - 2 + 3;
Console.WriteLine(result); // False
string
、char
、bool
只能进行==
与!=
运算(char
可以和数值类比较)
1
2
3 char s = 'A';
int a = 66;
Console.WriteLine(a > s); // 66 > 65 True
逻辑运算符
与&&
、或||
、非!
1 | bool result; |
逻辑运算符中,
!
的运算优先级最高,&&
高于||
,即逻辑运算符优先级低于条件运算符,低于算符运算符
短路现象,满足条件后不再往后运算
1
2
3
4
5
6
7
8
9
10 bool result;
int a = 3;
// a> 0 为 true,因此不计算表达式的第二部分
result = a > 0 || ++a >= 3;
Console.WriteLine(a); // 3
// a < 0 为 false,因此不计算表达式的第二部分
result = a < 0 && ++a >= 3;
Console.WriteLine(a); // 3
移位运算符
运算符 | 符号 | 说明 |
---|---|---|
位于 | & |
全零则0 |
位或 | ` | ` |
抑或 | ^ |
不同则1,相同则0 |
取反 | ~ |
0->1 1->0(取反) |
左移 | << |
算数左移,相当于乘以2^num |
右移 | >> |
算数右移,相当于除以2^num |
1 | sbyte a = 1; // 0000 0001 |
1 | sbyte a = 1; // 0000 0001 |
1 | sbyte a = 1; // 0000 0001 |
1 | sbyte a = 1; // 0000 0001 |
数值类在计算机中存储格式为补码
1 | sbyte a = -2; // 1111 1110 |
三目运算符
常用于唯二取值,可以使代码简洁
语法:
1 | string str = false ? "条件为真":"条件为假"; |
1 | // 取两值的最大值 |
1 | // 判断是否是闰年 |
条件分支语句
if else语句
1 | string username = "admin"; |
一些练习题
要求用户输入两个数,如果两个数可以整除或者两个数加起大于100,则输出a的值,否则输出b的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16int a, b;
a = int.Parse(Console.ReadLine());
b = int.Parse(Console.ReadLine());
if (a % 100 == 0 && b % 100 == 0)
{
Console.WriteLine(a);
}
else if (a + b > 100)
{
Console.WriteLine(a);
}
else
{
Console.WriteLine(b);
}有三个整数,分别存储不同的值,请输出其中的最大值
1
2
3
4
5
6
7
8
9
10
11
12
13
14int a, b, c;
a = int.Parse(Console.ReadLine());
b = int.Parse(Console.ReadLine());
c = int.Parse(Console.ReadLine());
int temp = a > b ? a : b;
if (temp > c)
{
Console.WriteLine(temp);
}
else
{
Console.WriteLine(c);
}让用户输入一个字符,如果字符是0-9的一个,那么现实“您输入了一个数字”,否则显示“这不是一个数字”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15char input;
input = Console.ReadKey().KeyChar;
Console.WriteLine();
int inputNumber = input;
// 利用了隐式转化
if (inputNumber >= 48 && inputNumber <= 57)
{
Console.WriteLine("您输入了一个数字");
}
else
{
Console.WriteLine("You entered a character");
}提醒用户输入年龄,如果大于等于18,则告知用户可以查看,如果小于13岁,则告知不允许查看,如果大于等于13并且小于18,则提示用户是否继续观看(yes,no),如果输入yes则允许用户观看,否则显示退出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29Console.WriteLine("请输入你的年龄:");
int age = int.Parse(Console.ReadLine());
if (age >= 18)
{
Console.WriteLine("允许查看");
}
else if (age >= 13)
{
Console.WriteLine("是否继续查看?(yes/no)");
string answer = Console.ReadLine();
switch (answer)
{
case "yes":
Console.WriteLine("允许查看");
break;
case "no":
Console.WriteLine("不允许查看");
break;
default:
Console.WriteLine("输入错误");
break;
}
}
else
{
Console.WriteLine("不允许查看");
}输入一个整数,如果是偶数,打印
Your input is even
,否则打印Your input is odd
1
2
3
4
5
6
7
8
9
10
11Console.WriteLine("请输入一个整数:");
int num = Convert.ToInt32(Console.ReadLine());
if (num % 2 == 0)
{
Console.WriteLine("Your input is even");
}
else
{
Console.WriteLine("Your input is odd");
}
switch语句
用于同类但不同值显示不同信息,常常配合枚举类使用
1 | Console.WriteLine("请输入一个1-7的数字代表星期几:"); |
注意:
case后只能是值,且必须是常量,不能是变量
case后的值的类型要与switch括号内的相同
case匹配后可以写完整的语句
case可构成贯穿
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 Console.WriteLine("请输入一个1-7的数字代表星期几:");
int day;
try
{
day = int.Parse(Console.ReadLine());
}
catch
{
// 结束程序
Console.WriteLine("输入错误");
return;
}
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
Console.WriteLine("今天是星期{0}", day);
break;
// 所有条件都不满足
default:
Console.WriteLine("输入错误");
break;
}
一些练习:
小王带了10元买星巴克咖啡,三种型号选择
1-(中杯,5元)
2-(大杯,7元)
3-(超大杯,11元)
请用户输入选择的型号,如果钱够,则购买成功,并算出小王最后还剩多少钱,如果不够,则提示用户”钱不够,请选择其他型号”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48int money = 10;
Console.WriteLine("请选择购买的杯型:1.中杯 2.大杯 3.超大杯");
int choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
if (money < 10)
{
Console.WriteLine("钱不够,请选择其他型号");
break;
}
else
{
Console.WriteLine("购买中杯成功");
Console.WriteLine("还剩{0}", money - 10);
}
break;
case 2:
if (money < 11)
{
Console.WriteLine("钱不够,请选择其他型号");
break;
}
else
{
Console.WriteLine("购买大杯成功");
Console.WriteLine("还剩{0}", money - 11);
}
break;
case 3:
if (money < 12)
{
Console.WriteLine("钱不够,请选择其他型号");
break;
}
else
{
Console.WriteLine("购买超大杯成功");
Console.WriteLine("还剩{0}", money - 12);
}
break;
default:
Console.WriteLine("输入错误");
break;
}输入学生的考试成绩,如果
成绩≥90:A
90>成绩≥80:B
80>成绩≥70:C
70>成绩≥60:D
成绩<60:E
(使用switch语法完成)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44Console.WriteLine("请输入成绩:");
int score = int.Parse(Console.ReadLine());
char level;
if (score >= 90)
{
level = 'A';
}
else if (score >= 80)
{
level = 'B';
}
else if (score >= 70)
{
level = 'C';
}
else if (score >= 60)
{
level = 'D';
}
else
{
level = 'E';
}
switch (level)
{
case 'A':
Console.WriteLine("等级:A");
break;
case 'B':
Console.WriteLine("等级:B");
break;
case 'C':
Console.WriteLine("等级:C");
break;
case 'D':
Console.WriteLine("等级:D");
break;
case 'E':
Console.WriteLine("等级:E");
break;
}
循环语句
循环执行某些逻辑
while语句
用于不能明确何时结束重复的情况
1 | int index = 0; |
使用break
和continue
改变执行流
break
- 跳出循环continue
- 跳出当前循环,从头执行
1 | int index = 0; |
一些练习
定义一个整型变量sum,然后分别把1-100之间的数字依次累加到sum中,当sum的值大于500的时候,中断操作,并在控制台输出累加到第几个数字就可以使sum大于500
1
2
3
4
5
6
7
8
9
10int sum = 0;
int index = 0;
while (sum <= 500)
{
if (sum > 500) break;
sum += index++;
}
Console.WriteLine("index:{0},sum:{1}", index, sum); // index:33,sum:528找到1-100之间所有能被7整除之外的所有整数和
1
2
3
4
5
6
7
8
9
10
11
12
13int index = 1;
int sum = 0;
while (index <= 100)
{
if (index % 7 != 0)
{
Console.WriteLine("{0}不能被7整除",index);
sum += index;
}
index++;
}
Console.WriteLine(sum);判断用户输入的数字是否是素数(只能被自身和1整除的数)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22Console.WriteLine("请输入一个树:");
int input = int.Parse(Console.ReadLine());
// 判断一个数是否是素数
bool isPrime = true;
for (int i = 2; i < input; i++)
{
if (input % i == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
Console.WriteLine($"{input} 是素数");
}
else
{
Console.WriteLine($"{input} 不是素数");
}要求用户输入用户名和密码(admin/8888),直到输对为止
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24string username = "admin";
string password = "8888";
while (true)
{
Console.WriteLine("请输入用户名:");
string inputUserName = Console.ReadLine();
Console.WriteLine("请输入密 码:");
string inputPassword = Console.ReadLine();
if (inputPassword == password && inputUserName == username)
{
Console.WriteLine("登录成功");
break;
}
else if (inputUserName != username)
{
Console.WriteLine("用户名错误");
}
else
{
Console.WriteLine("密码错误");
}
}假设看视频的人数是100人,每个月增长20%,请问按照此速度增加,经历多少个月人数会超过1000人
1
2
3
4
5
6
7
8
9
10double user = 100;
int mouth = 0;
while (user <= 1000)
{
mouth++;
user *= 1.2;
}
Console.WriteLine("经过{0}个月,用户涨到{1}", mouth, (int)user);求数列1,1,2,3,5,8,13……的第20位数字是多少
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15int first = 1;
int second = 1;
int count = 0;
while (count < 19)
{
Console.WriteLine("first:{0},second:{1}", first, second);
int temp = first + second;
first = second;
second = temp;
count++;
}
Console.WriteLine(first); // 6765
do while语句
先执行一次循环语句中的语句,再判断是否继续
1 | int count = 10; |
练习: 不断提示输入你的姓名,直到输入q结束
1 | string name = Console.ReadLine(); |
for循环
一般用于明确重复次数的循环
1 | for (int i = 1; i <= 10; i++) |
一些练习
求1-100所有偶数的和
1
2
3
4
5
6
7
8
9
10
11int sum = 0;
for (int i = 1; i <= 100; i++)
{
if (i % 2 == 0)
{
sum += i;
}
}
Console.WriteLine(sum); // Output: 2550找出100-999之间的水仙花数
例如:153= 1 * 1 * 1+ 5 * 5 * 5 + 3 * 3 * 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17for (int i = 100; i < 1000; i++)
{
int j = i;
double tempCount = 0;
while (j > 10)
{
// 将数的每个部分拆开三次方
tempCount += Math.Pow(j % 10, 3);
j /= 10;
}
// 百位
tempCount += Math.Pow(j, 3);
if ((int)tempCount == i)
{
Console.WriteLine("{0}是水仙花数",i);
}
}1
2
3
4153是水仙花数
370是水仙花数
371是水仙花数
407是水仙花数打印9*9乘法表
1
2
3
4
5
6
7
8
91*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=811
2
3
4
5
6
7
8for (int i = 1; i < 10; i++)
{
for (int j = 1; j <= i; j++)
{
Console.Write("{0}*{1}={2} ", i, j, i * j);
}
Console.WriteLine();
}输出10*10空心方形阵
1
2
3
4
5
6
7
8
9
10**********
* *
* *
* *
* *
* *
* *
* *
* *
**********1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22for (int i = 0; i < 10; i++)
{
if (i == 0 || i == 9)
{
for (int j = 0; j < 10; j++)
{
Console.Write("*");
}
}
else
{
for (int j = 0; j < 10; j++)
{
if(j==0||j==9){
Console.Write("*");
}else {
Console.Write(" ");
}
}
}
Console.WriteLine();
}输出10*10的三角形方阵
1
2
3
4
5
6
7
8
9*
**
***
****
*****
******
*******
********
*********1
2
3
4
5
6
7
8for (int i = 0; i < 10; i++)
{
for (int j = 0; j < i; j++)
{
Console.Write("*");
}
Console.WriteLine();
}输出如下10行三角方阵
1
2
3
4
5
6
7
8
9
10*
***
*****
*******
*********
***********
*************
***************
*****************
*******************1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 19; j++)
{
if (j >= 10 - i && j <= 10 + i)
{
Console.Write("*");
}
else
{
Console.Write(" ");
}
}
if (i == 9) Console.Write("*");
Console.WriteLine();
}