《C#本质论》第三、四章学习笔记

130 阅读6分钟

C#类型补充

这一章节在上一章的内容作了补充,首先指出了类型的划分:值类型引用类型

值类型是真实储存了数值的数据类型,而引用类型就相当于C语言的指针,本质上储存的是地址,指向不同的堆。另外还讲了元组和数组,元组是C# 7.0新增的特性,但是在我的电脑上没成功,这次就不写了,只讲数组。

值类型

除了string,目前讲过的其他所有基元类型都是值类型。值类型直接包含值。跟C语言的普通变量差不多,它的内存地址上就存储着它的值。

书中指出,初始化一个值类型变量并赋值的过程,是被赋值变量创建一个内存空间,然后拷贝源变量地址上的值过去。嗯,说的很详细。

引用类型

引用类型在C语言中并没有直接说明,个人猜测这是面向对象语言的概念。引用类型不存储实在的值,而是存储着内存地址,这跟C语言的指针是如出一辙的。直接给值类型存储大量的数据是不值得提倡的,书中指出大量复杂的数据都应该用引用类型。因为引用类型存储的地址是指向的,堆是多个内存地址连续内存块,也是为引用类型的变量分配实际数据的内存区域。

可空修饰符

值类型存储的是实在的数据,而不是地址,但是如果我们声明一个值类型变量但不想一开始给它赋值呢?能不能使用null呢?一般是不行的,但是C#允许使用?这个可空修饰符来让值类型变量使用null

int? i = null;
while(i==null);

匿名类型

当我们创建一个不想一开始就指定是什么类型的变量时,可以使用匿名类型关键字var,匿名类型一开始的类型是未知的,一定要实例化成具体的变量后才能使用,实例化关键字为new,这是面向对象语言中极为关键的概念!

var a = new {Title = " Essential C#",Value = 100.0};
System.Console.WriteLine(a.Title);

活用匿名类型声明,能够大大节省编写过程的时间成本。

数组

大体上来说,C#的数组在基础概念上和其他编程语言:数组存储一系列数据类型相同的元素。

不过,严肃的来讲,C#中的数组跟C语言的数组是不一样的,首先是声明方式,C#的方括号是在数据类型后面,而不是在变量名后面;C#使用数组的全过程是:C#的数组先需要声明数组,然后需要给这个数组实例化,才能往数组里存储数据。

int[] list; //先声明
list = new int[]{1,2,3};

new关键字是面向对象语言极为重要的,它用途很多,主要是实例化一个对象出来。

当然,也可以在声明时直接实例化,这时new就不是必要的了。

int[] list = {1,2,3};
int[] ls = new int[]{1,2,3,4};

不过,这里的new是真正的意义是在程序“运行时”分配内存,相当于malloc(),至于为什么没有free(),因为C#有GC啊~

使用new创建数组,就可以在方括号内指定数组长度了。

int[] list = new int[10];

C#中多维数组有两种声明方式,一种是在方括号内用逗号分隔维度:

最左边不在方括号内写数组的维度,是因为此时数组尚未实例化。

int[,] list = new int [9,9];//创建了一个9x9的二维数组

第二种声明方式是使用交错数组,这就跟C语言的声明方式很像了:

int[][] list = {new int[],
								new int[],
                new int[]}//创建一个由数组为元素,元素数量为3的组数组。

不过要注意的是,交错数组要求为内部的每个数组都创建数组实例

C#中,数组就是对象,C#本身对数组定义了很多种方法,最简单的是对数组求长度:

int[] list = new int[10];
int i = list.Length;//这里,i的值为10。

访问数组的元素基本上跟C语言的数组表示法差不多,也是现在大多数语言的方式。

int[] list = new int[3]{1,2,3};
int i = list[1]; //这里,i为2

实际上,字符串也是数组,至少C语言就是这么定义的,而在C#中大多数数组的方法也可用于字符串。这里以后还会学习到。

C#操作符

C#的操作符并没有什么特别的,作用大体上都是和C语言一致,不过书中详细介绍了逻辑操作符的一些特性。

异或操作符:^;两边的值有且只有一个为True时,整个表达式的值才为True。这个在C Prime Plus中貌似没学到?

bool a = True;
bool b = False
bool c = a^b;//c为真
bool d = a^c;//d为假

空合并操作符:??,如果左边的值为空,则将右边的值赋给它。

string list = null;
string a = "HW";
string b = list ?? a;
Console.WriteLine(b); //b输出为HW

C#控制流程

C#的各种循环和分支与C语言并无差别,甚至写法也没有啥差别。。。

当然,还是多了独有的特性的,比如foreach

foreach是更加简洁的遍历工具,语法简单,概念明确:

string welcome = "Hey,WDNMD!";
foreach(char i in welcome){
  Console.WriteLine(i);
}//输出一行一个字符

foreach()的写法是:

foreach(type variable in collection)
	statement

核心思路是用一个变量去暂时存储遍历对象的元素,然后执行操作。为了减少编写难度,一般用var类型声明这个变量即可(所以要注意遍历对象的类型是否有出错)。不过要注意,这个变量是只读的,在遍历过程中是不可更改的。

另外,C#的switch语句也更强大。C语言中swtich语句的case只能是整数或者字符(实际上就只能是整数),而C#更加灵活,可以是其他大多数数据类型了,书中说的是,只要与expression类型兼容,且是常量表达式即可~这样就可以尽情使用switch语句了。

小结

这两章大多数内容作为学过C语言的我读起来基本没障碍,不过可惜的是我没有学习位操作,所以位操作符完全看不懂,以后要用到再来补习吧。。。

C#比C语言多了很多让人编写起来很舒服的特性,特别是switch语句。foreach语句是简单化的遍历工具,优点python内味。

还有就是,值类型和引用类型的概念,这是学C语言时没怎么接触的,毕竟C语言有指针,直接简单粗暴的搞地址就行了~