VC++中全局变量定义的问题(转)
- 格式:doc
- 大小:16.00 KB
- 文档页数:2
c语⾔全局变量和局部变量问题及解决汇总答:能,局部会屏蔽全局。
要⽤全局变量,需要使⽤"::"局部变量可以与全局变量同名,在函数内引⽤这个变量时,会⽤到同名的局部变量,⽽不会⽤到全局变量。
对于有些编译器⽽⾔,在同⼀个函数内可以定义多个同名的局部变量,⽐如在两个循环体内都定义⼀个同名的局部变量,⽽那个局部变量的作⽤域就在那个循环体内。
答:extern可以⽤引⽤头⽂件的⽅式,也可以⽤extern关键字,如果⽤引⽤头⽂件⽅式来引⽤某个在头⽂件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你⽤extern⽅式引⽤时,假定你犯了同样的错误,那么在编译期间不会报错,⽽在连接期间报错。
答:可以,在不同的C⽂件中以static形式来声明同名全局变量。
可以在不同的C⽂件中声明同名的全局变量,前提是其中只能有⼀个C⽂件中对此变量赋初值,此时连接不会出错static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。
全局变量本⾝就是静态存储⽅式,静态全局变量当然也是静态存储⽅式。
这两者在存储⽅式上并⽆不同。
这两者的区别虽在于⾮静态全局变量的作⽤域是整个源程序,当⼀个源程序由多个源⽂件组成时,⾮静态的全局变量在各个源⽂件中都是有效的。
⽽静态全局变量则限制了其作⽤域,即只在定义该变量的源⽂件内有效,在同⼀源程序的其它源⽂件中不能使⽤它。
由于静态全局变量的作⽤域局限于⼀个源⽂件内,只能为该源⽂件内的函数公⽤,因此可以避免在其它源⽂件中引起错误。
从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储⽅式即改变了它的⽣存期。
把全局变量改变为静态变量后是改变了它的作⽤域,限制了它的使⽤范围。
static函数与普通函数作⽤域不同,仅在本⽂件。
只在当前源⽂件中使⽤的函数应该说明为内部函数(static),内部函数应该在当前源⽂件中说明和定义。
CC++语⾔中全局变量重复定义问题的解决⽅法前⾔在C语⾔中使⽤extern 关键字来定义全局变量的时候,我们需要在.h⽂件和.c⽂件中重复定义,这种重复,导致了出错⼏率的增加。
今天,在整理⾃⼰的代码的时候,考虑到我写的代码从⼀⾄终都是在⼀个cpp⽂件⾥⾯。
于是,想把⾃⼰的代码中的各个模块分离开来,以便更好地阅读和管理。
遇到的问题我的做法是:宏定义、结构体定义、函数声明以及全局变量定义放到⼀个head.h头⽂件中函数的定义放到head.cpp中main函数放到main.cpp中然⽽却报错了,提⽰xxx变量在*.obj⽂件中已定义问题出现的原因为什么会出现这种情况呢?⾸先单个⽂件的编译是独⽴的。
在head.cpp编译到head.obj,main.cpp编译到main.obj。
这个过程没有报错,也就是说明编译过程是没有问题的。
接下来是obj的链接。
在链接main.obj与head.obj的时候,此时编译器发现head.obj为这些全局变量分配了内存空间,⽽在main.obj中也为这些全局变量分配了内存空间。
同样⼀个变量却出现了两个不同的内存地址。
于是编译器报错。
不是办法的办法把head.h⾥⾯的头⽂件的全局变量都加上static。
编译便可通过,可是却会不经意出现了其他问题。
static只是把变量的⽣存周期延长,同时也把该变量限定于当前的⽂件。
⽽之所以能⽤于main.cpp中,是因为在编译的时候复制了⼀个变量名相同的变量给main.cpp⽽已。
那么main.cpp⾥⾯的“全局变量”的改变,并不能改变原来head.h⾥⾯的全局变量的值。
这样⼦虽然编译通过了,但是程序是错误的。
真正的解决⽅法把全局变量定义放到head.cpp⽂件中。
在head.h存放全局变量的声明,同时每个声明前⽤ extern 去修饰。
我的个⼈想法我觉得为了能更加分离全局变量,可以做的⼀个做法是:全局变量定义依旧放在head.cpp中。
新建⼀个global.h的头⽂件,存放全局变量的声明,同时每个声明前⽤ extern 去修饰。
C语言全局变量定义方法在C语言中,全局变量是在函数外部定义的变量,它可以被整个程序的各个函数访问和使用。
全局变量的作用范围是整个程序,在程序中任何地方都可以使用。
全局变量的定义方式有以下几种:1.在函数外部定义全局变量:```int globalVar; // 声明一个全局变量```这种方法将全局变量的定义放在所有函数的外部,可以在程序中的任何位置对其进行访问和使用。
全局变量在没有被初始化时,默认值为0。
2.在函数外部定义全局变量并初始化:```int globalVar = 100; // 声明并初始化一个全局变量```这种方法在定义全局变量的同时可以进行赋值初始化,全局变量的初始值可以根据需要自行设定。
3.在头文件中定义全局变量:除了在函数外部定义全局变量之外,还可以创建一个头文件,然后在需要使用全局变量的源文件中包含这个头文件,即可实现全局变量的共享。
在头文件中定义全局变量的步骤如下:a. 在一个头文件(例如global.h)中声明全局变量:```extern int globalVar; // 声明一个全局变量```注意使用`extern`关键字来修饰全局变量,表示该变量的定义在其他源文件中。
b.在需要使用全局变量的源文件中包含头文件:```#include "global.h"```通过包含头文件,就可以在源文件中访问和使用全局变量。
4. 使用static关键字定义全局变量:通过使用`static`关键字可以定义静态全局变量,静态全局变量的作用范围也是整个程序,但其作用范围被限制在定义它的源文件中。
静态全局变量的定义和普通全局变量的定义类似,只需要在声明时加上static 关键字即可:```static int globalVar; // 声明一个静态全局变量```静态全局变量只能在定义它的源文件中使用,其他源文件无法访问和使用。
需要注意的是,全局变量的使用应尽量减少,并且在使用时要小心。
关于c++中的全局变量(不赋值的全局变量算定义)定义有三种:1.不赋值的定义:int a;2.赋值的定义:int a=5; 或者 int a;a=5;3.加extern的定义:extern int a=5;//其实和不加是⼀样的。
声明只有⼀种:extern int a;所有,不要再问我变量不赋值算不算定义,告诉你,算,你要是敢包含两次不赋值的变量的头⽂件两次,编译器就敢报错,重定义c++单定义语法规则:变量只能定义⼀次。
定义与声明的区别:定义:声明⼀个变量,且为它分配内存空间。
声明:只声明⼀个变量,并不为它分配内存空间。
因此定义变量的过程已经声明了这个变量。
定义变量的⽅法:int a;//定义⼀个变量a,并且分配了内存空间,值为0(虽然没有显⽰为变量a提供值,但是编译器已经为a分配了内存空间,且赋值为0)int a=5;//定义变量a,并赋值为5(显⽰的赋值为5)extern int a=5;//虽然加上了extern关键字,但是由于显⽰的赋值了,所以仍然是定义。
那如何只声明变量呢?extern int a;//extern关键字表⽰变量a已经在别处定义了,这⾥需要使⽤,就声明⼀下。
这也是说要使⽤全局变量,必须要提前声明⼀下。
因此全局变量使⽤规则为:1.在define.cpp⽂件中定义变量//define.cpp[extern] int a=3;//在⽂件define.h中定义⼀个全局变量a,赋值为3.(extern关键字可以有,也可以没有)2.在define.h⽂件中声明变量extern int a;3.在⽤户⽂件中引⽤变量//user.h⽅法⼀:#include "define.h" //包含⽤extern声明的全局变量的⽂件(因为已经声明了,这⾥包含⼀下就可以了)或者⽤extern关键字声明⽅法⼆:extern int a; //2.必须声明已经定义了的变量a,这⾥没有给a分配内存,⽽是对外部定义好的a的引⽤;4.使⽤全局变量a+=1; //3.使⽤全局变量。
already defined in *.obj 符“号已定义”问题原理及解决方案VC6 如果想在 stdafx.h 中定义全局变量,由于该头文件会被include 多次,所以,经常会出现以下经典的错误:already defined in StdAfx.obj 。
解决方法:把该变量的定义int g_flag 放到 stdafx.cpp 中,然后在使用的地方extern 一下。
假如你在CAADlg.cpp 中使用了该变量g_flag ,那么就在CAADlg.cpp 的首部,构造函数的定义之外,添加上extern int g_flag;许多 Visual C++ 的使用者都碰到过LNK2005:symbol already defined 和LNK1169:one or more multiply defined symbols found 这样的链接错误,而且通常是在使用第三方库时遇到的。
对于这个问题,有的朋友可能不知其然,而有的朋友可能知其然却不知其所以然,那么本文就试图为大家彻底解开关于它的种种疑惑。
大家都知道,从C/C++ 源程序到可执行文件要经历两个阶段:(1)编译器将源文件编译成汇编代码,然后由汇编器 (assembler) 翻译成机器指令 (再加上其它相关信息 )后输出到一个个目标文件(object file,VC 的编译器编译出的目标文件默认的后缀名是 .obj) 中;(2) 链接器 (linker) 将一个个的目标文件 (或许还会有若干程序库 )链接在一起生成一个完整的可执行文件。
编译器编译源文件时会把源文件的全局符号(global symbol) 分成强 (strong) 和弱 (weak) 两类传给汇编器,而随后汇编器则将强弱信息编码并保存在目标文件的符号表中。
那么何谓强弱呢?编译器认为函数与初始化了的全局变量都是强符号,而未初始化的全局变量则成了弱符号。
比如有这么个源文件:extern int errorno;int buf[2] = {1,2};int *p;int main(){return 0;}其中 main 、 buf 是强符号, p 是弱符号,而 errorno 则非强非弱,因为它只是个外部变量的使用声明。
c++定义全局变量详解在C++中定义全局变量是应该尽量在.cpp⽂件中定义,⽽不要在.h ⽂件中定义,定义好了之后,可以在.h⽂件中利⽤extern关键字进⾏声明。
如果在.h⽂件中定义的话,多层包含可能会引起重复定义的错误。
下⾯是⼀个⽰例:在g_bash.cpp中定义全局变量:// g_bash.cpp#include "g_base.h"int g_TicketCount = 0; // 定义全局变量并初始化在g_bash.h⽂件中利⽤extern关键字进⾏声明:// g_bash.h#ifndef G_BASE_H#define G_BASE_Hextern int g_TicketCount; // 全局变量声明#endif // G_BASE_H然后在其他⽂件要使⽤这些变量的时候,只要#include "g_base.h"就可以了,⽽且不会引起重复定义的错误。
main.cpp下引⽤⽰例:#include <QCoreApplication>#include <iostream>#include g_base.husing namespace std;void proc(){cout<< proc(): <<endl;g_TicketCount++;}int main(int argc, char *argv[]){QCoreApplication a(argc, argv);cout<< g_TicketCount = << g_TicketCount << endl;proc();cout<< g_TicketCount = << g_TicketCount << endl;return a.exec();}结果:总结本篇⽂章就到这⾥了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!。
头文件定义全局变量等问题全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?可以,在不同的C文件中以static形式来声明同名全局变量。
头文件中不可以直接定义变量和函数,但是可以定义static变量,类。
extern 用法,全局变量与头文件(重复定义)用#include可以包含其他头文件中变量、函数的声明,为什么还要extern关键字,如果我想引用一个全局变量或函数a,我只要直接在源文件中包含#include<xxx.h> (xxx.h包含了a的声明)不就可以了么,为什么还要用extern 呢??这个问题一直也是似是而非的困扰着我许多年了,今天上网狠狠查了一下总算小有所获了:头文件首先说下头文件,其实头文件对计算机而言没什么作用,她只是在预编译时在#include的地方展开一下,没别的意义了,其实头文件主要是给别人看的。
我做过一个实验,将头文件的后缀改成xxx.txt,然后在引用该头文件的地方用#include"xxx.txt"编译,链接都很顺利的过去了,由此可知,头文件仅仅为阅读代码作用,没其他的作用了!不管是C还是C++,你把你的函数,变量或者结构体,类啥的放在你的.c或者.cpp 文件里。
然后编译成lib,dll,obj,.o等等,然后别人用的时候最基本的gcc hisfile.cpp yourfile.o|obj|dll|lib 等等。
但对于我们程序员而言,他们怎么知道你的lib,dll...里面到底有什么东西?要看你的头文件。
你的头文件就是对用户的说明。
函数,参数,各种各样的接口的说明。
那既然是说明,那么头文件里面放的自然就是关于函数,变量,类的“声明”了。
记着,是“声明”,不是“定义”。
那么,我假设大家知道声明和定义的区别。
所以,最好不要傻嘻嘻的在头文件里定义什么东西。
比如全局变量: #ifndef _XX_头文件.H#define _XX_头文件.H int A; #endif 那么,很糟糕的是,这里的int A是个全局变量的定义,所以如果这个头文件被多次引用的话,你的A会被重复定义显然语法上错了。
c语音中全局变量的名词解释C语言中全局变量的名词解释在C语言中,全局变量是指在程序的各个函数之外定义的变量。
它拥有全局的作用域,因此可以在程序的任何地方使用。
全局变量与局部变量相对,局部变量只能在其所属的函数内部使用。
全局变量具有以下特点:1. 可访问性:全局变量可以被程序中的任何函数访问和修改。
这意味着它可以在不同的函数中共享数据,方便数据的传递和共享。
2. 生命周期:全局变量在程序开始执行时被创建,在程序结束时才被销毁。
这意味着全局变量的生存周期与整个程序的生命周期一致,可以在程序的不同阶段保持数据的持久性。
3. 默认初始化:全局变量在定义时会被默认初始化。
根据类型的不同,全局变量的默认初始值可以是0、NULL或空字符串等。
全局变量的定义方式如下:```type variable_name;```其中,type表示变量的类型,variable_name表示变量的名称。
全局变量的定义通常会放在函数之外,以便于所有函数都能访问。
举例来说,我们可以定义一个全局变量来保存程序的执行次数:```c#include <stdio.h>int execution_count; // 全局变量void increment_execution_count() {execution_count++; // 在函数中使用全局变量}int main() {execution_count = 0; // 初始化全局变量increment_execution_count();printf("程序已执行 %d 次\n", execution_count);return 0;}```在上面的例子中,我们定义了一个整型的全局变量`execution_count`,并在`increment_execution_count()`函数中对其进行累加操作。
在`main()`函数中,我们将全局变量初始化为0,然后调用`increment_execution_count()`函数对其进行累加,并最终将结果打印出来。
c语⾔头⽂件中定义全局变量的问题问题是这么开始的:最近在看⼀个PHP的扩展源码,编译的时候的遇到⼀个问题:ld: 1 duplicate symbol for architecture x86_64仔细看了⼀下源码,发现在头⽂件中出现了全局变量的定义。
简化⼀下后,可以这么理解:// t1.h#ifndef T1_H#define T1_Hint a = 0;#endif//------------------//t1.c#include "t1.h"#include "t2.h"int main(){return 0;}//-----------------//t2.h#include "t1.h"//empty//----------------//t2.c#include "t2.h"//empty//-------这两个c⽂件能否通过编译?想必有点经验的必会说不会,重定义了。
那么是否真的如此?并不这么简单。
第⼀个问题,#ifndef 的这个宏是否防⽌了重定义(redefinition)?答案:是。
但是是在单个translation unit中(wiki )。
#ifndef 的头⽂件宏称为 include guards的()我们知道,⼀个完整的编译的过程是经过one.c --> PREPROCESSOR -> tmp.c(temporary) -> COMPILER -> one.obj -> LINKER -> one.exe这三个过程的,⽽在预编译阶段,便会把include的⽂件展开,我们使⽤cc -E 命令来查看t1.c的预编译的结果:➜ t cc -E t1.c# 1 "t1.c"# 1 "<built-in>" 1# 1 "<built-in>" 3# 321 "<built-in>" 3# 1 "<command line>" 1# 1 "<built-in>" 2# 1 "t1.c" 2# 1 "./t1.h" 1int a = 0;# 3 "t1.c" 2# 1 "./t2.h" 1# 4 "t1.c" 2int main(void){return 0;}看到编译器把 t1.h 做了展开,我们看到了 a的定义。
c语⾔中实现全局变量在⽤C语⾔编写程序的时候,我们常常想定义⼀个可以在不同.c⽂件中被使⽤的变量,以此来实现数据的传递。
但是这个变量定义的不对的话,就会在编译时出现编译错误,或者可以编译通过,但是没有实现变量在不同.c⽂件中实现共⽤。
正确的全局变量定义⽅式是这样的。
我们举例说明,项⽬⽂件夹project下有main.c、common.c和common.h三个⽂件,其中common.h⽂件分别#include在main.c和common.c ⽂件中。
现在希望声明⼀个字符型变量key,在main.c和common.c中公⽤。
使⽤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⽂件中定义,我这⾥只是在外部⽤它。
编译器就不给他分配内存空间,⽽等到真正遇到变量定义的时候再给他分配内存空间。
1、普通变量定义成全局变量如果是普通类型,完全可以不⽤*.h⽂件,直接在*.c⽂件中定义,在调⽤⽂件处⽤extern 声明,因为对于普通类型,编译器是可以识别的。
VC++中全局变量的问题(转)
/znsky/archive/2008/01/05/2026747.aspx
全局变量一般这样定义:
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()->成员”访问变量或函数。