关键字:C#的关键字全部大写

注释:跟C++ / Java 风格一致,///是文档注释,只能写在类、方法、属性的前面。不能用来注释单个变量。


C#语言也是严格区分大小写的



C#中的常量:

常量,顾名思义,就是“不会改变的量”。

我们平时书写的数字(比如12.85)、字符(比如'F')、字符串(比如"谢谢"),它们都属于“字面常量”。

有一些常量既重要又容易出错,比如圆周率π的值为3.1415926......,所以,我们常常会使用自定义常量。请看下面的代码:

  static void Main(string[] args)
        {
            const double PI = 3.1415926;                        //自定义常量PI
            Console.Write("半径为4的圆的周长为:");      //字符串常量
            Console.WriteLine(PI * 4 * 2);                        //使用自定义常量PI
            Console.Write("半径为4的圆的面积为:");      //字符串常量
            Console.WriteLine(PI * 4 * 4);                        //使用自定义常量PI
        }

需要解释2个关键字: const 关键字,表明PI是一个常量; double 关键字,表明PI的类型为“双精度浮点型”(一种精度很高的数字类型)。

你会发现,这段代码中使用了2次圆周率(周长、面积),但是因为使用自定义常量,所以字面常量3.1415926只书写了一次。这样做避免了重复书写导致的错误。

还有一点要特别注意:常量在声明时赋值,之后是不能修改的




C#的变量

上一节我们学习了常量,但编程中使用最多的是变量,这一节我们学习变量。

变量能够存储数据,并且与常量不同,变量存储的数据可以修改。比如今年18岁,明年可以变成19岁。

使用变量分为3步:声明、赋值、使用

声明变量的语法:数据类型 变量名;

给变量赋值的语法:变量名=值;

请阅读下面的代码:

        static void Main(string[] args )
        {
            int age;                //声明一个类型为int的变量age
            age = 18;             //给变量age赋值为18
            Console.WriteLine("我今年" + age+"岁"); //使用变量age
            age = 19;             //修改age变量的值
            Console.WriteLine("我今年" + age+"岁"); //使用变量age
        }

变量的声明和赋值可以同时完成(合在一起,也叫初始化)




C#的数据类型

我们知道声明变量需要写出数据类型,我们今天要学习的是最常用的几种类型。
字符类型 char ,存储用 '' (单引号)括起来的一个字符,例如:

char sex='男';//存储性别

字符串类型 string ,存储用“”(双引号)括起来的一串字符,例如:

string address="北京市宣武区牛街北口";//存储地址

整数类型 int ,存储整数,例如:

int age=23;//存储年龄

双精度浮点型 double ,存储小数,例如:

double salary=7991.63;//存储工资

以上四种是最常用的数据类型,其他常用类型,我们会随着课程深入慢慢介绍。

需要注意的是,某种类型的变量,只能存储这种类型的数据,否则,可能会出错。



C#的类型转换

上一节我们学习了4种数据类型,也提到每种类型的变量只能存这种类型的数据。可是,有时候真的需要把不同类型的值放在一起运算,比如这种:3.5+8 这时候怎么办呢?有下面2种情况:

自动类型转换:2种不同类型的数据运算,低精度类型会自动转换为较高精度的类型。
以3.5+8为例,显然数字8的精度较低(int),而3.5的精度较高(double),所以,8会自动转换为double型,即转换为3.5+8.0进行运算,结果为11.5。

请看这个例子:double d=2; 2的精度显然低于变量d的精度,所以2会自动转换为2.0然后赋值给d。
再看这个例子:int i=3.0;变量i的精度低于3.0,但是由于i已经声明为int型的变量,变量的值可以变,但变量的类型可不能变来变去的,所以这条命令会出错的。

强制类型转换:无法自动转换为我们需要的类型,可以用强制类型转换,比如上例可以这样完成:

int i=(int)3.0;

数字前面的(int)表示转换的目标类型为int,3.0会被强制转换为3。
需要注意, double 型强制转换为int型将失去小数部分,比如(int)2.8,我们得到的将是2。





