首页 > 技术文章 > 全局变量和全局静态变量

nuoforever 2021-08-05 14:57 原文

作用域:
全局变量整个程序空间,全局静态变量只在包含它的cpp中使用,下面举个栗子

global.h
#ifndef GLOBAL_H
#define GLOBAL_H

static int gs_a;
extern int g_b; //multiple definition,注意extern

#endif // GLOBAL_H

testa.h

#ifndef TESTA_H
#define TESTA_H

class TestA
{
public:
    TestA();
};

#endif // TESTA_H

testa.cpp

#include "testa.h"
#include "global.h"
#include <iostream>

TestA::TestA()
{
    gs_a = 1;
    g_b = 1;
    std::cout << "TestA gs_a : " << gs_a << " g_b : " << g_b << std::endl;
}

testb.h

#ifndef TESTB_H
#define TESTB_H

class TestB
{
public:
    TestB();
};

#endif // TESTB_H

testb.cpp

#include "testb.h"
#include "global.h"
#include <iostream>

TestB::TestB()
{
    gs_a = 2;
    g_b = 2;
    std::cout << "TestB gs_a : " << gs_a << " g_b : " << g_b << std::endl;
}

main.cpp

#include <iostream>
#include "global.h"
#include "testa.h"
#include "testb.h"

int g_b = 0; //undefined reference to g_b,注意初始化
int main(int argc, char *argv[])
{
    gs_a = 3;
    g_b = 3;
    std::cout << "Main gs_a : " << gs_a << " g_b : " << g_b << std::endl;
    TestA ta;
    std::cout << "Main::TestA gs_a : " << gs_a << " g_b : " << g_b << std::endl;
    TestB tb;
    std::cout << "Main::TestB gs_a : " << gs_a << " g_b : " << g_b << std::endl;
    return 0;
}

输出:

Main gs_a : 3 g_b : 3
TestA gs_a : 1 g_b : 1
Main::TestA gs_a : 3 g_b : 1
TestB gs_a : 2 g_b : 2
Main::TestB gs_a : 3 g_b : 2

 补充一点理论知识:

inline与宏定义有什么区别?
宏定义发生在预编译处理阶段,它仅仅是做字符串的替换,没有任何的语法规则检查;
inline函数则是发生在编译阶段,有完整的语法检查,在debug版本中跟普通函数一样,在release版本才会嵌入;
由于处理的阶段不一样,这就导致如果宏函数展开后仍然是一个函数调用的话,它是具有调用函数的开销,包括函数进栈出栈等等;而inline函数却仅仅是函数代码的拷贝替换,并不会发生函数调用的开销,在这一点上inline具有很高的执行效率。

inline函数与普通函数有什么区别?
正如上面提及的,普通函数的调用在汇编上有标准的 push 压实参指令,然后 call指令调用函数,给函数开辟栈帧,函数运行完成,有函数退出栈帧的过程;而 inline内联函数是在编译阶段,在函数的调用点将函数的代码展开,省略了函数栈帧开辟回退的调用开销,效率高。

static函数与普通函数有什么区别?
可见范围不一样:不被static关键字修饰的函数,它在整个工程范围内,全局都可以调用,即其属性是global的;只要函数参与了编译,且最后链接的时候把函数的.o文件链接进去了,是不会报undefined reference to ‘xxx’的;
被static关键字修饰的函数,只能在其定义的C文件内可见,即其属性由global变成了local,这个时候如果有另一个C文件的函数想调用这个static的函数,链接阶段会报undefined reference to ‘xxx’错误。

参考:

【gcc编译优化系列】static与inline的区别与联系

推荐阅读