C 数组和指针问题

A源文件声明:
int a[10] = {0}
int *b = a;

B源文件:
extern int *a;
extern int b[];
int x,y;

x = a[3];
y = b[3];

为什么会报段错误?

阅读 2.8k
2 个回答

指针和数组是不一样的,所以声明和定义应该一样,否则会出大问题,为什么出问题就要回到指针和数组的区别上了。
指针的使用过程大致如下:
clipboard.png

指针下标的使用过程大致如下:
clipboard.png

我们可以看到,如果对指针进行下标操作时,下标取的是指针指向空间偏移后的内容(5081 + i)。

我们再来看数组,

clipboard.png

a[]这个数组直接就是地址,我们取得值也是从a[]的起始地址开始算偏移的(9980 + i)。
所以,我们可以看出指针需要一个转换过程才能通过下标获取到它需要的内容,而数组直接就可以了。

回到你的问题,
A中定义了int a[10] = {0}
B中声明extern int *a;

那么在B中使用a的时候,B把它当成指针,也就是说,需要先获取它的值(也就是要访问的地址),然后用这个值加上偏移得到我们想要的内容。但其实它是数组,我们并不需要先获取数组起始处32bit的内容作为要访问的地址,然后用这个地址去获取我们想要的内容,所以会报错(好像老的编译器不会报错,然后就很难debug...)。

这个问题在《C专家编程》中用了一个章节讲解,我自己也写过一个读书笔记你可以去看看:
《C专家编程》读书笔记(4-10章)

你把B文件的extern int *a;改为extern int a[];就行了。

你在A,B文件声明的a,是两个类型的a,A中是数组类型,B中的是指针类型,其中数组类型可以转化为指针类型。可以转化并不代表它们类型就是一样的,最简单的例子,double转int。

推荐问题
宣传栏