c++全局变量

本文深入探讨了C++中#ndefine宏的作用,特别是如何利用它来避免全局变量在不同编译单元中重复定义的问题。通过分析实例,解释了在头文件中仅进行声明而不定义全局变量的重要性,以及如何正确地引入和解决链接错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编译单元

每一个.cpp对应一个编译单元,当然包括其#include的头文件。


头文件中应该只包含声明,对应的.cpp文件放定义: extern


test1.h

#ifndef AAA
#define AAA

//上面的声明有什么用?
//若下面的函数fun()不为extern,则会在link阶段出错,显示main.obj中已经有了fun(),test.obj再重复就出错了。
void fun();
void fun2();

extern int a;


#endif


test1.cpp

#include "test1.h"
#include<iostream>

void fun()
{
	std::cout << "fun()\n";
}

void fun2()
{
	fun();
}

int a = 1;


main1.cpp

#include "test1.h"

int main()
{
	fun();
	return 0;
}


上面的test1.h只包含声明,如果在其中定义如 int a = 1; 那么将会产生链接错误。

在vs2010下错误如下

error C2374: 'a' : redefinition; multiple initialization

因为有2个.cpp文件,产生了2个编译单元,如果在.h定义了全局变量a的话,每个编译单元都包含一个a的符号变量,当链接时将在data segment产生同一个a变量,产生名字冲突。而只在.h中声明,如 extern int a;

那么可以看出只有在test1.cpp中有定义,那么只有test1.obj这个编译单元中有a这个符号,也就不会产生名字冲突。

可以查看test1.obj和main.obj, 只有test1.obj中有a这个符号。



///////////////////////////////////////////////////////
#ifndef 在上面例子中当在.h中有a的定义时为什么没有阻止每个编译单元都生成一个a

百度百科相关解释


详细讨论#ifndef的作用

  在c语言中,对同一个变量或者函数进行多次声明是不会报错的。所以如果h文件里只是进行了声明工作,即使不使用# ifndef宏定义,多个c文件包含同一个h文件也不会报错。
  但是在c++语言中,#ifndef的作用域只是在单个文件中。所以如果h文件里定义了全局变量,即使采用#ifndef宏定义,一个c文件包含同一个h文件多次还是会出现全局变量重定义的错误。
  使用#ifndef可以避免下面这种错误:如果在h文件中定义了全局变量,一个c文件包含同一个h文件多次,如果不加#ifndef宏定义,会出现变量重复定义的错误;如果加了#ifndef,则不会出现这种错误。

////////

关键是   #ifndef的作用域只是在单个文件中


要记住 : 如果在h文件中定义了全局变量,一个c文件包含同一个h文件多次,如果不加#ifndef宏定义,会出现变量重复定义的错误;如果加了#ifndef,则不会出现这种错误。

test2.h

#ifndef _TEST_2_H_
#define _TEST_2_H_

char *fun2();
int a = 1;

#endif

test3.h

#include "test2.h"

char *fun3();

test2.cpp

#include "test2.h"
#include "test3.h"

char *fun2()
{
	return "fun()\n";
}

char *fun3()
{
	return "fun2()\n";
}


如果没有#ifndef将会有如下错误

              'a' : redefinition; multiple initialization









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值