上一次写blog还是上一次,瓜同学在这段时间经历了太多不幸,现在重修c++(byd数据结构与算法),当写日记一下记录每一次的心得与收获吧,算是在基础上的进阶与精进。(随缘~)
static:之前在函数传参过程中用的东西,像递归之类的,可以保留上一次的值(还有很多应用场景),在正儿八经谈static之前,咱们先来说说external,我才发现之前的用法是错误的,总是直接在main外用,以为他就是个全局声明的前缀,这样写了好像就可以在整个项目里面直接用(纯瓜同学臆想),现在发现:
//一个新建项目的main.cpp:
#include<iostream>
using namespace std;
extern char a; //注意不能extern char a=xxx;
//此外,extern也可在main内写,且仍输出b
int main()
{
cout << a;
return 0;
}
//同一项目的一个testextern.cpp:
char a = 'b';
//输出:
b
amazing,在同一个项目里两处全局定义同一个变量a,没有报错!嘞就是external!(实际作用有点像引用,是建立extern link,链接现在还暂时没玩明白)。
下面开始正儿八经讲static:它就像是一个私有的定义,举个例子:
//main.cpp:
#include<iostream>
using namespace std;
void a(char b)
{
}
int main()
{
a('c');
return 0;
}
//teststatic,cpp:
#include<iostream>
static void a(char b)
{
std::cout << b;
}
嘿,您猜怎么着,它不输出,而且这里两个地方都全局定义了a(),没有报错,这就是static,teststatic中的a()就像一个私有函数,main里面link不到的,所以可以void一个一模一样的,也不会有问题,main中就正常跑,可以说无视了static void a(),它只能在声明文件中被看到。所以,如果不希望变量是全局变量,那就得尽可能用static,否则编译器会跨翻译单元(跨文件)来链接,就可能同名报错,但如果需要跨文件,该咋做咋做呗~
如果在类与结构体中,注意了,若将static与正常变量一起定义,那么意味着这个static的变量只有一个实例:
#include<iostream>
using namespace std;
class player
{
public:
static int a ;
};
int player::a; //attention
int main()
{
player p1;
player p2;
p1.a = 10;
p2.a = 12;
cout << p1.a << endl << p2.a << endl << &p1.a << endl << &p2.a;
return 0;
}
正常情况这里是p1和p2应该输出对应的10和12,然而最后结果是两个12,我愿意称之为static的唯一性(并没有这种说法....流汗黄豆),这里打印一下地址,你也会惊奇地发现两者一致。此外,比较麻烦,在代码中的attention处,大家可以看到,我们又全局int了一下a,不然的话会爆link的错,只有再全局定义一次,链接器才能正确摸到我们static int的a。但相应的,如果我们想要跨类(共享)使用变量,可以使用这种方法,但要注意一些东西:
#include<iostream>
using namespace std;
class player
{
public:
int a ;
static void print(player playboy)
{
cout << playboy.a;
}
//以下写法是错误的!!!
//static void print()
//{
//虽然在同一个类里,但不能直接调用a
//}
};
int main()
{
player p1;
p1.a = 10;
player p2;
p2.a = 12;
player::print(p1);
cout << endl;
player::print(p2);
return 0;
}
注意,在上面提到了,static的method不能直接用a,这是因为静态method没有类实例,而正常情况的method则可以从当前类的的实例作为参数。最后输出10和12,perfect!
接下来就是曾经的回忆了,之前传参过程用的static,去让他定义类型的变量能保持上一次的结果,这便是局部静态(local static),局部说明它是在一定生存期、作用域内作用,之前用的例子中生存期基本是与程序同步的,而我们讨论的局部static就没有那么夸张,除此之外,类中的static可以被类中的东西访问,而函数中则只是当做一个函数的局部变量(其实两者还是很像,好类比的,但瓜同学还是想把他们分开)。下面开始举例子,在一个函数中我们static int a;在此次函数结束后,他并不会被删除(只是int a的话会被删除,下一次创造一个全新的a)
#include<iostream>
using namespace std;
void play()
{
static int a=0;
int b=0;
cout << a << " " << b << endl;
a++;
}
int main()
{
play();
play();
play();
return 0;
}
最后输出也是意料之中的0 0,1 0,2 0;
第一天大概就是这样,重新认识了一下extern和static,希望可以坚持学习(声音越变越小)