文章出处: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定义变量意味着什么的更多相关文章

  1. C++-模板的声明和实现为何要放在头文件中

    源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 ...

  2. C ++模板的声明和实现为何要放在头文件中?

    源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 ...

  3. c语言头文件中定义全局变量的问题

    c语言头文件中定义全局变量的问题 (转http://www.cnblogs.com/Sorean/) 先说一下,全局变量只能定义在 函数里面,任意函数,其他函数在使用的时候用extern声明.千万不要 ...

  4. c++ inline使函数实现可以在头文件中,避免多重定义错误

    作者:Jon Lee链接:https://www.zhihu.com/question/53082910/answer/133612920来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...

  5. cctype头文件中的一些内容

    1. string 标准库 1.1初始化 string s1; 默认构造函数s1为空 string s2(s1); 将s2初始化为s1的一个副本 string s3(“value”); 将s3初始化为 ...

  6. Effective Objective-C 2.0 — 第二条:类的头文件中尽量少引入其他头文件

    第二条:类的头文件中尽量少引入其他头文件 使用向前声明(forward declaring) @class EOCEmployer 1, 将引入头文件的实际尽量延后,只在确有需要时才引入,这样就可以减 ...

  7. 将inline、template声明和定义在头文件中

    如果要在要在源文件(a.cpp)中内联的展开一个函数(fun),则该源文件(a.cpp)中必须包含此函数(fun)的定义.如果要在多个文件中内联的展开fun,则在所有的源文件中都必须包含fun的定义. ...

  8. 头文件中的#ifndef/#define/#endif 的作用

    在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定 ...

  9. C++头文件中预编译宏的目的

    C++头文件中预编译宏的目的 eg: #ifndef _FACTORY_H_#define _FACTORY_H_......#endif //~_FACTORY_H_ 防止头文件被重复包含,导致变量 ...

随机推荐

  1. 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 ...

  2. 给学习IT、编程者的看

    Preface: 我始终认为,对一个初学者来说,IT界的技术风潮...... Content: 我始终认为,对一个初学者来说,IT界的技术风潮是不可以追赶的,而且也没有能力去追赶.我时常看见自己的DD ...

  3. CSS 之 嵌套 margin-top 处理

    如下代码: <div style=" width:1000px; height:700px; margin:auto;"> <div style=" w ...

  4. AJAX全套

    AJAX概述 AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术. AJAX = 异步 Java ...

  5. batchExportPNG.py不是我的代码

    #coding=gbk#@author lifc,20140806#批量制作输出专题图import arcpy,os,time,math #testpath=raw_input("testp ...

  6. [课程相关]附加题——stack的理解

    一.stack的三种解释 stack有三种解释,我个人理解如下. 1.用户自定义的stack 用户自定义的stack就是一般意义上的后进先出队列,从名字上就能理解了,stack由下向上增长,有一个顶指 ...

  7. VMware系统运维(十八)部署虚拟化桌面 通过View Client进行连接测试

    1.打开VMware Horizon View Client添加服务器,配置连接服务器的IP地址等信息 2.点击云图标进行连接,点击继续,证书部分我们后面再讲 3.输入用户名密码,点击"登录 ...

  8. VMware系统运维(十五)部署虚拟化桌面Horizon View Manager 5.2添加vCenter Server服务器

    1.点击"添加...",进入到"添加vCenter Server"界面,输入服务器的IP地址,用户名密码,点击"下一步" 2.设置View ...

  9. Fuck Sharepoint 2013

    最近遇到一个貌似是bug的问题,每次点击页面的时候页面的地址多出一行/_layouts/15/start.aspx#/ 然后跑到google上搜索出解决方案, 地址:http://social.tec ...

  10. jQuery无缝循环开源多元素动画轮播jquery.slides插件

    详细内容请点击 初始化插件: 一款基于jQuery无缝轮播图插件,支持图内元素动画,可以自定义动画类型$(".slideInner").slide({slideContainer: ...