用#include可以包含其他头文件中变量、函数的声明,为什么还要extern关键字?

1.头文件

其实头文件对计算机而言没什么作用,只是在预编译时在#include的地方展开一下,没别的意义了。将头文件的后缀改成xxx.txt,然后在引用该头文件的地方用#include"xxx.txt",编译、链接都很顺利的过去了,由此可知,头文件仅仅为阅读代码作用,没其他的作用了!

头文件就是对用户的说明。函数,参数,各种各样的接口的说明。

那既然是说明,那么头文件里面放的自然就是关于函数,变量,类的“声明”。

最好不要在头文件里定义什么东西。比如全局变量:

/*xx头文件*/

#ifndef _XX_头文件.H

#define _XX_头文件.H

int A;

#endif

那么,很糟糕的是,这里的int A是个全局变量的定义,所以如果这个头文件被多次引用的话,你的A会被重复定义,显然语法上错了。只不过有了这个#ifndef的条件编译,所以能保证你的头文件只被引用一次,不过也许还是不会出岔子,但若多个c文件包含这个头文件时还是会出错的,因为宏名有效范围仅限于本c源文件,所以在这多个c文件编译时是不会出错的,但在链接时就会报错,说你多处定义了同一个变量,

Linking...

incl2.obj : error LNK2005: "int glb" (?glb@@3HA) already defined in incl1.obj

Debug/incl.exe : fatal error LNK1169: one or more multiply defined symbols found

注意!!!

2.extern

对变量而言,如果你想在本源文件(例如文件名A)中使用另一个源文件(例如文件名B)的变量,方法有2种:

(1)在A文件中必须用extern声明在B文件中定义的变量(当然是全局变量);

(2)在A文件中添加B文件对应的头文件,当然这个头文件包含B文件中的变量声明,也即在这个头文件中必须用extern声明该变量,否则,该变量又被定义一次。

对函数而言,如果你想在本源文件(例如文件名A)中使用另一个源文件(例如文件名B)的函数,方法有2种:

(1)在A文件中用extern声明在B文件中定义的函数(其实,也可省略extern,只需在A文件中出现B文件定义函数原型即可);

(2)在A文件中添加B文件对应的头文件,当然这个头文件包含B文件中的函数原型,在头文件中函数可以不用加extern。

对上述总结换一种说法:

(a)对于一个文件中调用另一个文件的全局变量,因为全局变量一般定义在原文件.c中,我们不能用#include包含源文件而只能包含头文件,所以常用的方法是用extern  int a来声明外部变量。  

另外一种方法是可以是在a.c文件中定义了全局变量int global_num ,可以在对应的a.h头文件中写extern int global_num ,这样其他源文件可以通过include a.h来声明她是外部变量就可以了。


18.21 关键字extern的更多相关文章

  1. C# 关键字extern用法

    修饰符用于声明在外部实现的方法.extern 修饰符的常见用法是在使用 Interop 服务调入非 托管代码时与 DllImport 属性一起使用:在这种情况下,该方法还必须声明为 static,如下 ...

  2. 【转载】理解C语言中的关键字extern

    原文:理解C语言中的关键字extern 最近写了一段C程序,编译时出现变量重复定义的错误,自己查看没发现错误.使用Google发现,自己对extern理解不透彻,我搜到了这篇文章,写得不错.我拙劣的翻 ...

  3. 【校招面试 之 C/C++】第29题 C/C++ 关键字extern

    1.extern "C" extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码.加上extern "C"后,会指示 ...

  4. C/C++关键字 extern

    1.基本解释:extern 可置于变量或函数前面,表示变量或函数的定义在别的文件中,以提示编译器遇到此变量或函数时在其他模块中寻找定义. extern还有另外2个作用.第一:与“C”连用时,如 ext ...

  5. 关键字 extern

    定义:extern可置于变量或者函数前,以表示变量或者函数的定义在别的文件中.编译器会到其他模块中寻找其定义. extern int f(); extern int i; extern关键字   作为 ...

  6. 与C/C++关键字extern有关的原理

    关键字有一定的语义,但是用法不唯一. 对于C/C++语言的预编译.编译.汇编.链接.我相信大家在接触C++一年不到就背的滚瓜烂熟,但是其中的细节,是后来才慢慢想明白的.为什么我不讲extern关键字呢 ...

  7. DSP 中关键字extern,cregister,Near ,Far,restrict,volatile

    extern:extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.另外,extern也可用来进行链接指定. const: 可以 ...

  8. 关键字extern

    extern 可以置于  变量  或  函数  前,  以表明变量 或 函数 的定义在别的文件中,  下面代码用到的这些变量  或 函数是外来的,  不是本文件定义的, 提示链接器遇到此变量和函数时在 ...

  9. c++关键字extern的作用

    1.用extern修饰变量 使用在别的在源文件定义的非静态外部变量时,需要使用extern进行说明 2.用extern修饰函数 使用在别的在源文件定义的函数时,需要使用extern进行说明 3.用ex ...

随机推荐

  1. jsonp实现ajax跨域

    前端 dataType为jsonp,若不指定回调函数名则默认为callback $.ajax({ url:headUrl+'/img/getImgList', type:'GET', dataType ...

  2. MySQL从本地向数据库导入数据

    本文来自:https://www.cnblogs.com/lettuce-u/p/10715795.html(自己收藏看) 在localhost中准备好了一个test数据库和一个pet表: mysql ...

  3. 纯js星级评分

    @{ Layout = null;} <!DOCTYPE html> <html><head> <meta name="viewport" ...

  4. python代码规范和命名规范

    一.简明概述 1.编码 如无特殊情况, 文件一律使用 UTF-8 编码 如无特殊情况, 文件头部必须加入#-*-coding:utf-8-*-标识 2.代码格式 2.1.缩进 统一使用 4 个空格进行 ...

  5. centos6 升级安装openssh7

    1.准备工作: 查看下当前SSH版本: [root@bogon ~]# ssh -V OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013 或者 [root@b ...

  6. Action访问Servlet API的三种方法

    一.为什么要访问Servlet API ? Struts2的Action并未与Servlet API进行耦合,这是Struts2 的一个改良,从而方便了单独对Action进行测试.但是对于Web控制器 ...

  7. 我的自定义框架 || 基于Spring Boot || 第一步

    今天在园子里面看到一位大神写的springboot做的框架,感觉挺不错,遂想起来自己还没有一个属于自己的框架,决定先将大神做好的拿过来,然后加入自己觉得需要的模块,不断完善 目前直接复制粘贴过来的,后 ...

  8. Csrf_token ||| CSRF跨站请求伪造

    # 注: 部分内容参考网上,侵删   CSRF(Cross-site request forgery) 跨站请求伪造,是一种对网站的恶意利用  它会通过伪装成受信任用户的请求来利用受信任的网站来获取一 ...

  9. 使用axios获取本地json数据

    1. 通过搜索 网上说不放在static文件夹中会报错  但是一直报错  放到根目录下的时候不报错了 2. 在main.js中引入axios import axios from 'axios' 3. ...

  10. Django的forms表单组件批量设置字段样式

    from django import forms from . import models class UserInfoModelForms(forms.ModelForm): class Meta: ...