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++程序那样随意在类外定义全局变量,在这里要想定义能被工程内多个文件共享的全局变量和函数必须用一些特殊方法才行.实际上有多种方法可以实现,这里只介绍两种 ...
随机推荐
- Beat 'Em Up Game Starter Kit (横版格斗游戏) cocos2d-x游戏源代码
浓缩精华.专注战斗! 游戏的本质是什么?界面?养成?NoNo! 游戏来源于对实战和比赛的模拟,所以它的本源就是对抗.就是战斗! 是挥洒热血的一种方式! 一个游戏最复杂最难做的是什么?UI?商城? ...
- android 自己定义dialog并实现失去焦点(背景透明)的功能
前言:因为在项目中须要用到更新显示动画的需求,所以想到了dialog,自己定义dialog不难.网上教程非常多,可是在实现dialog背景透明的需求时,遇到了一点问题.网上的一些方法在我的机器上并没有 ...
- js如何实现简繁体互转
js如何实现简繁体互转 一.总结 一句话总结:其实无论是简体还是繁体,都是在显示端(前端),其实所有的我只用动js就好了,没必要动php. 当然,后端也可以做前端的事情,只是麻烦了点(要多通信两次,第 ...
- word 的使用 —— 分页符与分节符
节的概念:节定义了一些格式, 如页边距.页面的方向.页眉和页脚,以及页码的顺序. 分节符是指为表示节的结尾插入的标记. 分节符的作用: 分节符起着分隔其前后文本格式的作用,如果删除了某个分节符,它前面 ...
- js运算符单竖杠“|”与“||”的用法和作用介绍
在js开发应用中我们通常会碰到“|”与“||”了,那么在运算中“|”与“||”是什么意思呢? 在js整数操作的时候,相当于去除小数点,parseInt.在正数的时候相当于Math.floor(), ...
- AES简单加密解密的方法实现
package com.mstf.aes; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyEx ...
- PostgreSQL服务器存储参数的内部查看方法和实际表述之间的关系
postgres=# show wal_buffers ; wal_buffers ------------- 4MB(1 row) postgres=# show port; port ------ ...
- benchmark测试PostgreSQL数据库OLTP性能
1,安装配置PostgreSQL数据库 2,下载地址:http://sourceforge.net/projects/benchmarksql/?source=navbar Required:JDK7 ...
- C++笔试专题一:运算符重载
一:下面重载乘法运算符的函数原型声明中正确的是:(网易2016校招) A:MyClass operator *(double ,MyClass); B:MyClass operator *(MyCla ...
- 一个icon的选中与不选中
页面的样式展示 1.页面中选中的状态 2.页面中未选中的状态 3.俩个icon代表的状态 页面的布局展示 <label> <i class="iconfont icon-d ...