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

C语言指针与数组的区别(1) extern

2012-04-11 01:20 435 查看
近日阅读c专家编程,对c语言中的指针数组的区别有了新的认识。

先看一段代码:

//des.c
int a[] = {3,2};
void hello(){
printf("d.c %d",a);
}


//test.c
#include<stdio.h>
extern void hello();
extern int *a;
int main(void){
hello();
printf("\n : %d",a);
//printf("\n : %d",a[1]);
return EXIT_SUCCESS;
}



上面的代码的输出为

d.c 134520856

: 3

第一行代码是第一个文件d.c输出了int a[];a的内容

第二行代码是第二个文件hello.c输出了extern int *a;指针a的内容

gcc编译的时候,在链接阶段了,hello.o有extern a符号,在d.o中找到,所以extern a 和d.o的a是同一个符号(我认为称他们“指向相同”有歧义)

也可以用图像表示


。数组第一项在内存地址134520856处。

第一个文件d.c将a当成数组来处理,可以按照想象的进行输出,但是

但是第二个文件是把符号a当成指针来操作的(因为 extern int *a), 指针所在的地址是134520856,但是指针的值是3

如果去掉注释之后,则会报错,因为在main函数中,按照编译器的规矩,a[1]可以被我们这样认为 *(a+1);

因为a等于3,a+1等于4,*(a+1)的意思就是取内存地址为4的字节内容,我不知道地址为4的那个字节里面是什么东西。

再看下面代码:

int *a;
void hello(){
a =(int *) malloc(2);
a[0]=3;
a[1]=2;
printf("d.c %d",a);
}


extern void hello();
extern int *a;
int main(void){
hello();
printf("\n : %d",a);
return EXIT_SUCCESS;
}


输出结果:

d.c 161968136

: 161968136

我说了实际上 只要是extern a就表示这两个a符号,实际上是同一个符号a,(你可以将两个文件的函数输出&a,就会发现他们的地址是一样的)。

这种情况下的内存分配是这样的。



最后再看一个代码:

int *a;void hello(){
a =(int *) malloc(2);
a[0]=3;
a[1]=2;
printf("d.c value:%d\n",a);
printf("d.c address:%d\n",&a);
}


extern void hello();
extern int a[];
int main(void){
hello();
printf("hello.c value:%d\n",a);
printf("hello.c address:%d\n",&a);
printf("hello.c  a[1]",a[1]);
return EXIT_SUCCESS;
}


输出结果为:

d.c value:160223240

d.c address:134520864

hello.c value:134520864

hello.c address:134520864

hello.c a[1]

内存分布图为:



在hello.c中,a被当成int a[];

a的值为160223240, *(a+1),就能够访问到2.

总结:

编译器在编译的时候左值会由编译器分配地址,而右值运行时才能知道,当我们声明一个指针变量的时候,会首先为指针变量开辟一个内存空间,

即指针地址是确定的,但是指针所指向的地方时在运行时才知道。如果使用指针引用定义数组中的元素时,会将数组元素的值解析成地址,就造成了

访问错误
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: