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

【C语言】数组与指针的辨析

2016-10-05 14:00 323 查看
很多同学一直分辨不了数组和指针有什么区别,下面我参考一些资料,并根据自己的理解尝试对数组和指针进行辨析。

首先要有一个概念,数组就是数组,指针就是指针;数组不是指针,指针也不是数组。那些「数组等效指针」的说法是指在一定的条件下的才成立的,不是所有情况都适用。

下面有两个声明

char a[] = "hello";
char *p = "world";


那么在内存中将会初始化成这样:



其中a是数组,p是指针。

数组定义char a[]预留6个字符位置,并用名称a来表示。为什么是6个字符位置,因为初始化的时候,hello单词加上’\0’符号正好是6个字符。

指针声明char *p请求一个位置放置指针,用名称p表示。这个指针可以指向内存一个字符或者一个连续的字符(字符串)。

数组a是一个有6个字符的内存块,如果你对a使
sizeof
(即
sizeof a
),其返回的值是6。

指针p的大小是int,int是2字符16位还是4字符32位,这要看机器的类型。对p使用
sizeof
(即
sizeof p
),其返回的值和
sizeof int
是一样的。另外p所指向的地址是那个字符串的首地址,也称作基址。如果对*p使用sizeof,其返回值和
sizeof char
是一样的。这是因为p指向char,如果指向int则与
sizeof int
一样的。

编译器对数组和指针有什么不同的操作呢?

当编译器看到表达式a[3]时,它生成的代码从a位置开始跳过3个,然后取出那个字符。如果编译器看到p[3],它生成的代码找到p的位置,取出其中的指针值,在指针上加上3然后取出指向的字符。

换言之,a[3]是名为a的对象(的起始位置)之后3个位置的值,而p[3]是p指向的对象的3个位置之后的值。

另外,a[3]本质上就是*(a+3)。a是基址,3是偏移量,星号是解引用。如果你把a[3]写成3[a],编译器是不会报错的。但是我们没有这习惯所以不建议这样写。

那些「数组等价于指针」又是什么意思呢?

这句话的意思是说,数组和指针的算法定义使得可以使用指针方便地访问数组或者模拟数组。

或者说,只有在指针算术和数组下标运算中是等价的。

举个例子,在函数形参中,数组和指针是等价的,数组声明和指针的声明是可以互换的。

void foo(char a[]);
void foo(char *p);
没有任何差别。

为什么会这样?因为这样比较方便。

这里的数组形成会退化为指针,也就是说,数组根本没有传入到函数,允许void foo(char a[])的存在只不过为了看起来好像传入了数组而已,实际上传入的只是实参数组的首地址。这也是为什么调用函数写数组形参的时候,不是用
foo(array
)
,而是
foo(array)
。因为形参需要的是数组的首地址,也就是array,而不是数组的第n个元素array


参考资料:《你必须知道的495个C语言问题》第六章
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: