C语言随记_关于静态变量地址

来源:互联网 发布:java数组转化为字符串 编辑:程序博客网 时间:2024/06/05 08:49
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/

首先看下面这么一段代码:


//code_0;int main(void){int a = 1;int b = 2;printf("&a = 0x%x\n", &a);printf("&b = 0x%x\n", &b);return 0;} 


上述代码打印结果是:
&a = 0x12ff44

&b = 0x12ff40

通过打印结果,可以得出下图结论:


接着对代码进行一些修改,观察int型数组地址变化:

//code_1;int main(void){    int a[3];    printf("&a[0] = 0x%x\n", &a[0]);    printf("&a[1] = 0x%x\n", &a[1]);    printf("&a[2] = 0x%x\n", &a[2]);    return 0;}

上述代码打印结果是:

&a[0] = 0x12ff3c

&a[1] = 0x12ff40

&a[2] = 0x12ff44

通过打印结果,可以得出下图结论:

这时,我有了一个想法,因为我定义的是int a[3],那这一数组逻辑上就不存在第四个地址,那如果取第四个地址会发生什么呢?代码如下:

//code_2;int main(void){    int a[3];    printf("&a[0] = 0x%x\n", &a[0]);    printf("&a[1] = 0x%x\n", &a[1]);    printf("&a[2] = 0x%x\n", &a[2]);    printf("&a[3] = 0x%x\n", &a[3]); //a[3]在逻辑上是不存在,但是编译器不会报错或警报;        return 0;}

上述代码打印结果是:

&a[0] = 0x12ff3c

&a[1] = 0x12ff40

&a[2] = 0x12ff44

&a[3] = 0x12ff48

通过打印结果我们可以发现,虽然第四个数(即a[3])在逻辑上不存在,但是编译器的确可以打印其地址;



但是还有个问题,在code_0和code_1中,地址变量都是从0x12ff44作为起始地址再向下读取的,而逻辑上不存在的变量却超出了0x12ff44地址,于是在定义数组时,将int a[3]修改为int a[4],代码如下:

//code_3;int main(void){int a[4] ;printf("&a[0] = 0x%x\n", &a[0]);printf("&a[1] = 0x%x\n", &a[1]);printf("&a[2] = 0x%x\n", &a[2]);printf("&a[3] = 0x%x\n", &a[3]);    return 0;}


上述代码打印结果是:

&a[0] = 0x12ff38

&a[1] = 0x12ff3c

&a[2] = 0x12ff40

&a[3] = 0x12ff44

现在可以看出,变量地址变化恢复了正常;

下面接着进行一些测试,存在int型数组基础上,在数组前后添加inta1和int a2,进一步进行观察,代码如下:

//code_4;int main(void){int a1 ;int a[3];int a2;printf("&a1 = %x\n", &a1);printf("&a[0] = 0x%x\n", &a[0]);printf("&a[1] = 0x%x\n", &a[1]);printf("&a[2] = 0x%x\n", &a[2]);printf("&a[3] = 0x%x\n", &a[3]);    //a[3]任然在逻辑上不存在;printf("&a2 = %x\n", &a2);return 0;}

上述代码打印结果是:

&a1 = 0x12ff44

&a[0] = 0x12ff38

&a[1] = 0x12ff3c

&a[2] = 0x12ff40

&a[3] = 0x12ff44

&a2 = 0x12ff34

将打印结果用图例表示为:


从图例可以看出,&a[3]与&a1发生了冲突(或者说重合),由此发生了一个想法:打印a[3]会不会就此打印出a1的值,以下是代码:

//code_5int main(void){int a1 = 100;int a[3] = {0, 1, 2};int a2 = 200;printf("a1 = %d\n", ++a1);printf("a[0] = %d\n", a[0]);printf("a[1] = %d\n", a[1]);printf("a[2] = %d\n", a[2]);printf("a[3] = %d\n", ++a[3]);      //逻辑上不存在的a[3]的值;printf("a2 = %d\n", a2);return 0;}


上述代码打印结果是:

a1 = 101

a[0] = 0

a[1] = 1

a[2] = 2

a[3] = 102

a2 = 100

从打印结果再结合理论来看,因为a1与a[3]使用的同一地址,因此a1与a[3]存在等价关系,即a1==a[3];

通过上述code_0~code_5代码得出的一些规律,我在这里初始化几个变量,以及最后猜想的数据结果,通过代码来看打印出来的数据符不符合猜想结果:



以下是测试的代码:

//code_6;//为了打印结果可读性,改变了部分printf()位置;int main(void){int  a = 100;int  a1[3] = {10, 11, 12};int  a2[3] = {20, 21, 22};int  b = 200;printf("变量地址:\n");printf("&a = 0x%x\n", &a);printf("&a1[3] = 0x%x\n", &a1[3]);printf("&a1[2] = 0x%x\n", &a1[2]);printf("&a1[1] = 0x%x\n", &a1[1]);printf("&a1[0] = 0x%x\n", &a1[0]);printf("&a2[3] = 0x%x\n", &a2[3]);printf("&a2[2] = 0x%x\n", &a2[2]);printf("&a2[1] = 0x%x\n", &a2[1]);printf("&a2[0] = 0x%x\n", &a2[0]);printf("&b = 0x%x\n", &b);printf("变量值:\n");printf("a = %d\n", a);printf("a1[3] = %d\n", a1[3]);printf("a1[2] = %d\n", a1[2]);printf("a1[1] = %d\n", a1[1]);printf("a1[0] = %d\n", a1[0]);printf("a1[3] = %d\n", a1[3]);printf("a1[2] = %d\n", a1[2]);printf("a1[1] = %d\n", a1[1]);printf("a1[0] = %d\n", a1[0]);printf("b = %d\n", b);return 0;}


上述代码打印结果:

变量地址:

&a = 0x12ff44

&a1[3] = 0x12ff44

&a1[2] = 0x12ff40

&a1[1] = 0x12ff3c

&a1[0] = 0x12ff38

&a2[3] = 0x12ff38

&a2[2] = 0x12ff34

&a2[1] = 0x12ff30

&a2[0] = 0x12ff2c

&b = 0x12ff28

变量值:

a = 100

a1[3] = 100

a1[2] = 12

a1[1] = 11

a1[0] = 10

a2[3] = 10

a2[2] = 22

a2[1] = 21

a2[0] = 20

b = 200


2017.8.31更新:

做了关于二维数组地址的代码,如下所示:

int main(void){int a;int b[2][3];int c;printf("&a = 0x%x\n", &a);printf("&b[1][2] = 0x%x\t&b[1][1] = 0x%x\t&b[1][0] = 0x%x\n", &b[1][2], &b[1][1], &b[1][0]);printf("&b[0][2] = 0x%x\t&b[0][1] = 0x%x\t&b[0][0] = 0x%x\n", &b[0][2], &b[0][1], &b[0][0]);printf("&c = 0x%x\n\n", &c);printf("&b[2][0] = 0x%x\n", &b[2][0]);    //b[2][0]逻辑上并不存在;printf("&b[2][1] = 0x%x\n", &b[2][1]);    //b[2][1]逻辑上并不存在;return 0;}

上述代码打印结果:

&a = 0x12ff44

&b[1][2] = 0x12ff40    &b[1][1] = 0x12ff3c    &b[1][0] = 0x12ff38

&b[0][2] = 0x12ff34    &b[0][1] = 0x12ff30    &b[0][0] = 0x12ff2c

&c = 0x12ff28

&b[2][0] = 0x12ff44

&b[2][1] = 0x12ff48

/*----------------------------------------------------------------------------------------------------------------------------------------------------*/

原创粉丝点击