全局变量的定义

全局变量一般这样定义:

1。在一类的.cpp中定义 int myInt;

然后再在要用到的地方的.cpp里extern int myInt;这样就可以用了。

 

2。在stdafx.cpp中加入:

int myInt;

然后在stdafx.h中加入:

extern int myInt

这样定义以后无论在什么文件中都是可见的.

 

3。比较规范的是,先定义一个Glbs.h,把所有的全局变量原始定义放进去。然后定义一个Externs.h,把你先前定义在Glbs.h中的变量都加上extern。注意:如果你在Glbs.h中设置了初值,那么在Externs.h中就不要加值了。然后调用时,第一次调用的#i nclude <Glbs.h>,以后调用的#i nclude <Externs.h>

 

另:

 

问:如何在VC++中使用全局变量,以使文档中的所有类都能访问。

  答:把该变量放到该应用程序类的头文件中的attribute处。然后,在程序的任何地方,你都可以用下面的方法来访问该变量:

  CMyApp *app=(CMyApp*)AfxGet-App();

  app->MyGlobalVariable=…

  用这个方法,不但可以定义全局变量,也可以定义全局对象。

  例如:

  MyClass MyObject;

  CMyApp*app=(CMyApp*)AfxGet-App();

  app->MyObject.MyFunction();

 

VC中使用全局变量的2种办法及防错措施 

 

1. 对于全局变量存在和函数一样的问题,为了在其他CPP文件中能够访问这些变量,必须在主文件的H文件中加上extern声明,格式如下:

extern varibletype var; (声明)

在主文件的CPP文件中定义

varibletype var; (定义)

例子:

AppWizard建立一个Test工程

那么在Test.h中声明extern CString cs;

在Test.app定义CString cs;

 

   如果要定义整个工程的全局变量,在任何一个CPP文件中进行定义,然后在需要引用这个变量的文件中进行声明。如全局变量很多可以选择使用定义全局变量的。h文件,在需要的地方直接include头文件即可,不需要写那么多extern了。

2.应用程序类的主头文件处定义变量varibletype var,然后,在程序的任何地方,都可以用下面的方法来访问该变量: 

  CClassApp *app=(CClassApp*)AfxGetApp(); 

  app->var=

 类似的,以上方法也可以定义全局对象

例子:

AppWizard建立一个Test工程

那么在Test.h中声明 CString cs;

使用的时候CTestApp *app=(CTestApp*)AfxGetApp(); 

    app->cs="Global"

 

防错措施:

若定义的函数和全局变量在多个文件包含且造成嵌套或多次调用的话,这样将导致这个头文件每被包含依次,函数或变量就被重新定义一次,在链接编译时会导致重定义错误。为此需要使用一种被称为Guard macro的技术来保证不出错。在一个头文件开头加上 

#ifndef   _MACRO_1_

#define   _MACRO_1_

在文件末尾增加 

#endif

 

 另外转一下一位朋友写的在MFC中定义全局变量

 

在MFC下如何定义全局变量和全局函数VC++

 

用MFC制作的工程由很多文件构成,它不能象一般C++程序那样随意在类外定义全局变量,在这里要想定义能被工程内多个文件共享的全局变量和函数必须用一些特殊方法才行。实际上有多种方法可以实现,这里只介绍两种方法。

 

一、在应用程序类中定义

 

用MFC生成的工程中都有一个名为CxxxApp的类,它派生于CWinApp类。这个类主要进行程序的初始化,生成文档、视图对象等工作。我们可以把需要全局访问的变量和函数定义为这个类的成员变量和成员函数,就可以实现全局访问了。

 

从严格意义上讲,这种变量和函数并不是全局的,因为它仍然只是类中的成员,只是由于我们很容易获得CxxxApp类的指针,所以我们可以在文档、视图、对话框以及各种自定义类中访问到它们,达到与全局变量类似的效果。访问时用函数“AfxGetApp()”获得CxxxApp类的指针,用“AfxGetApp()->成员”访问变量或函数。

 

例:

 

Test.h:(应用程序类头文件)

 

class CTestApp : public CWinApp

{

public:

int x; //全局变量

int f(int y); //全局函数

…………

};

