我们先看下面的例子
void func(int **p, int n, int m){
for(int i=0; i < n; i++)
{
for(int j=0; j < m; j++)
{
p[i][j]=i+j; ///////调试通过,但执行时报错
cout << p[i][j] <
}
}
}
void main(){
int a[2][3];
func((int **)a, 2, 3);
int k;
cin >>k ;
}
我们看上面的例子,是想把数组a的内容传给函数func, 但在函数func赋值语句p[i][j]=i+j报内存存取错误,为什么呢?我们看看在C语言中2维数组在内存中的分布
实际上二维数组(或者多维)在内存中的地址就是连续的。比如:
array[2][2] = {{1,2},{3,4}};
实际上在内存中的顺序就是
... 1, 2, 3, 4, ...
[0][0] [0][1] [1][0] [1][1]
而如果是array[2][2][2] = {{{1,2},{3,4}},{{5,6},{7,8}}};
内存中的对应顺序也是一样。完全直接就用一个指针操作就可以了,然后只要指针移到对应的位置上,就可以访问任何一维的任何一个元素。
至于二重指针的问题, 实际上就是说的指向指针的指针。也就是说,我们定义一个二重指针
int **p;
它的意义就是:
...
p ---> | 0x1000 | 0x0010 this is a pointer too ---
| 20 | 0x0011 |
| ... | |
| 2012 | 0x1000 data <---
...
也就是说 (*p)的内容只是一个指针而已
当你在调用
int a[2][3];
func((int **) a, 2, 3);
的时候,实际上任何一个数组名只能当作一个一重指针使用而已。注意之前的说法,程序会认为
a[0][0]的内容视为一个指针——而实际上你的a[0][0]由于数组刚刚初始化,有可能是0,有可能是别的数——我们假设它是a[0][0] = 0吧,那么,你的func操作就把0 当作指针, 然后对 0 地址的内容进行操作 —— 你觉得结果会是什么?
因此,二维数组和二维指针是两回事,如上所述,任何一个数组名只能当作一个一重指针使用。
因此上面的func函数应该如下改写
void func(int *p, int n, int m)
{
for(int i=0; i < n; i++)
for(int j=0; j < m; j++)
{
p[i*n + j]=i+j;
cout << p[i*n + j] < }
}
阅读(2703) | 评论(0) | 转发(0) |