static为什么只会被初始化一次
static只会初始化1次
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结果的布局空间即可。 再往下深究的话,要看汇编代码试着再深究一下!