Test.cpp:(应用程序类程序文件)

 

int CTestApp::f(int y) //全局函数定义

{

y++;

return y;

}

定义在CTestApp类中的变量和函数可以在其它类中被访问。比如在视图的某函数中要访问变量x和函数f():

 

void CTestView::xyz()

{

CTestApp *app = (CTestApp *)AfxGetApp(); //生成指向应用程序类的指针

app->x = 0; //访问变量x

int z = app->f(1); //访问函数f()

…………

}

这样,变量x和函数f()可以视作为全局的。

 

用这种方法实现的全局变量和全局函数虽比较简单,但也有缺点,一是访问不太方便,每次都需要获取应用程序类的指针;再就是把一些与应用程序类本身无关的变量和函数放在里面,使这个类看上去怪怪的,破坏了类的封装。

 

二、用静态变量和静态函数实现

 

全局变量和全局静态变量的区别

  1)全局变量是不显式用static修饰的全局变量,但全局变量默认是动态的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过extern 全局变量名的声明,就可以使用全局变量。

  2)全局静态变量是显式用static修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用extern声明也不能使用。 

 

很喜欢API函数的那种调用方法,不论在哪个类中只要用“::API函数”就可以调用了。合理利用静态类型(static)可以实现与此相似的全局变量和全局函数。

 

静态变量和静态函数有如下性质:

 

若在一个类中用关键字static声明数据成员,则这个数据成员就只存在一个拷贝,无论该类创建了多少个实例,它始终只存在一个,即使该类的实例一个也没创建,它也存在。

 

若在一个类中用关键字static声明函数,该函数可以用“类名::函数名”方式访问,无需引用该类的实例,甚至这个类的实例可以不存在。

 

利用这个性质实现的全局变量和函数使用起来很方便。

 

值得注意的是,全局变量和全局函数最好集中封装,不要在文档、视图等类内部定义,这样用起来才有全局的感觉。

 

例:

 

1、添加一个没有基类的新类,设类名起为CPublic,姑且称之为公用类

 

单击“Insert”菜单下的“New Class”命令,选择“Class type”为“Generic Class”,在“Name”栏中填入类名“CPublic”,单击“OK”,则新类建立完毕。

 

2、包含公用类的头文件,使各个类都能访问它

 

CPublic的头文件应包含在应用程序类的头文件中,这样在其它类中引用CPublic类时就不需要再包含了。

 

Test.h:(应用程序类头文件)

 

#include "Public.h" //包含公用类头文件

 

class CTestApp : public CWinApp

{

…………

};

3、在公用类中定义全局变量和全局函数,均使用static修饰,静态变量还必须在类外定义和初始化

 

Public.h:(公用类头文件)

 

class CPublic

{

public:

CPublic();

virtual ~CPublic();

 

public:

static int x; //全局变量

static int time; //全局变量

static int f(int y); //全局函数

…………

}

在公用类中对静态变量进行初始化和定义函数体:

 

Public.cpp:(公用类程序文件)

 

int CPublic::x = 0; //初始化全局变量

int CPublic::time; //定义全局变量

 

CPublic::CPublic()

{

 

}

 

CPublic::~CPublic()

{

 

}

 

int CPublic::f(int y) //全局函数,这里不要再加static

{

y++;

return y;

}

4、全局量的使用

 

使用变量:CPublic::变量名

 

使用函数:CPublic::函数()

 

如在视图的某函数中访问变量x和函数f():

 

void CTestView::xyz()

{

CPublic::x = 0; //访问变量x

CPublic::time = CPublic::f(1); //访问函数f()

…………

}

在其它类中访问x、time和f()的方法与此相同。

 

5、几点注意:

 

①由于静态量可独立于类存在,不需要生成CPublic类的实例。

 

②静态数据成员的定义和初始化必须在类外进行,如例中x的初始化;变量time虽然没有初始化,但也必须在类外进行定义。由于没有生成CPublic类的实例,所以它的构造函数和析构函数都不会被执行,在里面做什么工作都没有什么意义。

 

③如果静态函数需要访问CPublic类内的变量,这些变量也必须为静态的。因为非静态量在不生成实例时都不会存在。如:

 

