C#数组和指针全面讨论

C#有很多值得学习的地方,这里我们主要介绍C#数组和C#指针,包括介绍为什么C#语言把数组形参当作指针等方面。

什么时候C#数组和C#指针相同

所有作为函数参数的数组名总是可以通过编译器转换为指针。在其他所有情况下,数组的声明就是数组,指针的声明就是指针,两者不能混淆。但在语句或表达式中引用时,数组总是可以写成指针的形式,两者可以互换。然而,C#数组和C#指针在编译器处理时是不同的,在运行时的表示形式也是不一样的。对编译器而言,一个数组就是一个地址,一个指针就是一个地址的地址,你应该根据情况做出选择。

为什么会发生混淆

当人们学习编程时,一开始总是把所有的代码都放到一个函数里。随着水平的进步,他们把代码分别放在几个函数中。在水平继续提高后,他们最终学会了如何用几个文件来构造一个程序。

什么时候C#数组和C#指针是相同的?C#语言标准对此作了如下说明:
规则1 表达式中的数组名(与声明不同)被编译器当作一个指向该数组第一个元素的指针。
规则2 下标总是与指针的偏移量相同。
规则3 在函数参数的声明中,数组名被编译器当作指向该数组的第一个元素的指针。

规则1:“表达式中的数组名”就是指针

规则1和2合在一起理解,就是对数组下标的引用总是可以写成“一个指向数组的起始地址的指针加上偏移量。”(个人认为,表述为“一个指向该数组第一个元素的指针加上偏移量”更明确。)

对数组的引用如a[i]在编译时总是被编译器改写成*(a+i)的形式。C#语言标准要求编译器必须具备这个概念性的行为。于是,a[6]和6[a]都是正确的。

编译器自动把下标值的步长调整到数组元素的大小。这就是为什么指针总是有类型限制,每个指针只能指向一种类型的原因,因为编译器需要知道对指针进行解除引用操作时应取几个字节,以及每个下标的步长应取几个字节。

规则2:C#语言把数组下标作为指针的偏移量

事实上,下标范围检测被认为并不值得加入到C#语言中。数组下标是定义在指针的基础上的,所以优化器常常可以把它转换为更有效率的指针表达式,并生成相同的机器指令。C#语言把数组下标改写成指针偏移量的根本原因是指针和偏移量是底层硬件所使用的基本模型。

相关推荐