C++中全局变量的声明和定义
原文链接:http://blog.csdn.net/candyliuxj/article/details/7853938
(1)编译单元(模块)
在VC或VS上编写完代码,点击编译按钮准备生成exe文件时,编译器做了两步工作:
第一步:将每个.cpp和相应的.h文件编译成obj文件;
第二步:将工程所有的obj文件进行Link,生成最终的.exe文件。
这样,错误可能在两个地方产生:
一个是在编译的时候发生的错误,主要是语法错误;
一个是在链接的时候的错误,主要是重复定义变量等。
编译单元指在编译阶段生成的每个obj文件。
一个obj文件就是一个编译单元。
一个.cpp和它对应的.h文件共同组成了一个编译单元。
一个工程由很多编译单元组成,每个obj文件里包含了变量存储的相对地址等。
(2)变量的声明与定义
函数或变量在声明时,并没有给它实际的物理内存空间,它有时候可保证你的程序编译通过;函数或变量在定义时,它就在内存中有了实际的物理空间。
如果你在编译单元中引用的外部变量没有在整个工程中任何一个地方定义的话,那么即使它在编译时可以通过,在链接时也会报错,因为程序在内存中找不到这个变量。
函数或变量可以声明多次,但定义只能一次。
(3)extern的作用
/**********res.h声明全局变量************/
#pragma once #include <QSemaphore> const int g_nDataSize = ; // 生产者生产的总数据量
const int g_nBufferSize = ; // 环形缓冲区的大小 extern char g_szBuffer[]; // 环形缓冲区
extern QSemaphore g_qsemFreeBytes; // 控制环形缓冲区的空闲区(指生产者还没填充数据的区域,或者消费者已经读取过的区域)
extern QSemaphore g_qsemUsedBytes; // 控制环形缓冲区中的使用区(指生产者已填充数据,但消费者没有读取的区域)
/**************************/
上述代码中g_nDataSize、g_nBufferSize为全局常量,其他为全局变量。
/**********res.cpp定义全局变量************/
#pragma once
#include "res.h" // 定义全局变量
char g_szBuffer[g_nBufferSize];
QSemaphore g_qsemFreeBytes(g_nBufferSize);
QSemaphore g_qsemUsedBytes;
/**************************/
在其他编译单元中使用全局变量时只要包含其所在头文件即可。
/**********类ConsumerThread使用全局变量************/
#include "consumerthread.h"
#include "res.h"
#include <QDebug> ConsumerThread::ConsumerThread(QObject* parent)
: QThread(parent) { } ConsumerThread::ConsumerThread() { } ConsumerThread::~ConsumerThread() { } void ConsumerThread::run() {
for (int i = ; i < g_nDataSize; i++) {
g_qsemUsedBytes.acquire();
qDebug()<<"Consumer "<<g_szBuffer[i % g_nBufferSize];
g_szBuffer[i % g_nBufferSize] = ' ';
g_qsemFreeBytes.release(); }
qDebug()<<"&&Consumer Over";
}
/**************************/
/***********res.h**********/
static char g_szBuffer[] = "";
void fun();
/************************/
/***********res.cpp**********/
#include "res.h"
#include <iostream>
using namespace std; void fun() {
for (int i = ; i < ; i++) {
g_szBuffer[i] = 'A' + i;
}
cout<<g_szBuffer<<endl;
}
/************************/
/***********test1.h**********/
void fun1();
/************************/
/***********test1.cpp**********/
#include "test1.h"
#include "res.h"
#include <iostream>
using namespace std; void fun1() {
fun(); for (int i = ; i < ; i++) {
g_szBuffer[i] = 'a' + i;
}
cout<<g_szBuffer<<endl;
}
/************************/
/***********test2.h**********/
void fun2();
/************************/
/***********test2.cpp**********/
#include "test2.h"
#include "res.h"
#include <iostream>
using namespace std; void fun2() {
cout<<g_szBuffer<<endl;
}
/************************/
/***********main.cpp**********/
#include "test1.h"
#include "test2.h" int main() {
fun1();
fun2(); system("PAUSE");
return ;
}
/************************/
运行结果如下:

