C++学习笔记:static和extern在类、结构体外的作用【Cherno】

如同字面意思:static代表不流动,extern代表流动;

说实话,这俩东西给本菜的感觉像是类里的public、private关键字,都是对作用域的限制;

如果我们定义一个变量为static变量,那么就声明了这个变量只能在本文件在被链接,对函数也是如此。extern不一样,当你用他声明一个变量时,系统并不是在真正创建一个变量,而是在向其他文件寻找同名变量,并调用;

现在我们有两个文件,value.cpp,源.cpp

源.cpp:

//源.cpp
#include<iostream>

int var = 1;

int main() {
	
	

	std::cout << &var << std::endl;
	std::cout << var << std::endl;
}

value.cpp

//value.cpp
#include<iostream>

int var = 1;

void show_var() {

	std::cout << &var << std::endl;
}

这个时候会报错:

这个是因为我们在讲文件链接起来的时候,发现一两个相同名字的变量,这很离谱。

因为这两个变量的作用域是全局的。【在别的文件在调用要用extern关键字】

我们只要稍稍做改进:

将源.cpp改为:

#include<iostream>

extern int var;

void show_var();

int main() {
	
	

	std::cout << &var << std::endl;//展示源.cpp里var的地址
	std::cout << var << std::endl;

	var++;

	show_var();//展示value.cpp里的var地址


}

然后就可以过编译了;

但是我们运行的时候我会发现一个非常有意思的现象:

先看一下运行结果:

 哦吼吼,原来var这个值是通过共享地址在不同文件中使用的;

其实我们还有一个方法可以改进这个bug,那就是将两个文件中的var变量定义为static,这个意思就是告诉链接器:你虽然看见两个一样名字的变量,但是这两个变量只在各自的文件中可以被调用,决不越雷池半步;

居然作用域不同,那么当然不会产生重名冲突,这里可以类比两个在同一文件中的两个独立函数,如果我们在这两个独立的函数中定义两个一样名字的变量,那么我们知道肯定不会出bug,因为他们的作用域没有交集;

改变后的文件如下:

//源.cpp
#include<iostream>

static int var;

void show_var();

int main() {
	
	

	std::cout << &var << std::endl;//展示源.cpp里var的地址
	std::cout << var << std::endl;

	var++;

	show_var();//展示value.cpp里的var地址
}
//value.cpp
#include<iostream>

static int var = 1;

void show_var() {

	std::cout << &var << std::endl;
	std::cout << var << std::endl;
}

这个时候我们运行,就会发现:

 这两个var分别是独立的;

如果我们在value的show_val函数在声明一个extern int var;

然后就有:

#include<iostream>

static int var = 2;

void show_var() {

	extern int var;

	std::cout << &var << std::endl;
	std::cout << var << std::endl;
}

运行一下:

 这说明extern找到的是本文件中的var变量;

如果我们将value.cpp中的var删除,那么会报错:

 这是什么原因呢?明明源.cpp中有一个var,且我们在value.cpp中让系统在别的文件中找var;

这只能说系统没找到,因为源.cpp中的var是静态的,static的,var只能在源.cpp中被调用,故系统找不到合法的var;

但是如果我们再定义一个文件:second.cpp,里面定义一个var,那么会怎么样呢?

//second
int var=1;

然后我们运行:

 可以过了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值