static为什么只会被初始化一次

1.static每次初始化相同的值,代码1中的static初始化 放到for循环中,每次进行初始化相同的值,先看一下这个结果。我们发现他们的内存布局是紧按着的。

#include <iostream>
using namespace std;

int main() {
	int n = 2;
	for(int i = 0; i < n; i ++)	{
		static int a = 10;
		static int b = 10;
		static int c = 20;
		static int d = 10;
		static int e = 10;
		static int f = 100;

		int *tmp = &a;
		for (int i = 1; i < 20; ++i) {
			cout << "i = " << i << ", *tmp = " << *tmp << endl;
			tmp ++;
		}
	}
	return 0;
}

结果:

i = 1, *tmp = 10
i = 2, *tmp = 10
i = 3, *tmp = 20
i = 4, *tmp = 10
i = 5, *tmp = 10
i = 6, *tmp = 100
i = 7, *tmp = 0
i = 8, *tmp = 0
i = 9, *tmp = 0
i = 10, *tmp = 0
i = 11, *tmp = 0
i = 12, *tmp = 0
i = 13, *tmp = -1792171088
i = 14, *tmp = 32752
i = 15, *tmp = -1792171048
i = 16, *tmp = 32752
i = 17, *tmp = 6
i = 18, *tmp = 0
i = 19, *tmp = 0
i = 1, *tmp = 10
i = 2, *tmp = 10
i = 3, *tmp = 20
i = 4, *tmp = 10
i = 5, *tmp = 10
i = 6, *tmp = 100
i = 7, *tmp = 0
i = 8, *tmp = 0
i = 9, *tmp = 0
i = 10, *tmp = 0
i = 11, *tmp = 0
i = 12, *tmp = 0
i = 13, *tmp = -1792171088
i = 14, *tmp = 32752
i = 15, *tmp = -1792171048
i = 16, *tmp = 32752
i = 17, *tmp = 6
i = 18, *tmp = 0
i = 19, *tmp = 0

2.每次初始化不同的值,同样也放到for循环中去,我们这时候来看看内存布局,就会发现有意思的事情了!

#include <iostream>
using namespace std;

int main() {
	for (int i = 0; i < 1; ++i) {
		static int a = (i + 100);
		static int c = (i + 500);
		static int d = (i + 20);
		static int e = (i + 30);
		static int f = (i + 40);
		static int g = (i + 50);
		static int b = (i + 200);

		int *tmp = &a;
		for (int i = 0; i < 30; ++i) {
			cout << "i = " << i << ", *tmp = " << *tmp << endl;
			tmp ++;
		}
	}

	return 0;
}

结果:

i = 0*tmp = 100
i = 1*tmp = 1
i = 2*tmp = 0
i = 3*tmp = 500
i = 4*tmp = 0
i = 5*tmp = 1
i = 6*tmp = 0
i = 7*tmp = 20
i = 8*tmp = 0
i = 9*tmp = 1
i = 10*tmp = 0
i = 11*tmp = 30
i = 12*tmp = 0
i = 13*tmp = 1
i = 14*tmp = 0
i = 15*tmp = 40
i = 16*tmp = 0
i = 17*tmp = 1
i = 18*tmp = 0
i = 19*tmp = 50
i = 20*tmp = 0
i = 21*tmp = 1
i = 22*tmp = 0
i = 23*tmp = 200
i = 24*tmp = 0
i = 25*tmp = 1
i = 26*tmp = 0
i = 27*tmp = 0
i = 28*tmp = 0
i = 29*tmp = 0

2.得到规律:

我们发现,第一元素a=100的后面紧挨着一个1,而其他的元素布局是【0-元素值-0-1】的形式。这个时候你会好奇这个布局格式和代码1中的布局格式完全不一样!!。那是因为我们每次赋的初值不相等。
2.1为什么出现这个样子呢?后面的1是干什么用的?
这里先解答一下:代码1的空间布局和代码2的空间布局其实是不在一块的,虽然他们都是在内存的静态区。
2.2后面的1是干什么用的?
后面的1其实是为了记录这个static有没有进行初始化,如果初始化了,那么会在这个元素的后面的内存空间中生成一个1,用来记录已经初始化了。我们再进行初始化的时候会失效!

3和4我们进行测试一下,证明一下我们的规律

3.测试代码1

#include <iostream>
using namespace std;

int main() {
	
	for (int x = 5; x < 10; ++x) {
		static int y = x; // 每次给y初始化不同的值
		cout << "x = " << x << ", y = " << y << endl;
	}

	return 0;
}
// 结果:
x = 5, y = 5
x = 6, y = 5
x = 7, y = 5
x = 8, y = 5
x = 9, y = 5

我们发现每次y的值都是5,说明被初始化了1次。
接下来我们用指针进行指向y元素内存后面的那个位置,我们看看它的值是不是1!

#include <iostream>
using namespace std;

int main() {
	
	for (int x = 5; x < 10; ++x) {
		static int y = x; // 每次给y初始化不同的值
		int *p = &y;
		p ++;
		cout << "*p = " << *p << endl;
		cout << "x = " << x << ", y = " << y << endl;
	}

	return 0;
}
// 结果:
*p = 1
x = 5, y = 5
*p = 1
x = 6, y = 5
*p = 1
x = 7, y = 5
*p = 1
x = 8, y = 5
*p = 1
x = 9, y = 5

我们发现y元素后面内存位置的值为1,验证了我们的猜想!

4.我们修改*p = 0,之后会发生什么?

#include <iostream>
using namespace std;

int main() {
	
	for (int x = 5; x < 10; ++x) {
		static int y = x; // 每次给y初始化不同的值
		int *p = &y;
		p ++;
		*p = 0;
		cout << "x = " << x << ", y = " << y << endl;
	}

	return 0;
}
# 结果:
x = 5, y = 5
x = 6, y = 6
x = 7, y = 7
x = 8, y = 8
x = 9, y = 9

结论:我们发现y的值进行了变化

现在我们可以得出结论,static为什么只能初始化1次,是因为该元素后面的内存中有个记录该元素是否被初始化过,如果初始化过为1,没有初始化过为0。我们可以进行强行修改该内存空间中的值,再次令static int y再次进行初始化。

小小的注意事项:如果for循环中定义了很多个static int x, y, z分别进行多次初始化不同值得时候,x一个内存空间中的值是1(即 int *p = & x; p += 1; 此时 *p = 1),而y的下下个内存空间的值是1(即 int *p = & y; p += 2; 此时 p = 1),z的下下**个内存空间的值是1(即 int *p = & z; p += 2; 此时 *p = 1)。可以看代码2结果的布局空间即可。 再往下深究的话,要看汇编代码试着再深究一下!