C#标识符的命名规则

程序中的变量名、常量名、类名、方法名,都叫做标识符。C#有一套标识符的命名规则,如果命名时不遵守规则,就会出错。这套规则简单说有下面三条:

①标识符只能由英文字母、数字和下划线组成,不能包含空格和其他字符。

错误的标识符声明:string $user; //错在使用了其他字符

②变量名不能用数字开头。

错误的标识符声明:double 6h;//错在用数字开头

③不能用关键字当变量名。

错误的标识符声明:char static ;//错在用关键字static做变量名





C#的算术运算符(一)

计算机程序,当然少不了“计算”,要计算就必须了解运算符。今天,我们先学习算术运算符中的加、减、乘、除。

加:+ 。加号有2个用途:当用加号连接两个数字时,会计算出这两个数字的和。比如:

Console.WriteLine(9+2.2);//输出11.2

另一种情况,当加号两边包含字符串的时候,会把两边的表达式连接成新的字符串。比如:

Console.WriteLine(9+"2.2");//输出92.2,因为"2.2"是字符串,所以9也被转换为"9",+起的作用是连接字符串

减:- 。减号的作用就是减法。比如:

Console.WriteLine(15-23);//输出-8

乘:* 。乘号的作用是求2数的乘积。比如:

Console.WriteLine(0.8*3);//输出2.4

除:/ 。除号的作用是求2数相除的商。比如:

Console.WriteLine(2/0.5);//输出4.0

但是,2个整数相除,结果仅保留整数部分,小数部分会被舍去。

Console.WriteLine(5/10);//输出0




C#的算术运算符(二)

这一节我们学习取余运算符

C#中的取余运算符就是%。上一节学习的除号,作用是求2个数字相除的商,而取余运算符%的作用是求两个数字相除的余数。比如:

Console.WriteLine(19/5);//求19除以5的商,输出3Console.WriteLine(19%5);//求19除以5的余数,输出4(商3余4)

编程中,%常常用来检查一个数字是否能被另一个数字整除。比如下面的代码片段:

int number = 29;
Console.WriteLine(number%2);//求number除以2的余数

如果输出0,表示没有余数,即number能够被2整除(是偶数);如果输出1,表示有余数,即number不能被2整除(是奇数)。



C#的算术运算符(三)

这一节学习两个特别的运算符++--

++,叫做自加运算符。比如你今年18岁,明年长了一岁,用代码写出来是这样:

int age=18;//今年18岁
age=age+1;//明年,在今年的年龄上加1岁

也可以写成这样:

int age=18;//今年18岁
age++;//明年,在今年的年龄上加1岁

age++;age=age+1;作用相同,都是变量的值+1

--,叫做自减运算符。同理,你今年18岁,用了XX护肤水以后,明年变成17岁了,可以这样写:

int age=18;//今年18岁
age--;//等同于 age=age-1;

另外,age++;age--;也可以写作++age;--age;

但请注意:如果与其他运算在同一语句中,++写在变量前面或后面,算法不一样,请看下例

Console.WriteLine(age++);作用等同于下面两句:

Console.WriteLine(age);//先打印a
ge=age+1;//后自加

Console.WriteLine(++age);作用等同于下面两句:

age=age+1;//先自加
Console.WriteLine(age);//后打印

你看,运算顺序不一样吧,所以输出的结果也不会相同。





C#的比较运算符

比较数字大小,或者比较数字相等的运算符是比较运算符。C#中的比较运算符有:

【C#学习笔记】基础_C#

注意:表示两个值相等的“等于”是由2个“=”组成的。

