您的位置:首页 > 编程语言 > C语言/C++

C语言——数组与指针区别与联系

2012-03-03 23:50 495 查看
今天重拾了一会C语言,看了两章《C专家编程》有关数组与指针的内容。看完感觉收获还是蛮多的,一些以前零碎的知识点一下子被串了起来,估计以后不会那么轻易就遗忘喽,

!言归正传,接下来我想把C语言中数组与指针这块的内容稍稍做个梳理以备日后查看。

学过C语言的人可能都知道C中最头疼的莫过于指针了,说到指针大家在平时写程序的过程也会经常把它和数组(亦或是数组名)弄混。这也难怪,因为有些情况下使用数组和用指针是一样的,比如后面将要介绍到的函数传参的情况。在此之前,首先大体介绍一下数组与指针的不同。

int num[5] = {1,2,3,4,5};

int *p;

p = num;

前两行代码分别声明了一个含有5个元素的整型数组以及一个指向整型数据的指针变量,第三句话使得指针p指向num数组。其中,num是数组名,p是指针名。之所以我们经常会把数组和指针搞混主要是因为我们常说“数组名就是数组首元素的指针”,其实这种说法并不准确,确切的说应该是“数组名的值等于数组首元素的地址”才对。虽然说我们都可以用数组下标的形式来获取数组里的元素,上例种取数组的第三个元素既可以是num[2],也可以是p[2]。虽说写法差不多,但是它们各自获取首元素的流程却不一样。num[2]:直接对数组首地址num偏移两个单位得到第三个元素的地址,然后再由该地址得到第三个元素的值;而p[2]则是先访问地址为p的内存单元,获取其中的数据(即数组的首地址),再对首地址偏移两个单位得到第三个元素的地址,最再由该地址得到第三个元素的值。由此可以看出,用指针来获取数组元素会比直接用数组名来访问多一步取首地址的操作。大家可以这样记:数组类型就是一个地址,而指针则是地址的地址。

上面也说了,既然数组与指针本就是两种不同的数据类型,那为什么好多人(我也不例外哈)有时还是分不清它俩呢?究其原因,主要还是因为有些情况下它俩能通用。那哪些情况下它们能通用呢,虽然书中列了3种情况,不过本人最主要只有一种,那就是函数调用参数传递的情况。看看下面两段代码:

void fun(int num[]) { ... }

void fun(int num[5]) { ... }

void fun(int *p) { ... }

这两种写法其实是等价的,因为编译器在处理形参为数组类型的变量时都会将其看做是指向数组第一个元素的指针。置于为什么编译器要这么处理,你可以这么理解:一是计算机硬件能够直接支持指针和偏移,而不能直接支持数组;二是基于效率考虑,很多时候函数中往往只需要处理数组中的少部分数据,因此实参传形参时没有必要将数组全部进行拷贝,将数组转化为指针后,需要用到哪个元素直接利用指针,偏移还有解引用就OK了!

数组与指针通用的情况最主要就是上面这种,其他时候你就把num看做数组类型,看做一个整体就好。如果你还是分不清哪些情况下是数组,哪些情况下是指针的话,还有一个判别方法,那就是利用sizeof函数。当数组是一个整体时,sizeof(数组名)得到的是整个数组所占的字节空间,当数组转化为指向数组第一个元素的指针时,sizeof出来的结果是4(即指针类型的字节大小)。大家可以试一下,当你在main函数中sizeof上面的num的话得到的应该是整个数组的字节大小即20(int占4B的情况),倘若你在你自定义的fun函数中sizeof参数数组的话,得到的结果应该是4。

另外两个需要注意的小点是:数组名的值等于数组的首地址(即第一个元素的地址),当你对数组进行取地址(&)操作时得到的结果也是数组的首地址,容易混淆的朋友可以把这时候的数组看做一个整体,取完地址自然是数组的首地址。所以,上例种的num的值和&num的值是相同的。另外一个需要注意的地方是,不能对数组名进行++或--操作,因为数组名是个左值不能对其进行重新赋值,或者你可以这样认为,数组名就是代表了定义时的那个数组,不能再变了。

说了这么多,也不知自己讲清一些木有,也许把某些朋友越搞越糊涂了,如果真是这样的话,建议可以看看《C专家编程》的4,8,9三章。上面有些地方可能说得也不是很准确,欢迎感兴趣的朋友可以相互交流交流,今天就写到这喽!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: