C语言extern作用(全局变量)
用C语言编写程序的时候,我们经常会遇到这样一种情况:希望在头文件中定义一个全局变量,然后包含到两个不同的c文件中,希望这个全局变量能在两个文件中共用。
举例说明:项目文件夹project下有main.c、common.c和common.h三个文件,其中common.h文件分别#include在main.c和common.c文件中。现在希望声明一个字符型变量key,在main.c和common.c中公用。如下图所示:
有人想,既然是想两个文件都用,那就在common.h中声明一个unsigned char key,然后由于包含关系,在main.c和common.c中都是可见的,所以就能共用了。
这种想法其实是很多初学者都会想到的,想起来确实有道理,但是实际写出来,我们发现编译的时候编译器提示出错,一般提示大概都类似于:Error: L6200E: Symbol key multiply defined (by common.o and main.o). 也就是说编译器认为我们重复定义了key这个变量。这是因为#include命令就是原封不同的把头文件中的内容搬到#include的位置,所以相当于main.c和common.c中都执行了一次unsigned char key,而C语言中全局变量是项目内(或者叫工程内)可见的,这样就造成了一个项目中两个变量key,编译器就认为是重复定义。
正确的解决办法:使用extern关键字来声明变量为外部变量。具体说就是在其中一个c文件中定义一个全局变量key,然后在另一个要使用key这个变量的c文件中使用extern关键字声明一次,说明这个变量为外部变量,是在其他的c文件中定义的全局变量。请注意我这里的用词:定义和声明。例如在main.c文件中定义变量key,在common.c文件中声明key变量为外部变量,这样这两个文件中就能共享这个变量key了,如下图所示。
代码如下(只写跟我们所说问题有关的部分):
(1)main.c文件
#include "common.h"
unsigned char key;
(2)common.c文件:
#include "common.h"
extern unsigned char key;
很多人看了可能糊涂,这里稍微说一下,其实就是变量定义和变量声明的区别,变量定义使用“数据类型+变量名称”的形式,编译器需要给他分配内存单元的;而变量声明使用“extern 变量类型+变量名称”的形式,是告诉编译器我这个变量将在其他外部c文件中定义,我这里只是在外部用它。编译器就不给他分配内存空间,而等到真正遇到变量定义的时候再给他分配内存空间。
由于很多人从开始学C语言就一直把定义变量叫声明变量,一开始就叫错了,所以导致现在分不清定义和声明的区别。要是还理解不了就想想函数的定义和声明,函数定义是编写函数功能实体,编译器要编译这个函数并且要分配内存空间,而函数声明并不生成函数功能实体,只是告诉编译器这是个函数,这个函数在后面将会定义实体,我这里只是提前用,编译器就会接着继续往下编译,如果子函数写在main函数之后,那么声明是必须的,如果不声明函数编译器都不知道这是个函数,编译就会报错。
C语言extern作用(全局变量)的更多相关文章
- C语言局部变量和全局变量问题汇总
1.局部变量能否和全局变量重名? 答:能,局部会屏蔽全局.要用全局变量,需要使用"::" 局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变 ...
- C语言中定义全局变量
(1)在C语言的头文件中定义变量出现的问题 最好不要傻嘻嘻的在头文件里定义什么东西.比如全局变量: /*xx头文件*/ #ifndef _XX_头文件.H #define _XX_头文件.H in ...
- C语言局部变量和全局变量的区别。——Arvin
局变量是使用相同的内存块在整个类中存储一个值. 全局变量的存在主要有以下一些原因: 1,使用全局变量会占用更多的内存(因为其生命期长),不过在计算机配置很高的今天,这个不成为什么问题,除非使用的是巨 ...
- IOS 基础-define、const、extern、全局变量
这里介绍一下define.const.extern的用法.优劣以及要注意的地方. 1.define 宏define是定义一个变量,没有类型信息.define定义的常量在内存中有若干个拷贝. defin ...
- 用extern定义全局变量
1.extern的作用 extern有两个作用,第一个,当它与"C"一起连用时,如: extern "C" void fun(int a, int b); 则告 ...
- C语言定义共享全局变量
好久没写C语言了,突然忘记怎么定义全局共享变量了,由于老项目的Code Base都是C的风格,其中又大量用了全局变量,只能跟着糊一坨shit上去了.没办法. 再共享全局变量的global_shared ...
- C语言extern关键字使用
在chinaunix上看见一篇转载的文章,觉得特别好,关于extern使用的解释: 参考链接:http://doc.chinaunix.net/CPP/201206/2248432.shtml 在C语 ...
- C static extern和全局变量
#include <stdio.h> //默认全局变量为外部变量 int a; //当全局变量前面加上static时,该变量为内部变量 static int b; void test(); ...
- 04、extern引用全局变量
这里强调一点就是关extern的声明: extern在声明中最主要的作用就是告诉编译器别的文件引用了全局变量XXXX. 举例: 有一个工程名字叫 Project1. Project1下面有两个.cpp ...
随机推荐
- myEclipse
破解myEclipse 建立一个java项目,将reg.java放入,并且运行在控制台 输入账户 回车就会出现 序列号 菜单栏--->myeclipse-->substription in ...
- [Appium] 使用Appium过程中遇到的各种坑
以下问题都是以ios为背景: 1. 问题: Case: 在页面S1上,点击元素A后,判读B元素是否出现. Detail:一开始通过Appium Inspector, 可以找到B元素,所以直接取该元素的 ...
- stl 存放对象析构问题
vector内数据使用结构体的话是深拷贝,vector内的数据会拷贝一份保存,vector内数据不会丢失.如果vector内数据是指针的话是进行浅拷贝,数据超出作用域后会自动析构,vector内所指向 ...
- Matrix的一些知识
1.什么是ColorMatrix ColorMatrix是一个颜色矩阵,它定义了一个 4*5 的float[]类型的矩阵 颜色矩阵,而图像的 RGBA 值则存储在一个5*1的颜色分量矩阵C中 所以为了 ...
- java使用xsd校验xml样例
知识点:XSD文件是指XML结构定义 ( XML Schemas Definition )文件,是DTD的替代品.可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其 ...
- string.Format 格式化输出日期
string.Format("{0:d}",System.DateTime.Now) 结果为:2009-3-20 (月份位置不是03) string.Format("{0 ...
- php 连接mongodb 增查改删操作
查询 <?php $m=new MongoClient('mongodb://admin:admin@localhost:27017/admin'); $db=$m->hndb; $cc= ...
- Java web--反射(解刨)
本质:先加载类 再解刨类的方法,字段,构造函数 目的:解刨出构造函数 为了new对象 解刨出字段 为了封装数据进去 解刨方法 ...
- modelsim(2) - vcd (dump, 查看,格式理解)
二 vcd dump 由于VCD可以用于做功耗分析,所以需要把其dump出来.另外VCD可以作为结果,也可以作为激励,但是实际看到的少啊! VCD是verilog的标准,所以有系统函数$dumpvar ...
- javascript高级程序设计--笔记01
概述 JavaScript的实现包含三个部分: 1 核心(ECMAScript) 提供核心语言功能 2 文档对象模型(DOM) 一套提供了访问以及操作网页内容的API 3 浏览器对象模型( ...