比较运算的结果,都是布尔类型( bool ,bool类型我们是第一次提到,它表示逻辑上的真(成立)假(不成立)。真与假用关键字 true 和 false 表示。

【C#学习笔记】基础_C#_02

上面程序中, x>=y 不成立会返回 false , x<=y 成立,会返回 true 。运行结果:

【C#学习笔记】基础_C#_03




C#的逻辑运算符(一)

逻辑运算符用来连接多个 bool 类型表达式,实现多个条件的复合判断。C#中的逻辑运算符包括:逻辑非( ! )、逻辑与( && )、逻辑或( || )

逻辑非用来对某一个 bool 类型表达式取反,即“真变假”或“假变真”。请看下面的代码:

Console.WriteLine(1 > 0);//条件表达式为true,输出TrueConsole.WriteLine(!(1 > 0));//用逻辑非对条件表达式取反,输出False

逻辑与用来判断 2 个 bool 类型表达式是否同时为 true 。请看下面的代码:

int x = 5, y = 2;//同时声明2个int型变量并赋值Console.WriteLine(x>3 && y>3);//判断x>3和y>3是否同时为true,由于y>3为false,所以整个表达式为false

只有当&&两边的表达式均为 true 时,整个表达式才为 true ;若任意一个表达式为 false ,整个表达式即为 false 

逻辑或用来判断2个 bool 类型表达式中是否有一个为 true 。请看下面的代码:

int x = 5, y = 2;//同时声明2个int型变量并赋值Console.WriteLine(x>3 || y>3);//判断x>3和y>3是否有一个为true,由于x>3为true,所以整个表达式为true

只要||两边的表达式有一个为 true ,整个表达式即为 true ;若两边的表达式均为 false ,整个表达式为 false 

对比一下,就是说: && 运算符,两边同真才算真,一边为假就算假; || 运算符,一边为真即为真,两边同假才是假。




C#的逻辑运算符(二)

作为对上一节学习的巩固,这一节我们通过几个示例熟悉逻辑运算符的应用。第一个示例是关于逻辑与,比如小张想结婚,未来丈母娘开出的条件是:存款必须过10万,必须有房子,这两条少一条都不行。既然2个条件都是“必须”做到,那就需要同时满足,适合用逻辑与连接:

【C#学习笔记】基础_C#_04

运行结果为:False

下一个示例是关于逻辑或,比如丽丽选择男朋友的标准,要么是“工程师”,要么是“运动员”,二者居其一即可:

【C#学习笔记】基础_C#_05

运行结果为:True



C#的赋值运算符

前面,我们已经学过一个赋值运算符“=”,这次我们学习一下其他的赋值运算符:

赋值“+=”:先加后赋值。请看下面的例子:

int x=5;
x += 2;//这句等同于x=x+2;执行后,x的值为7

赋值“-=”:先减后赋值。请看下面的例子:

int x=5;
x -= 2;//这句等同于x=x-2;执行后,x的值为3

赋值“*=”:先乘后赋值。请看下面的例子:

int x=5;
x *= 2;//这句等同于x=x*2;执行后,x的值为10

赋值“/=”:先除后赋值。请看下面的例子:

int x=5;
x /= 2;//这句等同于x=x/2;执行后,x的值为2

取余赋值“%=”:先取余后赋值。请看下面的例子:

int x=5;
x %= 2;//这句等同于x=x%2;执行后,x的值为1

与其他运算符从左向右计算不同,赋值运算符从右向左计算。




C#的运算符优先级

前面我们学习了那么多运算符,如果编程中同时使用了多个运算符,到底哪一个会先运算呢?这就是优先级的问题。C#运算符的优先级请参考下面的顺序:

括号。学数学的时候我们就知道,要先计算括号里面的内容。C#语言也是一样,如果有多层括号,要从里向外计算。括号优先级最高。

一元运算符。有些运算符两边有2个操作数,比如2+3、6%5等等,这些叫做二元运算符。只有一个操作数的叫做一元运算符,它们的优先级高于二元运算符。一元运算符包括:++(自加) 、 --(自减) 、 !(逻辑非)

*(乘)、/(除)、%(取余)

+(加)、-(减)

>(大于)、<(小于)、>=(大于等于)、<=(小于等于)

==(等于)、!=(不等于)

&&(逻辑与)

||(逻辑或)

赋值运算符。包括:=、+=、-=、*=、/=、%=。

另外,还需要注意一点:优先级相同的运算符从左向右计算(赋值运算符相反)

请看下面这段代码:

bool b = 20 - (15 - 8) * 2 > 10 && (2 % 2 * 2 + 2) > 2;
Console.WriteLine(b);

分析:首先计算优先级最高的括号,(15-8)得到7,(2%2*2+2)则需要先计算%和*,后算+,结果是2,表达式就变成了:

bool b=20-7*2>10&&2>2;

接下来优先级最高的是7*2,然后是减法,变成:

bool b=6>10&&2>2;

继续计算两个大于号,得到:

bool b=false&&false;

最后的结果当然是false:

【C#学习笔记】基础_C#_06



C#用流程图描述程序逻辑

流程图是程序步骤的图形化表示方法。流程图中包括如下符号:

【C#学习笔记】基础_C#_07

以上图形中,流程线用来连接相邻的两个步骤;每一个程序都有且仅有一个开始结束

以下流程图描述的是,求2个浮点数的和,后边是用C#实现:

【C#学习笔记】基础_C#_08【C#学习笔记】基础_C#_09




C#中判断和分支

走到岔路口,需要选择方向。编写程序也会遇到判断和分支。请看下面的流程图,判断手机账户余额是否不足10元,如果不足给出提示:

【C#学习笔记】基础_C#_10

这个程序在“balance<10”这个步骤出现了分支,“balance<10”被称为判断( bool 类型),当判断为 true 时,执行左边的分支,输出提示;当判断为 false 时,执行右边的分支,不输出任何内容。

在C#中,这个结构成为条件结构,通常用 if 关键字来实现:

【C#学习笔记】基础_C#_11

当 if 右边的判断为 true 的时候,会执行分支一;如果判断为 false ,则不会执行分支一




C#中if...else条件结构

前一节我们学习了 if 条件结构。条件结构可以有2个分支,比如下面的流程图,判断一个整数是奇数还是偶数:

【C#学习笔记】基础_C#_12

这个流程图从C#实现如下,其中,条件为 true 时执行的分支写在 if() 后面的{}中;条件为 false 时执行的分支写在 else 后面的{}中。

【C#学习笔记】基础_C#_13

这个由 if 和 else 组成的结构是条件结构的一种,它的基本逻辑是:当条件为 true 时,执行分支1,否则,执行分支2。这段程序中,变量num能够被2整除时会执行分支1,不能被2整除时执行分支2。程序的运行结果是:

【C#学习笔记】基础_C#_14

每一个 if...else 结构都包含 1 个条件和 2 个分支,而程序会根据条件的真与假,选择执行其中的某一个分支。条件必须为 bool 类型的表达式。


C#中嵌套的if结构

程序开发中,往往需要先判断一个条件是否成立,再判断另一个条件。比如下面的例子:验证账号是否为“admin”,如果不是则提示错误;如果是,则验证密码是否为“bj2022”:

【C#学习笔记】基础_C#_15

用C#实现如下:
【C#学习笔记】基础_C#_16

外层的if (userName == "admin") 会被首先判断,如果为 false ,就会输出“用户名错误!”;如果为 true ,再判断内层的if (password == "bj2022")




C#中多重if结构

如果,有多个条件,其中只有一个成立,应该怎样判断呢?比如小明考试,90分以上奖励一台手机,80-89分奖励一个滑板,60-79分奖励一个烧饼,60以下没有奖励,0-100的分数被划分为4档,需要做3次条件判断。如果用上一节学习的嵌套if结构完成,3层if的嵌套会使程序变得很复杂。本节我们使用多重 if 结构实现,它的基本语法为:

【C#学习笔记】基础_C#_17

程序运行时,将从上到下依次判断条件,若某个条件为 true ,则执行对应的分支,并且停止后面条件的判断。比如下面的代码,将输出“奖励一个烧饼”:

【C#学习笔记】基础_C#_18



C#中else与if的匹配

if...else 条件结构中,如果某个分支只包含一条命令,那么是可以省略大括号{}的。比如上一节的练习,可以简化为:

【C#学习笔记】基础_C#_19

请注意,如果分支中包含2条以上的命令,是不能省略{}的。

如果 if 和 else 比较多,又省略了{},怎么判断那一个 if 和哪一个 else 是一对呢?请看下面的代码:

【C#学习笔记】基础_C#_20

当出现多个 if 和 else ,又没有{}来界定范围时,请参考下面2条原则:

每一个 else 与前面离它最近的 if 配对。按照这个原则,上面示例代码的两个 else 都与第二个 if 配对,这显然是不可能的,于是又有了第二个原则。

多个 else 都与同一个 if 相近时,最内层的 else 优先配对。这样,第一个 else 处于内层,就与第二个 if 优先配对,第二个 else 只能与第一个 if 配对。上面的示例代码会输出“C”。

根据这两个原则,上面的代码等同于如下的规范代码:

【C#学习笔记】基础_C#_21

编写条件结构时,尽可能加上 {} 可以省掉不必要的错误和麻烦



C#的条件运算符

C#提供了一种条件运算符,能够代替简单的 if...else 结构。这种条件运算符的语法如下:

条件表达式 ? 分支1 : 分支2

?: 就是条件运算符,可以看到它有3个操作数,所以又被称为三元运算符。它的运算逻辑是:当条件表达式为 true 时,执行分支1;当条件表达式为 false 时,执行分支2。

下面的例子中,根据年龄的大小,输出“成年人”或“未成年人”:

【C#学习笔记】基础_C#_22

因为age=17,所以条件表达式age>=18的值为 false ,返回“未成年人”。



C#的switch结构

if...else 之外,C#中还有一种 switch 条件结构,可以用来对变量进行多个分支的等值判断。语法如下:

【C#学习笔记】基础_C#_23

(变量)与每一个 case 后面的常量进行等值比较,如果相等,就执行对应的分支。执行分支以后, break 关键字会使 switch 结构中止,不会再判断后面的常量。如果变量与所有的常量都不相同,则执行 default 后面的分支。

下面的代码,根据运算符完成了四则运算中的一项:

【C#学习笔记】基础_C#_24

上面的代码,因为变量oper的值与 case '*' 匹配,所以会输出乘积“18”。

switch 中的(变量)只能是3种类型:整型(如 int )、字符型( char )、字符串类型( string )。




C#循环流程图和while循环

 程序连续的重复一个步骤称为“循环”。循环可以简化我们的代码,减少冗余。例如,打印 1-10 的整数,我们可以写 10 条打印语句,也可以这样:

【C#学习笔记】基础_C#_25

这个循环结构,会首先判断 x<=10 ,条件为真时执行循环体(“输出x”和“x++”),之后,再次判断条件 x<=10 ,若条件为真则继续执行循环体......若条件为假,则结束循环。

简单的说,循环是由循环体(需要重复执行的命令)和循环条件组成的。运行时,先判断循环条件,若条件为 true ,就执行循环体一次,然后再判断条件...当条件为 false 时,结束循环。上面的流程图,当变量 x 累加到 11 时,循环条件为 false ,循环就会结束。

C#中,可以用 while 循环结构来实现:

【C#学习笔记】基础_C#_26

对比代码和流程图可知, while 循环结构中,循环条件写在 () 中,循环体写在 {} 中。运行结果:

【C#学习笔记】基础_C#_27




C#算法——求和

这一节,我们学习用循环累加的方式求和。

上一节,我们曾经循环打印过 1-10 的整数,如果声明一个变量,在打印的过程中,把每一个数字都累加到变量里面,就可以得到 1-10 的和。求和算法的基本步骤

①声明变量 sum 用来存储“和”。 sum 的初始值赋为 0 。

②循环,用变量 x 访问每一个数字,用 sum+=x 的方式累加。(即 sum=sum+x; )

③循环结束后, sum 中存储的即是和。

【C#学习笔记】基础_C#_28

运行结果如下:

【C#学习笔记】基础_C#_29



C#中for循环

前面已经学习了 while 循环,C#中还有一种非常有用的 for 循环,特别适合于“已知循环次数”的循环。
比如,循环打印3次“我能行!”,用 while 循环可以这样写:

【C#学习笔记】基础_C#_30

而用 for 循环这样写:

【C#学习笔记】基础_C#_31

可以看出来, while 循环有的变量声明、循环条件、变量自加, for 循环一个也不缺,但是 for 循环把这些跟循环次数有关的元素都放在 ( ; ; ) 中,使得{}中的循环体更加纯粹,程序结构更加清晰。

*  for 循环 ( ; ; ) 中的两个分号是不能缺少的。

for 循环运行时,首先进行变量声明和赋值;接下来判断循环条件,若条件为 true ,则执行循环体一次,若条件为 false ,则结束循环;执行循环体后,进行变量自加。然后会进入下一次循环

【C#学习笔记】基础_C#_32



C#中do…while循环

C#中, do...while 循环也是一种常用的循环结构。循环结构各部分运行顺序如下:

【C#学习笔记】基础_C#_33

从上面的示意可以看出, do...while 循环第一次执行循环体是没有经过条件判断的,也就是说会无条件的执行一次循环体,此后的逻辑

顺序就与while循环相同了——先判断条件,条件为true再执行循环体一次。请看下面的例子:

【C#学习笔记】基础_C#_34

尽管循环条件始终为 false ,但由于 do...while 循环第一次执行循环体不判断条件,所以循环体还是执行了一次。运行结果为:

【C#学习笔记】基础_C#_35

我们已经学习了C#中最常用的三种循环结构,下面我们小小总结一下:

【C#学习笔记】基础_C#_36



C#循环结构之continue

循环中可以应用 continue 关键字中止一次循环,直接进入下一次。请看下面的例子:

【C#学习笔记】基础_C#_37

当程序执行到到 continue的时候,会立即停止本次循环体,直接进入下一次循环。所以,第三行输出比其他行少一些:

【C#学习笔记】基础_C#_38

所以,可以使用 continue 关键字,在循环中剔除一些特殊的数据。



C#循环结构之break

前面学习 switch 结构时,我们曾经遇到过 break 关键字, break 在 switch 结构的作用是“跳出 switch 结构”。
break 关键字还可以用在循环中,作用是“结束循环”。下面的循环代码中,当 x==3 的时候会执行 break 

【C#学习笔记】基础_C#_39

运行结果:

【C#学习笔记】基础_C#_40

对比代码和运行结果可知,当执行到 break ,循环结束(尽管此时循环条件仍然为 true )。

利用 break 关键字和 true 关键字,我们可以用另一种方式编写循环,下面的代码是输出1-5的整数:

【C#学习笔记】基础_C#_41

运行结果:

【C#学习笔记】基础_C#_42



C#循环结构之嵌套循环

在一个循环体中包含另一个循环,称为“嵌套循环”。当2个循环嵌套的时候,外层循环体执行一次,内层循环体执行 n 次( n 是内层循环的次数)。请看下面的例子:

【C#学习笔记】基础_C#_43

运行结果:

【C#学习笔记】基础_C#_44

比较代码和运行结果,我们发现,内层循环体执行 3 次,外层循环体执行 1 次。这就有点像钟表上的时针和分针——时针走一格,分针走一圈。

下面一段代码打印了一个矩形:

【C#学习笔记】基础_C#_45

运行效果:

【C#学习笔记】基础_C#_46

思考一下,哪一个变量决定了每一行的循环次数, x 还是 y ?




C#的声明数组和赋值

编程中有这样一种情形:我们需要存储多个同类型数据。比如,保存 1600 个学生的年龄。是否需要声明 1600 个 int 类型的变量?过了一年,学生们长了 1 岁,是否需要给每个变量重新赋值?这件事情,想想就怕怕。好在C#中有一种数组,专门存储一组相同类型的数据。数组的声明和初始化语法如下:

数据类型[ ] 数组名 = new 数据类型[长度]; 

注意:数组名像变量名一样要遵循标识符的命名规则;长度必须是整数

下面我们来比较变量和数组的声明与初始化,右边是在内存中为变量和数组分配空间的示意:

【C#学习笔记】基础_C#_47

对比变量 x 和数组 y 就会发现,数组 y 中其实包含了 3 个 double 类型的变量,为什么是 3 个?因为初始化数组时在 [ ] 中声明的长度为 3 。既然都在数组 y 中,所以 3 个变量(应该叫数组元素)的名字都叫 y ,为了区分它们,按照顺序给它们加上索引 [0]、[1]、[2] 。请注意:数组的索引从 0 开始递增。那么,数组 y 中 3 个元素的名字就变成了 y[0]、y[1]、y[2] 。最后再注意一点:数组经过初始化以后,数组元素有默认的初始值, double 类型为 0.0 , int 类型为 0 , char 类型为 'a' , bool 类型为 false , string 类型为 null 

数组元素的赋值与普通变量相同。下面的示例中,我们声明了一个长度为 3 的 string 类型数组,逐个赋值,然后打印:

【C#学习笔记】基础_C#_48

上例中,需要注意的是元素的索引,数组元素索引从 0 开始递增,所以长度为 3 的数组,其元素索引为 [0]、[1]、[2] 。

如何知道一个数组的长度呢? 数组.Length 属性会返回数组的长度(即数组元素的个数)。请看下面的例子:

【C#学习笔记】基础_C#_49

代码中的 friends.Length 会返回 friends 数组的长度,请看运行结果:

【C#学习笔记】基础_C#_50



C#访问数组元素

上一节我们学习了数组的声明和初始化,以及数组元素的访问方法。其实,C#中数组元素有多种初始化方式,请看下例:

【C#学习笔记】基础_C#_51

上例中,数组 a 的初始化方式我们已经学习过了;数组 b、c、d 是在初始化时为数组元素指定初始值,请注意数组 d 用 [3] 声明了数组长度,后面 { } 中的初始值个数要与 [ ] 中声明的长度相同。数组 b、c 初始化没有声明长度,长度由 { } 中的初始值个数确定。

上一节我们还学习了数组的一个属性 Length , Length 能够返回数组的长度,利用它和数组元素的索引,我们可以循环访问每一元素。上一节中打印名字的代码,可以这样改进:

【C#学习笔记】基础_C#_52

Length 属性返回数组的长度,如上例中,数组长度为 3 , Length 就返回 3 ,即循环变量 i 从 0 循环到 2 。为什么不循环到 3 呢?因为数组元素的索引是从 0 开始的呀!长度为 3 的数组,索引为 0 - 2 。

通过上例,我们看到,使用数组就能循环访问一组相同类型的变量了,是不是比使用单个变量要轻松呢?



C#的foreach关键字

for 循环使我们可以通过索引访问数组元素;而 foreach 循环则可以不依赖索引而读取每一个数组元素。下面的示例代码声明了一个整型数组,然后通过两种方法打印数组元素:

【C#学习笔记】基础_C#_53

运行结果是相同的:

【C#学习笔记】基础_C#_54

使用 foreach 的语法:

【C#学习笔记】基础_C#_55

需要解释一下 ④ ,如上面的示例代码,迭代变量 x 只能用于读取数组 num 中的值,但是不能给数组元素赋值,如果尝试给 x 赋值,则会有下面的错误提示:

【C#学习笔记】基础_C#_56

了解了 foreach 循环的语法,你可能会有疑问:好像 foreach 循环能做的 for 都能做, foreach 存在的意义是什么呢?其实,C#中还存在一些类似于数组的数据组织方式,它们中有一些是没有元素索引的,对于这些元素,只能通过 foreach 遍历。关于那些更高级的对象,我们留待后面的课程介绍。


C#的二维数组的声明和访问

二维数组,就是以数组作为元素的数组。挺拗口的,看看它跟一维数组的对比:

【C#学习笔记】基础_C#_57

左边的 a 是一维数组,数组中包含 4 个 int 型变量:a[0]、a[1]、a[2]、a[3] 。

右边的 b 是二维数组,数组中包含 2 个 int 型一维数组:b[0]、b[1] 。而 b[0] 和 b[1] 中又分别包含 3 个 int 型变量:b[0,0]、b[0,1]、b[0,2]、b[1,0]、b[1,1]、b[1,2] 。

总结一下,二维数组这样声明:

int[,] arr = new int[2,3]; //包含2个一维数组,每个一维数组包含3个变量,总共2*3=6个数组元素

二维数组元素这样赋值和打印:

arr[1,0] = 28; //二维数组元素有2个索引,都是从0开始,以arr数组为例,元素索引从[0,0]到[1,2]Console.Write( arr[1,0] );

我们可以用二维数组管理相关的数据,比如有 4 名同学参加语文和数学两门考试,我们用二维数组存储他们的成绩,每位同学的 2 门课分数,存储在一个一维数组中:   

【C#学习笔记】基础_C#_58

运行结果如下:

【C#学习笔记】基础_C#_59


访问器

通常C++中会对类中的属性设置成private,然后对可以修改的对象单独写一个修改值的方法,但C#则大大简化了这个步骤

这是C++、Java里面没有的东西。

注意命名规则 _name  ---->    Name

C#z中:字段是类中原始的成员对象,通常是私有的,属性是对字段的封装,通常是公有的



  class Child
    {
        private string _sex;     //隐藏字段

        public string Sex        //公开属性
        {
            get { return _sex; }    //读访问器
            set { _sex = value; }   //写访问器
        }

    }

使用:

            Child LaoWang = new Child();
            LaoWang.Sex = "male";
            Console.WriteLine(LaoWang.Sex);


补充:字段封装的快捷键: 光标放在字段内,CTRL + R + E


对Set访问器进行检查:

               public string Sex        //公开属性
        {
            get
           {
                 return _sex; 
           }    //读访问器
            set
           { 
               if(value == "man" && value != "woman")
               {
                   _sex = value; 
               }
           }   //写访问器
        }



访对象初始化器

使用:

Child child = new Child {Name = "小明", Age = 5};



C#中的数据类型

值类型: int   char  double   bool ...

值类型变量存储对象的值,赋值会创建值的副本,修改任何一个副本,都不会影响到其他的副本

引用类型: 类、数组、接口



C#中的结构体

struct class的区别:

struct不允许定义无参构造函数

默认访问限定符不同

struct中可以不实例化而直接访问成员方法



C#中枚举

在下面这种情况:

 class Child
    {
        public Child(String sex)
        {
            _sex = sex;
        }

        private String _sex;
        public string Sex
        {
            get
            {
                return _sex;
            }

            set
            {
                if (value == "男" || value == "女")
                {
                    _sex = value;
                }
            }
        }
    }

这样写是没有问题的,将性别限制成了“男”、“女”两种情况


但如果是星座呢? 星座有12种,难道要全部用if判断吗?

这个地方,就可以用枚举

代码如下:

enum Constell
    {
        白羊,水瓶,金牛,摩羯
    }

    class Child
    {
        Child(Constell con)
        {
            _con = con;
        }
        private Constell _con;

        internal Constell Con
        {
            get
            {
                return _con;
            }

            set
            {
                _con = value;
            }
        }
    }


【C#学习笔记】基础_C#_60



C#中的传值和传引用

和C++不同,默认传递方式取决于传递的参数是值类型还是引用类型

另外传递方式略有差异,需要在调用处和函数定义处均声明,如:

MySwap(ref val1, ref val2);

(个人觉得这样比C++好用许多)


C#中的out关键字

out用来声明参数为输出型参数。

同样,在函数的定义处和调用处,都要用out关键字声明要修饰的变量



(就更到这里吧。。 C#应该还是没用上,但这几天的学习,真心喜欢这门语言,又好看又好用啊)

(接下来,学习Qt,更新笔记!)