指针与数组名异同比较总结

来源:互联网 发布:unity3d捕鱼完整源码 编辑:程序博客网 时间:2024/06/08 06:40

首先用一句话来概括本文文意——指针只是指针,即存储地址的变量;数组名既有作为指针常量的特性,也具有作为数组的不同于指针的特征。

1、指针

      想到指针就应当想到地址,记住一句话:“指针即地址”。指针是个用来存储地址的变量,它与普通类型的变量唯一的不同就是它所存储的内容是个地址,可以通过某种操作关联到其它的内存空间,这种操作即为地址的间接引用。但是如果不对指针进行间接引用的操作的话,那么,指针变量与普通的变量没有任何不同,它所指向的内存空间也不会发生任何的改变。


例如上图,声明一个字符型变量ch与指针ptr,并将ptr指向ch。可能很多同学都会跟我一样,一想到指针就会想到它会指向某个地方,会对指针的操作格外小心翼翼,继而会害怕去使用指针。这里要谨记一句话——除非对指针进行间接引用操作,否则指针与它所指向的内容毫无瓜葛。这里的关联箭头会给我们造成很多的误导,总是直接将指针与它所指向的内容紧紧连在一起,所以如果只是对指针变量进行非间接引用操作,就不会对它所指向的内容造成任何改变。所以我们在使用指针的时候,一定要明了当前对其进行的操作时直接的还是间接的。


2、数组

1)数组名作为指针常量

数组名有两重身份,第一个就是作为指针的身份。但是它是一个特殊的指针,即是一个指针常量。即声明后不能对它的值进行任何的修改,它所存放的地址是数组首个元素的地址。

2)数组名作为数组的特性

数组名只有在两种场合不作为一个指针常量。第一个就是作为sizeof操作符的操作数时。sizeof是计算一个变量的空间大小,当数组名作为sizeof操作符的操作数时,操作的结果是整个数组的空间大小而非一个指针常量的大小。第二个就是作为单目操作符&的操作数时。操作符&的作用是获取其操作数的地址。当数组名作为&的操作数时,获取到的地址并不是一个指针常量的地址,二是一个指向数组的地址。指向数组的地址在《c与指针》中的多维数组章节有非常详细的描述。


3、指针与数组名的异同

1)从声明开始说起

编译器在声明一个数组时,其过程是根据所指定的数组元素个数为数组分配相应的内存空间,然后创建一个指针常量,即数组名,并用分配的内存空间的起始地址为其进行初始化。而在声明一个指针的时候,编译器只为其分配相应存储地址的空间,并不会分配任何其它的空间。

2)下标引用

记住一句话——下标引用是作用于任何指针,而仅仅是数组名的。其实下标引用的过程是先取地址,在进行间接引用。如现在有指针char  *ptr与字符数组char  ch[10]。在进行赋值ptr = ch;现在要取数组中的第三个元素,可以采取的操作是:ptr[2]与ch[2]。唯一的不同是ptr是个普通指针,可以进行指针运算,而ch是个指针常量,其值无法改变,所以有一句话就是——下标绝不会比指针更有效率,但是指针有时会比下标更有效率,就是在计算具体地址的时候,如果ptr采取的是逐步后移,即每次ptr++,而ch只能是从ch[0]、ch[1]、、、,前者所做的指针运算只是每次加1,而后者可能会加较大的数据,这时候便需要进行乘法运算,计算具体的移位数量。具体案例在《c与指针》P145。

3)作为函数形参

其实数组并不能作为形参,一般都是以指针作为形参来接受传递的数组实参。而我们见过的数组形参,它只是编译器放行的一种形式,为了使人们比较容易理解,其它只是有数组的外貌,其数组名并不是真正的数组名,也只是一个普通的指针而已。所以可以对其值进行任何修改操作。这就是为什么所谓的数组形参可以接受任何长度的数组实参的原因。使用这种方法,如果想要知道数组的长度,需要显示的进行传递。


因此

0 0