C++学习笔记(二)

条件与分支

当开始一个程序的时候,整个应用程序及所有模块加载到内存中。也就是说我们必须检查条件,然后跳转到内存的不同地方,然后从这里开始执行。这也就意味着if语句和分支通常有比较大的开销。为了解决这一问题分支预测技术出现。现在的CPU处理速度非常高,所以实际上分支预测出色,造成的影响也比较少。但在GPU中仍然存在性能问题。(为了解决大量的计算GPU不支持分支预测)

分支预测

当处理一个分支指令时,有可能会产生跳转,从而打断流水线指令的处理,因为处理器无法确定该指令的下一条指令,直到分支指令执行完毕。流水线越长,处理器等待时间便越长,分支预测技术就是为了解决这一问题而出现的。因此,分支预测是处理器在程序分支指令执行前预测其结果的一种机制。

C++中的静态(static)

类和结构体外的静态

#include <iostream>
#define LOG(x) std::cout << x << std::endl

extern int s_Variable;

int main()
{
	LOG(s_Variable);
	std::cin.get();
}

这是一段代码,我们在另一个cpp文件中下一行代码 static int s_Variable = 5;这个时候编译会产生链接错误,因为我们把s_Variable定义成了静态变量(static)。静态变量只会在翻译单元内部链接

静态变量和函数意味着,当需要将这些函数或变量与实际定义的符号链接时,链接器不会在翻译单元的作用域之外去寻找那个符号的定义。也就是说,静态变量和静态函数只对声明它的N那个cpp文件可见,就像是class里面的private

如果在头文件中声明了一个静态变量,并将头文件包含在两个不同的C++文件中,就相当于在两个cpp文件中都声明了这个相同的静态变量。

类和结构体中的静态

在类中,static与变量一起使用,意味着在类的所有实例中这个变量只有一个实例。例如:有一个类,这个类有很多实例,某个实例改变了一个静态变量的值,那么会在所有实例中反映出这个变化。

静态方法无法访问到类的实例,静态方法可以被调用,不许需要通过类的实例。而在静态方法内部,不能写引用的类实例的代码。

#include <iostream>

struct Entity
{
	int x, y;
	void print()
	{
		std::cout << x << "," << y << std::endl;
	}
};

int main()
{
	Entity e;
	e.x = 2;
	e.y = 3;
	Entity e1 = { 5,8 };
	e.print();
	e1.print();
	std::cin.get();
}

最后输出的结果是

2,3
5,8

但如果我们把x,y变成静态变量

#include <iostream>

struct Entity
{
	static int x, y;
	void print()
	{
		std::cout << x << "," << y << std::endl;
	}
};

int Entity::x;
int Entity::y;

int main()
{
	Entity e;
	e.x = 2;
	e.y = 3;
	Entity e1;
	e1.x = 5;
	e1.y = 8;
	e.print();
	e1.print();
	std::cin.get();
}

此时x和y就不是类的成员变量了,也没有办法用初始化器来初始化变量了。

最后输出的结果是

5,8
5,8

我们看到代码中多了一个奇怪的东西 int Entity::x; int Entity::y; 静态成员变量是所有实例共享的,但是其只是在类中进行了声明,并未定义或初始化(分配内存),类或者类实例就无法访问静态成员变量,这显然是不对的,所以必须先在类外部定义,也就是分配内存

ps:静态成员变量在编译时存储在静态存储区,即定义过程应该在编译时完成,因此一定要在类外进行定义,但可以不初始化。

在这个例子中所有用实例去引用静态变量的代码其实等价于 Entity::x = 5; Entity::y = 8; 就相当于在名为Entity的命名空间中创建了两个变量,它们实际不属于类。(他们实际上还是类的一部分,而不是命名空间,但是和命名空间中一样)

类中的静态函数同理,调用他时其实就等价于 Entity::print();不过不需要在类外声明。(此时x,y也是静态的)如果x和y不是静态的就会报错,因为静态方法不能访问非静态变量

局部静态(Local Static)

静态局部变量允许我们声明一个变量,它的生存期基本上相当于整个程序的生存期,它的作用范围被限制在一个作用域内。

#include <iostream>

void Function()
{
	int i = 0;
	i++;
	std::cout << i << std::endl;
}

int main()
{
	for(int i = 0; i < 3; i++)
		Function();
	std::cin.get();
}

输出结果就是

1
1
1

我们每次调用函数都会把i赋值为0然后+1,所以每次都会打印出1。

但是如果我们把i变成静态变量

#include <iostream>

void Function()
{
	static int i = 0;
	i++;
	std::cout << i << std::endl;
}

int main()
{
	for(int i = 0; i < 3; i++)
		Function();
	std::cin.get();
}

输出的结果就是

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值