当前位置:  编程技术>c/c++/嵌入式

基于C++全局变量的声明与定义的详解

    来源: 互联网  发布时间:2014-10-17

    本文导语:  (1)编译单元(模块)在VC或VS上编写完代码,点击编译按钮准备生成exe文件时,编译器做了两步工作:第一步,将每个.cpp(.c)和相应的.h文件编译成obj文件;第二步,将工程中所有的obj文件进行LINK,生成最终.exe文件。那么,...

(1)编译单元(模块)
在VC或VS上编写完代码,点击编译按钮准备生成exe文件时,编译器做了两步工作:
第一步,将每个.cpp(.c)和相应的.h文件编译成obj文件;
第二步,将工程中所有的obj文件进行LINK,生成最终.exe文件。
那么,错误可能在两个地方产生:
一个,编译时的错误,这个主要是语法错误;
一个,链接时的错误,主要是重复定义变量等。
编译单元指在编译阶段生成的每个obj文件。
一个obj文件就是一个编译单元。
一个.cpp(.c)和它相应的.h文件共同组成了一个编译单元。
一个工程由很多编译单元组成,每个obj文件里包含了变量存储的相对地址等。
(2)声明与定义
函数或变量在声明时,并没有给它实际的物理内存空间,它有时候可保证你的程序编译通过;
函数或变量在定义时,它就在内存中有了实际的物理空间。

如果你在编译单元中引用的外部变量没有在整个工程中任何一个地方定义的话,那么即使它在编译时可以通过,在连接时也会报错,因为程序在内存中找不到这个变量。
函数或变量可以声明多次,但定义只能有一次。
(3) extern作用
作用一:当它与"C"一起连用时,如extern "C" void fun(int a, int b);,则编译器在编译fun这个函数名时按C的规则去翻译相应的函数名而不是C++的。
作用二:当它不与"C"在一起修饰变量或函数时,如在头文件中,extern int g_nNum;,它的作用就是声明函数或变量的作用范围的关键字,其声明的函数和变量可以在本编译单元或其他编译单元中使用。
即B编译单元要引用A编译单元中定义的全局变量或函数时,B编译单元只要包含A编译单元的头文件即可,在编译阶段,B编译单元虽然找不到该函数或变量,但它不会报错,它会在链接时从A编译单元生成的目标代码中找到此函数。
(4)全局变量(extern)
有两个类都需要使用共同的变量,我们将这些变量定义为全局变量。比如,res.h和res.cpp分别来声明和定义全局变量,类ProducerThread和ConsumerThread来使用全局变量。(以下是QT工程代码)
代码如下:

/**********res.h声明全局变量************/ 
#pragma once 

#include  

const int g_nDataSize = 1000; // 生产者生产的总数据量 
const int g_nBufferSize = 500; // 环形缓冲区的大小 

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  
ConsumerThread::ConsumerThread(QObject* parent) 
: QThread(parent) { 

ConsumerThread::ConsumerThread() { 


ConsumerThread::~ConsumerThread() { 

void ConsumerThread::run() { 
 for (int i = 0; i < g_nDataSize; i++) { 
  g_qsemUsedBytes.acquire();
  qDebug()

    
 
 

您可能感兴趣的文章:

  • c++作用域运算符用法(全局变量和局部变量)
  • 不同C++源文件中共享同一个全局变量
  • 全局结构体变量和全局结构体指针变量
  • static全局变量与普通的全局变量的区别详细解析
  • 在一个进程中我定义了几个全局变量,然后我又fork了几个子进程,子进程中是否可以各自对全局变量进行修改,如果各子进程都对其进行修改,
  • 在JBUILDER中如何使用全局变量,最好举一个例子。我也不知道在哪里定义全局变量?
  • 动态库中的变量(全局和自动变量)在什么地方存储,内存在什么位置分配?
  • linux动态链接库里全局变量和静态变量会导致动态库不可重入吗?
  • Java中怎样定义全局变量???
  • PHP 超全局变量库 superGlobals
  • 网卡驱动使用全局变量
  • PHP static局部静态变量和全局静态变量总结
  • 多进程中的全局变量问题,多谢帮忙!!!!
  • linux内核怎么定义汇编全局变量及在c文件中使用这个变量?有关0。11下的字符回显
  • linux中大量的全局变量怎么体现结构化的程序设计?
  • 求解关于全局变量的问题
  • 条件编译可以使用全局变量吗?
  • 如何不通过全局变量和静态变量与模态对话框进行数据交换?
  • C# 全局变量的学习小结
  • 除了全局变量,线程还可以通过哪些方法向定时器传递数据?
  • jsp中怎样定义全局变量
  • 问一个c语言问题:变长数组与全局变量
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • GNOME全局菜单 gnome2-globalmenu
  • 全局路径匹配 GPAMatching
  • asp.net读取本地与全局资料文件的代码
  • 全局唯一ID生成服务 snowflake
  • 如何使连接池成为全局的?
  • 请问,uboot的命令函数,能否调用全局变量
  • JQuery中使用Ajax赋值给全局变量失败异常的解决方法
  • 传说很难的一个问题--全局变量问题
  • 模块编程中对内核全局变量引用的问题
  • linux内核全局变量定义问题!
  • debian下用脚本设置 全局变量的问题
  • 建一个linux共享库(.so.x.x文件)里边包含类、全局变量,结构体等
  • QT下如何定义全局变量
  • 全局变量问题求助
  • JQuery中使用Ajax赋值给全局变量异常的解决方法
  • 全局脚本是何文件?
  • 一个简单的全局变量的问题
  • 如何用c实现生成一个类似windows下uuid的全局唯一串的算法
  • java的应用程序中如何定义一个全局变量,在程序的任何地方都可以修改使用?
  • 怎么把一个命令设为全局可见的呢?




  • 特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3