[C/C++]在头文件中使用static定义变量意味着什么
文章出处:http://www.cnblogs.com/zplutor/
看到有一位同学在头文件中这么写:
static const wchar_t* g_str1 = …
static const wchar_t* g_str2 = …
这种定义变量的方式我从来没有见过,而且它还能顺利通过编译,于是我很想知道编译器是如何处理这种变量定义的。
定义全局变量时使用static,意味着该变量的作用域只限于定义它的源文件中,其它源文件不能访问。既然这种定义方式出现在头文件中,那么可以很自然地推测:包含了该头文件的所有源文件中都定义了这些变量,即该头文件被包含了多少次,这些变量就定义了多少次。
假如将上面两行代码的static去掉,编译的时候就会出现变量重定义的错误,这进一步证实了上面的推测,因为没有static的话变量的作用域是全局的,定义了两个以上的同名变量就会出现该错误。
推测终究是推测,要真正证实这个推测还要通过写代码来验证。验证的方式是:在头文件中使用static定义变量,在多个源文件中包含该头文件,然后在每个源文件中输出变量的地址,同时在一个源文件中改变变量的值并输出,在另一个源文件中也输出。如果每个源文件的输出都不同,则推测得证;否则推测是错误的。
下面是定义变量的头文件的代码:
//Header.h
#pragma once static int g_int = ;
接下来在另一个头文件中声明两个测试函数:
//Functions.h
#pragma once void TestSource1();
void TestSource2();
分别在两个源文件中定义这两个测试函数:
//Source1.cpp
#include <stdio.h>
#include "Header.h" void TestSource1() { wprintf(L"g_int's address in Source1.cpp: %08x\n", &g_int);
g_int = ;
wprintf(L"g_int's value in Source1.cpp: %d\n", g_int);
}
//Source2.cpp
#include <stdio.h>
#include "Header.h" void TestSource2() { wprintf(L"g_int's address in Source2.cpp: %08x\n", &g_int);
wprintf(L"g_int's value in Source2.cpp: %d\n", g_int);
}
最后在main函数中调用这两个测试函数:
//Main.cpp
#include "Functions.h" int wmain() { TestSource1();
TestSource2();
}
运行该程序:

可以看到,虽然在代码中好像使用了相同的变量,但是实际上使用的是不同的变量,在每个源文件中都有单独的变量。所以,在头文件中定义static变量会造成变量多次定义,造成内存空间的浪费,而且也不是真正的全局变量。应该避免使用这种定义方式。
作为对比,下面使用正确的方式来定义全局变量:
//Header.h
#pragma once extern int g_int;
//Source1.cpp
#include <stdio.h>
#include "Header.h" int g_int = ; void TestSource1() { wprintf(L"g_int's address in Source1.cpp: %08x\n", &g_int);
g_int = ;
wprintf(L"g_int's value in Source1.cpp: %d\n", g_int); }
其它文件不变。
运行程序:

可以看到,这次两个源文件中使用的都是同一个变量。要注意的是,使用extern声明变量时不能带有初始值,否则仍然属于变量定义,会出现变量重定义的错误。
[C/C++]在头文件中使用static定义变量意味着什么的更多相关文章
- C++-模板的声明和实现为何要放在头文件中
源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 ...
- C ++模板的声明和实现为何要放在头文件中?
源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 ...
- c语言头文件中定义全局变量的问题
c语言头文件中定义全局变量的问题 (转http://www.cnblogs.com/Sorean/) 先说一下,全局变量只能定义在 函数里面,任意函数,其他函数在使用的时候用extern声明.千万不要 ...
- c++ inline使函数实现可以在头文件中,避免多重定义错误
作者:Jon Lee链接:https://www.zhihu.com/question/53082910/answer/133612920来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...
- cctype头文件中的一些内容
1. string 标准库 1.1初始化 string s1; 默认构造函数s1为空 string s2(s1); 将s2初始化为s1的一个副本 string s3(“value”); 将s3初始化为 ...
- Effective Objective-C 2.0 — 第二条:类的头文件中尽量少引入其他头文件
第二条:类的头文件中尽量少引入其他头文件 使用向前声明(forward declaring) @class EOCEmployer 1, 将引入头文件的实际尽量延后,只在确有需要时才引入,这样就可以减 ...
- 将inline、template声明和定义在头文件中
如果要在要在源文件(a.cpp)中内联的展开一个函数(fun),则该源文件(a.cpp)中必须包含此函数(fun)的定义.如果要在多个文件中内联的展开fun,则在所有的源文件中都必须包含fun的定义. ...
- 头文件中的#ifndef/#define/#endif 的作用
在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定 ...
- C++头文件中预编译宏的目的
C++头文件中预编译宏的目的 eg: #ifndef _FACTORY_H_#define _FACTORY_H_......#endif //~_FACTORY_H_ 防止头文件被重复包含,导致变量 ...
随机推荐
- LMAX Disruptor – High Performance, Low Latency and Simple Too 转载
原文地址:http://www.symphonious.net/2011/07/11/lmax-disruptor-high-performance-low-latency-and-simple-to ...
- 给学习IT、编程者的看
Preface: 我始终认为,对一个初学者来说,IT界的技术风潮...... Content: 我始终认为,对一个初学者来说,IT界的技术风潮是不可以追赶的,而且也没有能力去追赶.我时常看见自己的DD ...
- CSS 之 嵌套 margin-top 处理
如下代码: <div style=" width:1000px; height:700px; margin:auto;"> <div style=" w ...
- AJAX全套
AJAX概述 AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. AJAX = 异步 Java ...
- batchExportPNG.py不是我的代码
#coding=gbk#@author lifc,20140806#批量制作输出专题图import arcpy,os,time,math #testpath=raw_input("testp ...
- [课程相关]附加题——stack的理解
一.stack的三种解释 stack有三种解释,我个人理解如下. 1.用户自定义的stack 用户自定义的stack就是一般意义上的后进先出队列,从名字上就能理解了,stack由下向上增长,有一个顶指 ...
- VMware系统运维(十八)部署虚拟化桌面 通过View Client进行连接测试
1.打开VMware Horizon View Client添加服务器,配置连接服务器的IP地址等信息 2.点击云图标进行连接,点击继续,证书部分我们后面再讲 3.输入用户名密码,点击"登录 ...
- VMware系统运维(十五)部署虚拟化桌面Horizon View Manager 5.2添加vCenter Server服务器
1.点击"添加...",进入到"添加vCenter Server"界面,输入服务器的IP地址,用户名密码,点击"下一步" 2.设置View ...
- Fuck Sharepoint 2013
最近遇到一个貌似是bug的问题,每次点击页面的时候页面的地址多出一行/_layouts/15/start.aspx#/ 然后跑到google上搜索出解决方案, 地址:http://social.tec ...
- jQuery无缝循环开源多元素动画轮播jquery.slides插件
详细内容请点击 初始化插件: 一款基于jQuery无缝轮播图插件,支持图内元素动画,可以自定义动画类型$(".slideInner").slide({slideContainer: ...