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

C语言中数组与指针的区别

2014-02-09 21:02 381 查看
在C语言的代码中,经常会将数组的数组名当做指针来使用。通过地址的偏移来对数组的元素进行操作。

此时,认为数组名和指针是等同的。

但是数组与指针到底是什么关系?将指针和数组划等号,会不会有什么问题呢?

下文,将对数组与指针的区别进行说明。

在进行说明之前,先说明一个背景知识:在C语言程序运行时,是通过符号(label)的地址进行访问的。

也就是,经过编译和链接之后,程序中的符号(变量和函数)都会被替换成相应的地址。

此部分知识,可参考程序编译的相关书籍。

正因为是通过符号的地址进行访问,这就造成了指针和数组在使用上的最大区别:指针在进行访问时,需要多一次的地址提取!

下面举例进行说明:

数组

char a[9] = "abcdefgh";

b = a[i];

此时,编译器已知的是数组的地址,即数组的首地址。要取得a[i],需要进行如下两步操作:

将数组首地址加i;
通过步骤1中的地址,取得a[i]的值

指针

char *p = "abcdefgh";

c = p[i];

此时,编译器已知的是指针p的地址。要取得p[i],需要进行如下三步操作:

通过指针p的地址,取得p所指向的内容"abcdefgh"的首地址
将步骤1中的地址加i
通过步骤2中的地址,取得p[i]的内容

因此,上述的数组和指针操作中,看起来二者的操作没有区别,执行的结果也相同。

实际上,指针在进行访问时,需要多一次的地址提取!

一个例子证明上述区别:

file1:
char ptr[] = "HELLO";
file2:
extern char *ptr;

char ch = ptr[3];


上面的程序执行结果是什么?程序应该会出现segment fault。有兴趣的,可以编译运行一下。

道理很简单,file1中定义了数组ptr。那么程序在编译时,符号的地址是已知的,即数组首地址已知。

file2中,将ptr声明为char型指针。这样的话,file2中对ptr进行操作时,是将ptr的地址作为指针的地址来使用的。

那么,file2中会按照指针的访问的三个步骤进行操作。

程序的初衷是将ptr[3](字符'L')赋值给ch。但是,编译器将字符'L'当做一个地址。

把ASCII字符当做地址进行操作,显然会得到一个错误的结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: