C++ extern 和 static

简要说下extern:
extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。
C/C++中extern关键字详解

  • extern 和 static
    上文对extern 和 static做了说明,并举了例子,我对其进行了测试:
test1.h

#ifndef TEST1H
#define TEST1H
static char g_str[] = "123456"; 
extern char g_char;
void fun1();
#endif
test1.cpp

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

using namespace std;
char g_char = 'W';
static char s_char = 'H';
void fun1()  {
    cout << g_str << endl;
    cout << g_char << endl;
    cout << s_char << endl;
}
test2.cpp


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

using namespace std;

void fun2()  {
    cout << g_str << endl;//g_str(static修饰)在内存中有多份
    //extern g_char;
    cout << g_char << endl;//g_char(extern 修饰)在内存中只有一份0x601077
    //cout << s_char << endl;
}

int main() {
    fun1();
    fun2();
    return 0;
}

gdb 调试

fun1 () at test1.cpp:7
7           cout << g_str << endl;
(gdb) p &g_str
$1 = (char (*)[7]) 0x601070 <g_str>
(gdb) n
123456
8           cout << g_char << endl;
(gdb) p &g_char
$2 = 0x601077 <g_char> "W123456"
(gdb) n
W
9       }
(gdb) n
main () at test2.cpp:14
14          fun2();
(gdb) s
fun2 () at test2.cpp:7
7           cout << g_str << endl;
(gdb) p &g_str
$3 = (char (*)[7]) 0x601078 <_ZL5g_str>
(gdb) n
123456
9           cout << g_char << endl;
(gdb) p &g_char
$4 = 0x601077 <g_char> "W123456"

可见,g_str(static修饰)在内存中有多份,g_char(extern修饰)在内存中只有一份0x601077。 我们通常说static修饰的全局变量只能在一个文件中使用,而不能在其他文件中使用,而在此例中,发现g_str在内存中有多份,这是因为在Test2.cpp中include “test1.h”,所以相当于test2.cpp也定义了一个g_str,但两者却是不同的,即使存储的内容相同但地址不同。下面举一个例子说明“static修饰的全局变量只能在一个文件中使用,而不能在其他文件中使用”:

test1.cpp


#include <iostream>

using namespace std;

char s_char = 'H';

void fun1() {
    cout << s_char << endl;
}
test2.cpp
#include <iostream>
//#include "test1.cpp""
using namespace std;
extern char s_char; // 声明s_char在其他文件中定义
void fun2() {
    cout << s_char << endl;
}



int main() {

    //fun1();
    fun2();
    return 0;
}

此时g++ -g –std=c++11 -o test test2.cpp test1.cpp 可以编译通过运行成功。
但若在test1,cpp中加入static,如:

test1.cpp


#include <iostream>

using namespace std;

static char s_char = 'H';

void fun1() {
    cout << s_char << endl;
}

则编译出错:对‘s_char’未定义的引用
collect2: error: ld returned 1 exit status

C/C++中extern关键字详解 中对于static不存在重复定义的问题,而对于extern char g_str[]=”123456”那种情况却存在重复定义,原因在于:static修饰全局变量的作用域只能是本身的编译单元,即本文件中。 所以即使test1.cpp 和 test2.cpp中都定义了static全局变量,但它们仅限于本文件中; 而extern char g_str[]= “123456”; // 这个时候相当于没有extern, 这个全局变量就不限于本身编译单元,所以会出现重复定义的错误

最后,作者给了点建议:1 一般定义static全局变量时,都把它放在原文件中而不是头文件; 2 只在头文件中尽量做声明,比如extern char g_str[]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值