您的位置:首页 > 编程语言 > C语言/C++

C_C++_二维数组与二维指针的地址与访问关系

2014-07-28 13:05 417 查看
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ROW 3
#define COL 5

int main()
{
int **a;
int **b;
int arr[ROW][COL] = {0};
int i,j;

printf("sizeof(int) = %d\n",sizeof(int));
printf("\n数组地址:\n");
for(i=0; i<ROW; i++)
{
for(j=0; j<COL; j++)
{
arr[i][j] = i+j;
// printf("%p ",*(arr+i)+j); //访问方式一
printf("%p ",&arr[i][j]); //访问方式二
printf("->%d ",arr[i][j]);

//printf("%p  ",(int *)arr+i*COL+j); //OK
//printf("%d \n",*((int *)arr+i*COL+j)); //OK

}
printf("\n");
}
/*
VC6.0运行结果:
数组地址:
0012FF04 ->0 0012FF08 ->1 0012FF0C ->2 0012FF10 ->3 0012FF14 ->4
0012FF18 ->1 0012FF1C ->2 0012FF20 ->3 0012FF24 ->4 0012FF28 ->5
0012FF2C ->2 0012FF30 ->3 0012FF34 ->4 0012FF38 ->5 0012FF3C ->6

证明了对于数组可以用数组形式访问,也可用指针形式访问,
即可以把数组名当指针来用,且数组单元地址连续
可以用:arr[i][j] 和 *(*(arr+i)+j) 和 *((int *)arr+i*COL+j)
*/
printf("\n");

//一次性分配足够内存地址是连续的
a = (int **)malloc(sizeof(int)*ROW*COL);
memcpy(a,arr,sizeof(int)*ROW*COL);
printf("二维指针一次性动态分配足够内存的地址:\n");
for(i=0; i<ROW; i++)
{
for(j=0; j<COL; j++)
{
//printf("%d ",a[i][j]); //error
//printf("%p ",*(*(a+i)+j)); //error
printf("%p ",(int *)a+i*COL+j);
printf("->%d ",*((int *)a+i*COL+j));
}
printf("\n");
}
/*
VC6.0运行结果:
二维指针一次性动态分配足够内存的地址:
00580F08 ->0 00580F0C ->1 00580F10 ->2 00580F14 ->3 00580F18 ->4
00580F1C ->1 00580F20 ->2 00580F24 ->3 00580F28 ->4 00580F2C ->5
00580F30 ->2 00580F34 ->3 00580F38 ->4 00580F3C ->5 00580F40 ->6

证明了对于一次性分配的二维指针指向的内存来说,内存单元地址连续且呈线性分布,
但该指针不能做数组名使用,以数组名访问会出错,访问时要注意元素间隔。
可以用:*((int *)a+i*COL+j)
不能用:a[i][j] 和 *(*(a+i)+j)
*/
printf("\n");

printf("二维指针两次分配内存:\n");
b = (int **)malloc(sizeof(int *)*ROW);
for(i=0; i<ROW; i++)
{
b[i] = (int *)malloc(sizeof(int)*COL);
}

for(i=0; i<ROW; i++)
{
for(j=0; j<COL; j++)
{
b[i][j] = arr[i][j];
//printf("%p ",&b[i][j]); //访问方式一 ok
printf("%p ",*(b+i)+j); //访问方式二 ok
printf("->%d ",*(*(b+i)+j));
//printf("%p \n",*((int *)b+i*ROW+j));//error
}
printf("\n");
}

/*
VC6.0运行结果:
二维指针两次分配内存:
003D0FA8 ->0 003D0FAC ->1 003D0FB0 ->2 003D0FB4 ->3 003D0FB8 ->4
003D0FF0 ->1 003D0FF4 ->2 003D0FF8 ->3 003D0FFC ->4 003D1000 ->5
003D1038 ->2 003D103C ->3 003D1040 ->4 003D1044 ->5 003D1048 ->6

证明了对二维指针两次分配内存,对每一次malloc操作分配的内存是连续的,
但这一次malloc操作与下一次malloc操作分配的内存地址不是相连的,
特殊情况下会相连,这种情况比较少。
访问的时候可以作指针形式访问,也可以做数组形式访问
可以用:b[i][j] 和 *(*(b+i)+j);
但是不能用:*((int *)b+i*ROW+j)
*/
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: