本文转自:http://blog.csdn.net/xingjiarong/article/details/47656339

利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数,下面就结合具体的实例,分类说明一下。

一、引用同一个文件中的变量

#include<stdio.h>

int func();

int main()
{
func(); //
printf("%d",num); //
return ;
} int num = ; int func()
{
printf("%d\n",num);
}

如果按照这个顺序,变量 num在main函数的后边进行声明和初始化的话,那么在main函数中是不能直接引用num这个变量的,因为当编译器编译到这一句话的时候,找不到num这个变量的声明,但是在func函数中是可以正常使用,因为func对num的调用是发生在num的声明和初始化之后。

如果我不想改变num的声明的位置,但是想在main函数中直接使用num这个变量,怎么办呢?可以使用extern这个关键字。像下面这一段代码,利用extern关键字先声明一下num变量,告诉编译器num这个变量是存在的,但是不是在这之前声明的,你到别的地方找找吧,果然,这样就可以顺利通过编译啦。但是你要是想欺骗编译器也是不行的,比如你声明了extern int num;但是在后面却没有真正的给出num变量的声明,那么编译器去别的地方找了,但是没找到还是不行的。

下面的程序就是利用extern关键字,使用在后边定义的变量。

#include<stdio.h>

int func();

int main()
{
func(); //
extern int num;
printf("%d",num); //
return ;
} int num = ; int func()
{
printf("%d\n",num);
}

二、引用另一个文件中的变量

如果extern这个关键字就这点功能,那么这个关键字就显得多余了,因为上边的程序可以通过将num变量在main函数的上边声明,使得在main函数中也可以使用。 
extern这个关键字的真正的作用是引用不在同一个文件中的变量或者函数。

main.c

#include<stdio.h>

int main()
{
extern int num;
printf("%d",num);
return ;
}

b.c

#include<stdio.h>

int num = ;

void func()
{
printf("fun in a.c");
}

例如,这里b.c中定义了一个变量num,如果main.c中想要引用这个变量,那么可以使用extern这个关键字,注意这里能成功引用的原因是,num这个关键字在b.c中是一个全局变量,也就是说只有当一个变量是一个全局变量时,extern变量才会起作用,向下面这样是不行的。

main.c

#include<stdio.h>

int main()
{
extern int num;
printf("%d",num);
return ;
}

b.c

#include<stdio.h>

void func()
{
int num = ;
printf("fun in a.c");
}

另外,extern关键字只需要指明类型和变量名就行了,不能再重新赋值,初始化需要在原文件所在处进行,如果不进行初始化的话,全局变量会被编译器自动初始化为0。像这种写法是不行的。

extern int num=;

但是在声明之后就可以使用变量名进行修改了,像这样:

#include<stdio.h>

int main()
{
extern int num;
num=;
printf("%d",num);
return ;
}

如果不想这个变量被修改可以使用const关键字进行修饰,写法如下:

main.c

#include<stdio.h>

int main()
{
extern const int num;
printf("%d",num);
return ;
}

b.c

#include<stdio.h>

const int num=;
void func()
{
printf("fun in a.c");
}

使用include将另一个文件全部包含进去可以引用另一个文件中的变量,但是这样做的结果就是,被包含的文件中的所有的变量和方法都可以被这个文件使用,这样就变得不安全,如果只是希望一个文件使用另一个文件中的某个变量还是使用extern关键字更好。

三、引用另一个文件中的函数

extern除了引用另一个文件中的变量外,还可以引用另一个文件中的函数,引用方法和引用变量相似。

main.c

#include<stdio.h>

int main()
{
extern void func();
func();
return ;
}

b.c

#include<stdio.h>

const int num=;
void func()
{
printf("fun in a.c");
}

这里main函数中引用了b.c中的函数func。因为所有的函数都是全局的,所以对函数的extern用法和对全局变量的修饰基本相同,需要注意的就是,需要指明返回值的类型和参数。