extern const char g_szBuffer[]; //写入 .h中
const char g_szBuffer[] = ""; // 写入.cpp中
C++中全局变量的声明和定义的更多相关文章
- C++全局变量的声明和定义
(1)编译单元(模块) 在VC或VS上编写完代码,点击编译按钮准备生成exe文件时,编译器做了两步工作: 第一步,将每个.cpp(.c)和相应的.h文件编译成obj文件: 第二步,将工程中所有 ...
- 【C++】C++中变量的声明与定义的区别
声明(declaration):意味着告诉编译器关于变量名称.变量类型.变量大小.函数名称.结构名称.大小等等信息,并且在声明阶段不会给变量分配任何的内存. 定义(definition):定义就是在变 ...
- 今天才知道原来我还没弄清楚js中全局变量和局部变量的定义...
查资料看到这段还不错,来源:原文:https://blog.csdn.net/czh500/article/details/80429133 粘过来记录一下... 1.使用var声明变量,在方法内部是 ...
- 变量声明和定义及extern 转载
在讨论全局变量之前我们先要明白几个基本的概念: 1. 编译单元(模块): 在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LINK ER ...
- 关于C++的变量和类的声明和定义
什么是变量?变量或者叫对象,是一个有具名的.可以供程序操作的存储空间.这里具名是指变量是有名字的,可供操作是指能进行加减乘除或者输入输出等操作,存储空间则是指有一块属于它的内存空间. 为了便于说明,标 ...
- 多个".h"文件中声明及定义 全局变量和函数
一.".h"文件必须以如下格式书写 例:文件<CZ_efg_hi.h"> ------------文件内容----------- #ifndef CZ_Efg ...
- C++中重定义的问题——问题的实质是声明和定义的关系以及分离式编译的原理
这里的问题实质是我们在头文件中直接定义全局变量或者函数,却分别在主函数和对应的cpp文件中包含了两次,于是在编译的时候这个变量或者函数被定义了两次,问题就出现了,因此,我们应该形成一种编码风格,即: ...
- [转载]C++中声明与定义的区别
C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类的实现放在cpp文件中.它们为什么能够关联到一起呢?你知道什么东西可以放在.h文件中,什么不能.什么东西又可以放在cpp文件中.如果 ...
- MFC中全局变量的定义及使用
用MFC制作的工程由很多文件构成,它不能象一般C++程序那样随意在类外定义全局变量,在这里要想定义能被工程内多个文件共享的全局变量和函数必须用一些特殊方法才行.实际上有多种方法可以实现,这里只介绍两种 ...
随机推荐
- 紫书 习题 8-23 UVa 1623 (set妙用 + 贪心)
这道题我是从样例中看出思路了 2 4 0 0 1 1 看这组数据, 输出的是No, 为什么呢?因为两个1之间没有神龙喝水, 所以一定会有水灾. 然后就启发了我,两次同一个湖的降水之间必须至少有一次神龙 ...
- ASP.NET-ajax.BeginForm使用02
Ajax.BeginForm中OnFailure.Onsuccess.OnComplete函数是可以处理从后台返回的数据的,比直接使用jquery的$.ajax方法还要节约时间 @using( ...
- IntelliJ IDEA 进行Maven项目创建build
IntelliJ IDEA 进行Maven项目创建build 1,文件-新建-maven 项目:2,编写pom.xml文件:3,鼠标放到左下,然后选择Maven Projects,然后可以查看项目信息 ...
- leetCode(38):Lowest Common Ancestor of a Binary Search Tree
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...
- HDU 4965 Fast Matrix Calculation(矩阵高速幂)
HDU 4965 Fast Matrix Calculation 题目链接 矩阵相乘为AxBxAxB...乘nn次.能够变成Ax(BxAxBxA...)xB,中间乘n n - 1次,这样中间的矩阵一个 ...
- Precision and recall From Wiki
Precision.全部推断为正样本的数量里面,有多少是真正的正样本.就是精确率 Recall.所有的正样本里面,检測到了多少真正的正样本,又称查全率.即所有正样本查找到了多少的比率.
- 漫谈linux之文件IO篇(SSD写性能和机械硬盘差不多,读是4到10倍)
前同事的文章,觉得写得很清晰,收藏了. http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的东西,技术 ...
- OpenGL编程(四)改变窗口大小时保持图形的原形
前面的例子,当我们通过拖拉的方法改变窗口的长宽比例时,窗口里的图形的长宽也相应地伸缩,导致图形变形.如下图: 正如上图所示,当我们把窗口宽度拉长后,图形就会显得比较胖.同样,当我们把窗口的高度拉长后, ...
- CentOS7-1810 系统Samba配置说明
Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件.SMB(Server Messages Block,信息服务块)通信协议是微软(Microsoft)和英特尔(Intel)在198 ...
- Linux 下易用的光盘镜像管理工具(虚拟光驱软件)转载
作者: Frazer Kline | 2014-11-23 11:07 评论: 4 收藏: 4 分享: 10 磁盘镜像包括了整个磁盘卷的文件或者是全部的存储设备的数据,比如说硬盘,光盘(DVD,C ...