class CPublic

{

public:

int x; //内部变量

static int f(int y) //全局函数

{

x++;

return x;

};

…………

};

这里x虽为类内成员,但如果不生成CPublic类的实例,就会出现函数f()存在,而变量x不存在的问题。

 

总之,用没有实例的类管理全局量是一个不错的选择,它具有集中管理,使用方便的好处。当然,除非特别必要,全局量还是少用为好,一个好的编程者决不会随意滥用全局量的,一个封装做得不好的程序,在修改维护时会让你吃足苦头。

<think>嗯,用户想了解全局变量定义和用法。首先,我得回忆一下全局变量的基本概念。全局变量是在整个程序中都有效的变量,可以在任何函数或模块中访问,对吧?那它的定义方法在不同编程语言里可能有所不同,比如C、Python或者JavaScript。 记得在C语言中,全局变量通常是在函数外部定义的,这样所有函数都能访问。比如在引用3里提到的例子,int g_nShape=0; 这样的定义。而Python的话,需要在函数内部用global关键字声明,像引用1里说的,函数里用global x来修改全局变量。 接下来,用户可能想知道如何正确使用全局变量。使用不当会导致代码难以维护,比如在多个地方修改同一个变量,容易引发bug。需要强调合理使用,避免滥用。比如在QT编程中,引用2提到在头文件里声明extern,然后在源文件里定义,这样其他文件就能用了。 还要注意不同语言的作用域规则。比如JavaScript的全局变量是挂在window对象上的,而模块化开发中可能用闭包来避免污染全局空间。像Node.js中用global对象,或者ES6的模块作用域。 可能用户会遇到的问题包括变量命名冲突、意外的修改,这些都要提醒。另外,多线程环境下全局变量的同步问题,比如加锁机制,引用4里提到的STM32多文件定义方法,可能涉及到硬件编程中的注意事项。 最后,生成相关问题的时候,要覆盖定义方法、优缺点、语言差异、多线程和替代方案,这样用户能全面了解。还要确保引用正确的来源,比如Python的问题对应引用1,C语言对应3和4,QT对应2。 总结一下,回答的结构应该先定义,再使用方法,分语言讲解,注意事项,最后应用场景。这样用户能一步步理解全局变量的核心知识点。</think>### 全局变量定义与使用详解 #### 一、全局变量定义 全局变量是在程序的**整个作用域**内均可访问的变量,其生命周期从程序启动到结束。定义方式因编程语言而异: 1. **C语言**:在函数外部直接定义 ```c int global_var = 10; // 文件作用域的全局变量 ``` 跨文件使用时需配合`extern`声明(见引用[3][^3]): ```c extern int global_var; // 其他文件中声明 ``` 2. **Python**:在函数外定义,函数内通过`global`关键字声明修改(引用[1][^1]): ```python x = 10 def func(): global x x = 20 ``` 3. **JavaScript**:直接定义或通过`window`对象: ```javascript var globalVar = "data"; // 浏览器环境 window.globalVar = "data"; // 显式声明 ``` #### 二、全局变量的使用方法 1. **跨模块共享数据**(引用[2][^2]): - 在头文件`global.h`中声明: ```cpp extern QString appConfig; ``` - 在源文件`global.cpp`中定义: ```cpp QString appConfig = "default"; ``` 2. **硬件编程场景**(引用[4][^4]): ```c // SlaveMap.h extern uint8_t SlaveMap[32]; // SlaveMap.c uint8_t SlaveMap[32] = {0}; ``` 3. **状态跟踪**: ```python game_score = 0 # 跟踪游戏得分 def add_score(): global game_score game_score += 10 ``` #### 三、注意事项 1. **命名规范**:建议加`g_`或`global_`前缀(如`g_nShape`) 2. **线程安全**:多线程环境需加锁保护 3. **耦合度控制**:过度使用会降低代码可维护性 4. **初始化问题**:C语言中未初始化的全局变量默认为0 #### 四、应用场景 1. 程序配置参数(如QT的界面设置) 2. 硬件寄存器映射(STM32开发[^4]) 3. 游戏状态管理(俄罗斯方块形状记录[^3]) 4. 跨模块通信桥梁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值