12.extern(转)的更多相关文章

  1. C++学习笔记 知识集锦(二)

    1. 命名规范 2. 代码格式 3. QString的判断 4. 对象的判空 5. 隐式接口&显式接口 6. vector&string 7. static 8. const 9. v ...

  2. 【C语言入门教程】1.3 C语言“32个”关键字

    关键字是已被C语言标准作为命令.数据类型或者固定函数名的字母组合.关键字不能被用做变量名或函数名.下面列举了C语言的32个关键字,它们遵循C语言的语法使用,形成了C程序设计语言.  序号  关键字 说 ...

  3. openal-1.13 静态编译(mingw32)

    1.CMakeLists.txt SET(LIBTYPE SHARED) 改成 SET(LIBTYPE STATIC) 2.include/al/al.h 删除 dllexport 3.include ...

  4. ARM中C和汇编混合编程及示例(转)

    在嵌入式系统开发中,目前使用的主要编程语言是C和汇编,C++已经有相应的编译器,但是现在使用还是比较少的.在稍大规模的嵌入式软件中,例如含有OS,大部分的代码都是用C编写的,主要是因为C语言的结构比较 ...

  5. 【读书笔记】C++Primer---第二章

    1.C++基本数据类型:字符型.整型.浮点型等: 2.算术类型如下表,下表只是表示C++要求的最小储存空间,但是一般编译器使用的都比所要求的储存空间大,以前类型所能表示的最大值也因机器的不同而有不同的 ...

  6. stm32 启动文件 C和汇编交叉嵌入

    在嵌入式系统开发中,目前使用的主要编程语言是C和汇编,C++已经有相应的编译器,但是现在使用还是比较少的.在稍大规模的嵌入式软件中,例如含有OS,大部分的代码都是用C编写的,主要是因为C语言的结构比较 ...

  7. C51学习笔记

    转自:http://blog.csdn.net/gongyuan073/article/details/7856878 单片机C51学习笔记 一,   C51内存结构深度剖析 二,   reg51.头 ...

  8. *2.3.4_封装成agent

    上一节在验证平台中加入monitor时,读者看到了driver和monitor之间的联系:两者之间的代码高度相似.其本质是因为二者处理的是同一种协议,在同样一套既定的规则下做着不同的事情.由于二者的这 ...

  9. RK3288 增加双屏异显 eDP+LVDS

    CPU:RK3288 系统:Android 5.1 下面是官方文档中的信息. 1.rk3288 支持的显示接口可以任意组合. 2.双屏异显时,一个显示接口当主屏,另一个当副屏:主副屏由板级 dts 文 ...

随机推荐

  1. py thon 多线程(转一篇好文章)

    http://www.cnblogs.com/fnng/p/3670789.html

  2. 设置参数进行java的jvm监控

    1.设置jconsole监控服务器的tomcat参数及java jvm大小,执行命令vi ../tomcat/bin/catalina.sh  “在服务器安装的tomcat目录下” JAVA_OPTS ...

  3. [Lydsy1805月赛] 对称数

    挺不错的一道数据结构题QWQ. 一开始发现这个题如果不看数据范围的话,妥妥的树上莫队啊23333,然鹅10组数据是不可能让你舒舒服服的树上莫队卡过的23333 于是想了想,这个题的模型就是,把u到v链 ...

  4. URAL 2062 Ambitious Experiment(分块)

    [题目链接] http://acm.timus.ru/problem.aspx?space=1&num=2062 [题目大意] 给出两个操作,操作一给出区间[l,r],对l到r中的每一个下标i ...

  5. 【主席树】bzoj3653 谈笑风生

    设siz[i]表示i的子树大小-1. 询问中b在a上方的便于统计. 对于b在a下方的情况,贡献为距a距离在K以内的节点的siz之和. 按dfs序建立可持久化线段树,线段树的下标是深度. 相当于把每个点 ...

  6. Problem Q: 多项式求和x+(x^2)/2!+(x^3)/3!+...

    #include<stdio.h> #include<math.h> int main() { float x,i; scanf("%f",&x); ...

  7. fidder模拟post提交到PHP遇到的问题

    http头必须带上Content-type: application/x-www-form-urlencoded  之后 ,php 才能接收到post数据 1. 用php://input可以很便捷的取 ...

  8. zk删除node模式

    检查状态 状态描述指定的znode的元数据.它包含时间戳,版本号,ACL,数据长度和子znode等细项. 语法 stat /path 示例 stat /FirstZnode 输出 [zk: local ...

  9. ILSpy反编译软件的使用

    早期.Net平台下的反编译软件一般用reflector,但自从其商业化后就没有使用了,现在主要用ILSpy查看dll的源码,其开源.免费的特点很快就流行开来,功能和性能丝毫不逊于reflector   ...

  10. Mysql的共享锁和排他锁(转载)

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...