关于c语言内部存储机制的微探究
研究二维数组的存储方式
首先我们探究关于二维数组的指针用法,我们都知道设计二维指针即表示为表,谈到这我们看下下面两段代码,唯一的不同就是关于*data+i
与*(data+i)
的区别。随机取值的地址如下。可以明显的看出地址的差值为4字节,即一个int.
#include<stdio.h>
int main(){
int data[2][3] = {1,3,5,7,9,0};
for (int i = 0;i < 6;i++)printf("%d ",*(*data+i));
return 0;
}
#include<stdio.h>
int main(){
int data[2][3] = {1,3,5,7,9,0};
for (int i = 0;i < 6;i++)printf("%d ",*(*(data+i)));
return 0;
}
代码 | 结果 |
---|---|
*data+i | 1,3,5,7,9,0 |
*(data+i) | 1,7,X,X,X |
data相对于一维数组而言是值,但是二维中其为指向值的地址,高维类推,那么*data+i
中的 i 明显就是变量 i对应的字节数而非变量本身的值,c的存储方式为顺序存储,这样下方地址一次加4就显而易见了。有以下表格也可得知*(data+i)
随 i 递增,依次增加12,那么问题来了,为什么是12,那要看数组的一行有多少个元素。*(data+i)
表示的是第i行的地址,由于数组为23,即一行有3个元素,每个元素的字节为4,因此,每读到下一行时,地址+12,跳过第i-1行的所有值。
结论:*data+i
依元素递增,*(data+i)
依行递增
以下表格为2*3的数组
value | i | *data+i 地址 | 增值 | *(data+i) 地址 | 增值 | 地址差值 | data+i 地址 |
---|---|---|---|---|---|---|---|
1 | 0 | 0019FF18 | 0019FF18 | 0 | 0019FF18 | ||
3 | 1 | 0019FF1C | 4 | 0019FF24 | 12 | 8 | 0019FF24 |
5 | 2 | 0019FF20 | 4 | 0019FF30 | 12 | 16 | 0019FF30 |
7 | 3 | 0019FF24 | 4 | 0019FF3C | 12 | 24 | 0019FF3C |
9 | 4 | 0019FF28 | 4 | 0019FF48 | 12 | 32 | 0019FF48 |
0 | 5 | 0019FF2C | 4 | 0019FF54 | 12 | 40 | 0019FF54 |
探究指针与二维数组的指向关系
想法:小白看看能否将一维数组由二维指针表示,那么就能将一维数组转为二维数组,通过输出结果发现并不如愿以偿。以下是对数组的探究过程。
首先创建一维数组,然后为二维指针申请空间,探讨一维数组在二维空间中的存储情况,通过输出相应结果得出结论.
下图为4x10的相对数组值
i \ j | -3 | -2 | -1 | 0 | 1 | 2 | 3 | |||
---|---|---|---|---|---|---|---|---|---|---|
0 | 2 | 5 | 7 | 9 | ||||||
1 | 2 | 5 | 7 | 9 | ||||||
2 | 2 | 5 | 7 | 9 | ||||||
3 | 2 | 5 | 7 | 9 |
此图可以说明C对一维数组的存储的存储方式,那么结果明显是不能简单的将一维数组直接转为任意二维数组,如果能找到行列对应的关系,那么通过封装函数则可实现不同维度数组建的转换。
以下是代码探究过程
#include<stdio.h>
#include<stdlib.h>
int main(){
int **data;
int i[4] = {2,5,7,9};
data = (int**)malloc(sizeof(int*)*4);//为指针申请空间
*data = &i[0];
*(data+1) = &i[1];
*(data+2) = &i[2];
*(data+3) = &i[3];
for (int j = -3;j < 7;j++)printf("%10d",j);
printf("\n\n");
for (int k = 0;k < 4;k++)
{
printf("%-2d",k);
for (int j = -3;j < 7;j++)
{
if (j == -3){printf("%10d",data[k][-3]);continue;}
if (j == -2){printf("%10d",data[k][-2]);continue;}
if (j == -1){printf("%10d",data[k][-1]);continue;}
printf("%10d",data[k][j]);
if (j == 6)printf("\n");
}
}
free(data);//回收空间
return 0;
}