浅谈C语言 extern 指针与数组
/*
* d.c
*
* Created on: Nov 15, 2011
* Author: root
*/
#include "apue.h"
int a[] = {3,2};
void hello()
{
printf("d.c %d",a);
}
/*
============================================================================
Name : hello.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include "apue.h"
extern void hello();
extern int *a;
int main(void)
{
hello();
printf("\n : %d",a);
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(理解吗?)。
如果将hello.c改成下面这样
#include "apue.h"
extern void hello();
extern int *a;
int main(void)
{
hello();
printf("\n : %d",a[1]); // 这里被修改了
return EXIT_SUCCESS;
}
在main函数中,按照编译器的规矩,a[1]可以被我们这样认为 *(a+1);
因为a等于3,a+1等于4,*(a+1)的意思就是取内存地址为4的字节内容,我不知道地址为4的那个字节里面是什么东西。但是起码不是我们想要的。
转载请注明出处:http://www.cnblogs.com/stonehat/archive/2011/11/15/2250091.html
二、再看下面的代码。
// file : d.c
#include "apue.h"
int *a;
void hello()
{
a =(int *) malloc(2);
a[0]=3;
a[1]=2;
printf("d.c %d",a);
}
// file : hello.c
#include "apue.h"
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,就会发现他们的地址是一样的)。
这种情况下的内存分配是这样的。
如果main函数改成这样的,就是输出a[1]的值,
int main(void)
{
hello();
printf("\n : %d",a[1]);
return EXIT_SUCCESS;
}
按照规矩,输出*(a+1),a等于161968136, 加1,就等于161968140(懂?),就会输出2.
三、再看一种情况。
// d.c
#include "apue.h"
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);
}
// hello.c
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.
转载请注明出处:http://www.cnblogs.com/stonehat/archive/2011/11/15/2250091.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器