作用域:
全局变量整个程序空间,全局静态变量只在包含它的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’错误。
参考: