C#是微软公司推出的一种语法简洁、类型安全的面向对象的编程语言,开发人员可以通过它编写在.NET Framework上运行的各种安全可靠的应用程序。
.NET 框架是一个多语言组件开发和执行环境,它提供了一个跨语言的统一编程环境。其中C#是该平台上使用的编程语言之一,类似的还有Visual Basic.NET、Python、j#、Visual C++.NET等。
开发环境一般使用Visual Studio2019或Rider Sharp等集成开发环境。
class Program {
static void Main(string[] args) {
Console.WriteLine("Hello World");
Console.ReadLine();
}
}
使用Rider有些烦人的功能:代码的检查问题和大括号换行的风格,这里记录改进过程:
代码检查:新版点击Rider右下角的铅笔来切换语法检查问题。
括号缩进:File -> Settings -> Code Style -> C# - > Braces Layout,将里面的选项改成:
At end of line(K&R style)
C# 语言是在 C、C++ 的基础上发展而来的,因此在语法形式上有些类似。
C# 语言的数据类型分为值类型和引用类型。
值类型包括整型、浮点型、字符型、布尔型、枚举型等;
引用类型包括类、接口、数组、委托、字符串等。
从内存存储空间的角度而言,值类型的值是存放到栈中的,引用类型首先会在栈中创建一个引用变量,然后在堆中创建对象本身,再把这个对象所在内存的首地址赋给引用变量。
整型
所谓整型就是存储整数的类型,按照存储值的范围不同,C# 语言将整型分成了 byte 类型、short 类型、int 类型、long 类型等,并分别定义了有符号数和无符号数。
有符号数可以表示负数,无符号数仅能表示正数。
类 型 | 取值范围 |
---|---|
sbyte | 有符号数,占用1个字节,-27〜27-1 |
byte | 无符号数,占用1个字节,0〜28-1 |
short | 有符号数,占用2个字节,-215〜215-1 |
ushort | 无符号数,占用2个字节,0〜216-1 |
int | 有符号数,占用4个字节,-231〜231-1 |
uint | 无符号数,占用4个字节,0〜232-1 |
long | 有符号数,占用8个字节,-263〜263-1 |
ulong | 无符号数,占用8个字节,0〜264-1 |
浮点型
浮点型是指小数类型,浮点型在 C# 语言中共有两种,一种称为单精度浮点型,一种称为双精度浮点型。
类 型 | 取值范围 |
---|---|
float | 单精度浮点型,占用4个字节,最多保留7位小数 |
double | 双精度浮点型,占用8个字节,最多保留16位小数 |
在 C# 语言中默认的浮点型是 double 类型。如果要使用单精度浮点型,需要在数值后 面加上 f 或 F 来表示:
123.45f、123.45F
字符型和字符串类型
字符只能存放一个字符,占用两个字节,使用char关键字表示。例如 'a'、'中' 等。
字符串长度不固定,使用string关键字表示。例如:例如 "abc"、"123" 等。
在 C# 语言中还有一些特殊的字符串,代表了不同的特殊作用(转义字符)。
转义字符 | 等价字符 |
---|---|
' | 单引号 |
" | 双引号 |
\ | 反斜杠 |
\0 | 空 |
\a | 警告(产生蜂鸣音) |
\b | 退格 |
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
布尔类型
在 C# 语言中,布尔类型使用 bool 来声明,它只有两个值,即 true 和 false。
布尔类型的值也被经常用到条件判断的语句中,比如三元运算符中使用布尔类型判断:
int result = a > b ? a : b;
C#中代码的注释和折叠分别如下所示:
代码的折叠
region 和 #endregion
代码如下所示:
#region
private void changeButtonStates(bool flag) {
......
}
#endregion
代码的注释
- 单行注释。 以 // 开始,到本行结束。
- 多行注释。 /*开始 */结束,之间的都为注释。
- 文档注释。用于对类和方法进行注释,在类或方法前面,连续输入3个///
代码如下所示:
///
/// 修改按钮的可用状态
///
///
#region
private void changeButtonStates(bool flag) {
// 这里是方法内部实现
......
}
#endregion
数据类型转换
C#常量数据类型只能是原始数据类型:int、bool、char、double、string等。
其中基本数据类型的转换如下表所示:
命令 | 结果 |
---|---|
Convert.ToBoolean(val) | var转换bool |
Convert.ToByte(val) | var转换byte |
Convert.ToChar(val) | var转换char |
Convert.ToDecimal(val) | var转换decimal |
Convert.ToDouble(val) | var转换double |
Convert.ToInt(val) | var转换short |
Convert.ToInt32(val) | var转换int |
Convert.ToInt64(val) | var转换long |
Convert.ToSByte(val) | var转换sbyte |
Convert.ToSingle(val) | var转换float |
Convert.ToString(val) | var转换string |
Convert.ToUnit13(val) | var转换ushort |
Convert.ToUnit32(val) | var转换unit |
Convert.ToUnit64(val) | var转换ulong |
示例代码如下所示:
class Program {
static void Main(string[] args) {
int i = 10;
Console.WriteLine("十进制转二进制:"+Convert.ToString(i, 2));
Console.WriteLine("十进制转八进制:"+Convert.ToString(i, 8));
Console.WriteLine("十进制转十六进制:"+Convert.ToString(i, 16));
Console.WriteLine("二进制转十进制:"+Convert.ToInt32("1010",2));
Console.WriteLine("八进制转十进制:"+Convert.ToInt32("10",8));
Console.WriteLine("十六进制转十进制:" + Convert.ToInt32("a",16));
Console.ReadKey(true);
}
}
(1)算数运算符
C#中算数运算符包含如下所示:
运算符 | 说 明 |
---|---|
+ | 对两个操作数做加法运算 |
- | 对两个操作数做减法运算 |
* | 对两个操作数做乘法运算 |
/ | 对两个操作数做除法运算 |
% | 对两个操作数做取余运算 |
算数运算符相关示例如下所示:
class Program {
static void Main(string[] args) {
Console.WriteLine("千位" + 1234 / 1000);
Console.WriteLine("百位" + 1234 / 100 % 10);
Console.WriteLine("十位" + 1234 / 10 % 10);
Console.WriteLine("个位" + 1234 % 10);
}
}
输出结果如下:
千位1
百位2
十位3
个位4
(2)赋值运算符
赋值运算符中最常见的是等号,除了等号以外还有很多赋值运算符,它们通常都是与其他运算符连用起到简化操作的作用。
运算符 | 说 明 |
---|---|
= | x=y,等号右边的值给等号左边的变量,即把变量 y 的值赋给变量 x |
+= | x+=y,等同于 x=x+y |
-= | x-=y,等同于 x=x-y |
*= | x=y,等同于 x=xy |
/= | x/=y,等同于 x=x/y |
%= | x%=y,等同于 x=x%y,表示求 x 除以 y 的余数 |
++ | x++ 或 ++x,等同于 x=x+1 |
-- | x-- 或 --x,等同于 x=x-1 |
赋值运算符相关示例如下所示:
class Program {
static void Main(string[] args) {
int i = 10;
i++;
i--;
i += 10;
Console.WriteLine(i);
}
}
(3)比较运算符
关系运算符用于实现对两个值的比较运算,关系运算符在完成对两个操作数的比较运算后会返回一个代表运算结果的布尔值。
运算符 | 说 明 |
---|---|
== | 表示两边表达式运算的结果相等,注意是两个等号 |
!= | 表示两边表达式运算的结果不相等 |
> | 表示左边表达式的值大于右边表达式的值 |
< | 表示左边表达式的值小于右边表达式的值 |
>= | 表示左边表达式的值大于等于右边表达式的值 |
<= | 表示左边表达式的值小于等于右边表达式的值 |
使用比较运算符运算的结果是布尔型的值,因此经常将使用比较运算符的表达式用到逻辑运算符的运算中。
class Program {
static void Main(string[] args) {
Console.WriteLine("10是否为偶数:" + ((10 % 2) == 0));
}
}
(4)逻辑运算符
逻辑运算符主要包括与、或、非等,它主要用于多个布尔型表达式之间的运算。
运算符 | 含义 | 说明 |
---|---|---|
&& | 逻辑与 | 如果运算符两边都为 True,则整个表达式为 True,否则为 False;如果左边操作数为 False,则不对右边表达式进行计算,相当于“且”的含义 |
|| | 逻辑或 | 如果运算符两边有一个或两个为 True,整个表达式为 True,否则为 False;如果左边为 True,则不对右边表达式进行计算,相当于“或”的含义 |
! | 逻辑非 | 表示和原来的逻辑相反的逻辑 |
在使用逻辑运算符时需要注意逻辑运算符两边的表达式返回的结果都必须是布尔型的。
class Program {
static void Main(string[] args) {
Console.WriteLine("2021年是否是闰年:" + ((2021 % 4 == 0) && (2021 / 100 != 0) || (2021 % 400 == 0)));
}
}
(5)位运算符
所谓的位运算,通常是指将数值型的值从十进制转换成二进制后的运算,由于是对二进制数进行运算,所以使用位运算符对操作数进行运算的速度稍快。
位运算包括与、或、 非、左移、右移等,具体的表示符号如下表所示。
运算符 | 说 明 |
---|---|
& | 按位与。两个运算数都为 1,则整个表达式为 1,否则为 0;也可以对布尔型的值进行比较,相当于“与”运算,但不是短路运算 |
| | 按位或。两个运算数都为 0,则整个表达式为 0,否则为 1;也可以对布尔型的值进行比较,相当于“或”运算,但不是短路运算 |
~ | 按位非。当被运算的值为 1 时,运算结果为 0;当被运算的值为 0 时,运算结果为 1。该操作符不能用于布尔型。对正整数取反,则在原来的数上加 1,然后取负数;对负整数取反,则在原来的数上加 1,然后取绝对值 |
^ | 按位异或。只有运算的两位不同结果才为 1,否则为 0 |
<< | 左移。把运算符左边的操作数向左移动运算符右边指定的位数,右边因移动空出的部分 补 0 |
>> | 有符号右移。把运算符左边的操作数向右移动运算符右边指定的位数。如果是正值,左侧因移动空出的部分补 0;如果是负值,左侧因移动空出的部分补 1 |
>>> | 无符号右移。和 >> 的移动方式一样,只是不管正负,因移动空出的部分都补 0 |
在上面列出的运算符中比较常用的是左移运算符和右移运算符。
class Program {
static void Main(string[] args) {
// 使用位运算符计算 2 的立方
Console.WriteLine("2的立方为:" + (2 <<2));
}
}
(6)三元运算符
三元运算符也被称为条件运算符,与后面要学习的 if 条件语句非常类似。
布尔表达式 ? 表达式 1: 表达式 2
其中:
- 布尔表达式:判断条件,它是一个结果为布尔型值的表达式。
- 表达式 1:如果布尔表达式的值为 True,该三元运算符得到的结果就是表达式 1 的运算结果。
- 表达式 2:如果布尔表达式的值为 False,该三元运算符得到的结果就是表达式 2 的运算结果。
需要注意的是,在三元运算符中表达式 1 和表达式 2 的结果的数据类型要兼容。
class Program {
static void Main(string[] args) {
Console.WriteLine("10为:" + (10 % 2 == 0 ? "偶数" : "奇数"));
}
}
运算符的优先级不用太在意,一般开发中都会使用括号的方式来改变运算顺序。
变量和常量是相对的:变量是指所存放的值是允许改变的,而常量表示存入的值不允许改变。
数据类型 变量名;
变量的使用示例如下所示:
class Program {
static void Main(string[] args) {
int num = 100;
double num1 = 100.123;
bool isFlag = true;
String name = "Hello";
Console.WriteLine("num1:" + num1);
Console.WriteLine("num:" + num);
Console.WriteLine("isFlag:" + isFlag);
Console.WriteLine("name:" + name);
}
}
变量命名方法有两种,一种是 Pascal 命名法(帕斯卡命名法),另一种是 Camel 命名法(驼峰命名法)。
常量在第一次被赋值后值就不能再改变。定义常量需要使用关键字 const
来完成。
const 数据类型 常量名 = 值;
分别求圆的面积和周长,并使用常量存放 π 的值,将 π 的值定义为3.14。
class Program {
static void Main(string[] args) {
const double PI = 3.14;
int r = 3;
Console.WriteLine("圆的周长是:" + 2 * PI * r);
Console.WriteLine("圆的面积是:" + PI * r * r);
}
}
注意:常量在开发中一般都使用大写的方式,例如PI、FLAG等。
if else 语句是最常用的条件语句,并且 if else 语句的形式有多种:
if (){xxx}
if(){xxx}else{xxx}
if(){xxx} else if(){xxx}else{xxx}
示例代码如下所示:
class Program {
static void Main(string[] args) {
Console.WriteLine("请输入一个整数:");
int num = int.Parse(Console.ReadLine());
if (num % 2 == 0) {
Console.WriteLine(num + "是偶数");
} else {
Console.WriteLine(num + "是奇数");
}
}
}
还有一种if(){xxx} else if(){xxx}else{xxx}的结构代码如下:
class Program {
static void Main(string[] args) {
Console.WriteLine("请输入一个整数:");
int num = int.Parse(Console.ReadLine());
if (num == 1) {
Console.WriteLine(num + "是1");
}else if(num == 2) {
Console.WriteLine(num + "是2");
}
else {
Console.WriteLine(num + "未知");
}
}
}
流程语句不但可以多次判断,还可以进行嵌套使用。
switch case 语句也是条件语句的一种,在判断条件的选择上会有一些局限性。
switch(表达式) {
case 值 1:
语句块 1;
break;
case 值 2:
语句块 2;
break;
...
default:
语句块 n;
break;
}
其中case代表条件的分支,而default是默认的可以省略。
示例代码如下所示:
class Program {
static void Main(string[] args) {
Console.WriteLine("请输入学生考试的成绩(0~100的整数)");
int points = int.Parse(Console.ReadLine());
switch (points / 10) {
case 10:
Console.WriteLine("优秀");
break;
case 9:
Console.WriteLine("优秀");
break;
case 8:
Console.WriteLine("良好");
break;
case 7:
Console.WriteLine("及格");
break;
case 6:
Console.WriteLine("及格");
break;
default:
Console.WriteLine("不及格");
break;
}
}
}
循环语句和条件语句一样都是每个程序中必不可少的,循环语句是用来完成一些重复的工作的,以减少编写代码的工作量。
for 循环是最常用的循环语句,语法形式非常简单,多用于固定次数的循环。
for(表达式 1; 表达式 2; 表达式3){
表达式 4;
}
其中表达式的解析如下:
- 表达式 1:为循环变量赋初值。
- 表达式 2:为循环设置循环条件,通常是布尔表达式。
- 表达式 3:用于改变循环变量的大小。
- 表达式 4:当满足循环条件时执行该表达式 4
使用循环输出 1~10 的数,并输出这 10 个数的和。
class Program {
static void Main(string[] args) {
int sum = 0;
for (int i = 0; i <= 10; i++) {
sum += i;
}
Console.WriteLine("1~10的和是:" + sum);
}
}
使用嵌套for循环打印九九乘法表:
class Program {
static void Main(string[] args) {
for(int i = 1; i <10; i++) {
for(int j = 1; j <= i; j++) {
Console.Write(i + "x" + j + "=" + i*j + "\t");
}
Console.WriteLine();
}
}
}
while循环
while 循环与 for 循环类似,但是 while 循环一般适用于不固定次数的循环。
while(布尔表达式){
语句块;
}
hile 语句执行的过程是,当 while 中布尔表达式的结果为 True 时,执行语句块中的内容,否则不执行。
使用 while 循环输出 1~10 的数并输出 1~10 的和。
class Program {
static void Main(string[] args) {
int i = 1;
int sum = 0;
while (i <= 10) {
sum = sum + i;
i++;
}
Console.WriteLine("1~10的和为:" + sum);
}
}
do...while循环
do while 循环是先执行一次,再进行循环,也就是至少会执行一次。
do {
语句块;
}while(布尔表达式);
do while 语句执行的过程是,先执行 do{} 中语句块的内容,再判断 while() 中布尔表达式的值。
使用 do while 循环输出 1~10 的数。
class Program {
static void Main(string[] args) {
int i = 1;
do {
Console.WriteLine(i);
i++;
} while (i <= 10);
}
}
C#提供break、continue、goto等关键字用来中断循环的操作。
break
break 语句用于中断循环,使循环不再执行。如果是多个循环语句嵌套使用,则 break 语句跳出的则是最内层循环。
使用 for 循环输出 1~10 的数,当输出到 4 时结束循环。
class Program {
static void Main(string[] args) {
for (int i = 0; i <= 10; i++) {
if (i == 4){
break;
}
Console.WriteLine(i);
}
}
}
continue
continue 语句不是强制终止,continue 会跳过当前循环中的代码,强制开始下一次循环。
在 for 循环中当值迭代到 4 时使用 continue 结束本次迭代,继续下一次迭代,代码如下。
class Program {
static void Main(string[] args) {
for (int i = 0; i <= 10; i++) {
if (i == 4) {
continue;
}
Console.WriteLine(i);
}
}
}
goto
goto 语句用于直接在一个程序中转到程序中的标签指定的位置,标签实际上由标识符加上冒号构成。
如果要跳转到某一个标签指定的位置,直接使用 goto 加标签名即可。
class Program {
static void Main(string[] args) {
int x = 10;
Console.WriteLine("x = {0}", x);
if (x == 10) {
x = 20;
goto A;
}
x = x + 1;
for (int i = 0; i <5; i++) {
Console.WriteLine(i);
}
A:Console.WriteLine("x = {0}", x);
}
}
由于goto语句直接跳转到A处,所以中间的循环没有执行,输出结果如下:
x = 10
x = 20