二维动态数组定义及二维静态数组与**P的区别
2011-11-21 22:05
543 查看
矩力集成2008年校园招聘笔试题:动态申请一个二维数组存储图像阵列
传统的解决方案是分配一个指针数组, 然后把每个指针初始化为动态分配的 ``列"。 以下为一个二维的例子:
//typedef int (*arraypoiter)[ncolumns];
int **dynamic_alloc_arrays(unsigned int nrows,unsigned int ncolumns)
{
unsigned int i;
int **array = (int **)malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
array[i] = (int *)malloc(ncolumns * sizeof(int));
printf("array=0x%x/n",(int)array);
for(i=0;i<nrows;i++)
{
printf("array[%d]=0x%x/n",i,(int)array[i]);
}
printf("/n");
return array;
}
void main(void)
{
int **test_allocate;
unsigned int nrows=3;
unsigned int ncolumns=4;
test_allocate = dynamic_alloc_arrays(nrows,ncolumns);
printf("test_allocate=%x/n",test_allocate);
}
/*
array=911c70
array[0]=911c30
array[1]=911bf0
array[2]=911bb0
test_allocate=911c70
*/
当然, 在真实代码中, 所有的 malloc 返回值都必须检查。你也可以使用 sizeof(*array) 和sizeof(**array) 代替 sizeof(int *) 和 sizeof(int)(因为*array的类型为int *,**array的类型为int)。
你可以让数组的内存连续, 但在后来重新分配列的时候会比较困难, 得使用一点指针算术:
int **dynamic_alloc_arrays(unsigned int nrows,unsigned int ncolumns)
{
unsigned int i;
int **array = (int **)malloc(nrows * sizeof(int *));
array[0] = (int *)malloc(nrows * ncolumns * sizeof(int));
for(i = 1; i < nrows; i++)
array[i] = array[0] + i * ncolumns;
printf("array=0x%x/n",(int)array);
for(i=0;i<nrows;i++)
{
printf("array[%d]=0x%x/n",i,(int)array[i]);
}
printf("/n");
return array;
}
void main(void)
{
int **test_allocate;
unsigned int nrows=3;
unsigned int ncolumns=4;
test_allocate = dynamic_alloc_arrays(nrows,ncolumns);
printf("test_allocate=%x/n",test_allocate);
}
/*
array=911c70
array[0]=911c10
array[1]=911c20
array[2]=911c30
test_allocate=911c70
*/
在两种情况下, 动态数组的成员都可以用正常的数组下标 arrayx[i][j] 来访问 (for 0 <= i <nrows 和 0 <= j <ncolumns)。
另一种选择是使用数组指针:
int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));
但是这个语法变得可怕而且运行时最多只能确定一维。因为NCOLUMNS必须为定值
××××××××××××××××××××××××××××××××××××××
C语言里,数组名是被看作指针来使用的,一维数组是指针,二维数组是指向指针的指针,三维是......... 真的是这样的吗??看下面的例子:
void show (int * * info, int x, int y) //打印一个x*y的数组的内容
{
int i, j;
for (i=0;i<x;i++)
{
for (j=0;j<y;j++)
{
printf ("%d ",info[i][j]);
}
printf ("/n");
}
}
void Function (void)
{
int as[10][10];
show (as,10,10);
// error C2664: 'show' : cannot convert parameter 1 from 'int [10][10]' to 'int ** ' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
}
在C中没有安全类型检查,上述程序只是warning,但是程序运行会崩溃
在C++中,根本就无法编译通过,即as[10][10]和int * *根本不是一个类型
为什么?在c中,二维数组虽然是定义为指向指针的指针,但是实际上被指向的指针是不存在的,即没有一个内存来存储这个指针,只是在执行as
时返回一个指针罢了,as所指的不过是存放数组内容的地址!!
实际上从上面**P和动态二维数组的使用即可看出来,**P和静态二维数组的本质区别!
传统的解决方案是分配一个指针数组, 然后把每个指针初始化为动态分配的 ``列"。 以下为一个二维的例子:
//typedef int (*arraypoiter)[ncolumns];
int **dynamic_alloc_arrays(unsigned int nrows,unsigned int ncolumns)
{
unsigned int i;
int **array = (int **)malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
array[i] = (int *)malloc(ncolumns * sizeof(int));
printf("array=0x%x/n",(int)array);
for(i=0;i<nrows;i++)
{
printf("array[%d]=0x%x/n",i,(int)array[i]);
}
printf("/n");
return array;
}
void main(void)
{
int **test_allocate;
unsigned int nrows=3;
unsigned int ncolumns=4;
test_allocate = dynamic_alloc_arrays(nrows,ncolumns);
printf("test_allocate=%x/n",test_allocate);
}
/*
array=911c70
array[0]=911c30
array[1]=911bf0
array[2]=911bb0
test_allocate=911c70
*/
当然, 在真实代码中, 所有的 malloc 返回值都必须检查。你也可以使用 sizeof(*array) 和sizeof(**array) 代替 sizeof(int *) 和 sizeof(int)(因为*array的类型为int *,**array的类型为int)。
你可以让数组的内存连续, 但在后来重新分配列的时候会比较困难, 得使用一点指针算术:
int **dynamic_alloc_arrays(unsigned int nrows,unsigned int ncolumns)
{
unsigned int i;
int **array = (int **)malloc(nrows * sizeof(int *));
array[0] = (int *)malloc(nrows * ncolumns * sizeof(int));
for(i = 1; i < nrows; i++)
array[i] = array[0] + i * ncolumns;
printf("array=0x%x/n",(int)array);
for(i=0;i<nrows;i++)
{
printf("array[%d]=0x%x/n",i,(int)array[i]);
}
printf("/n");
return array;
}
void main(void)
{
int **test_allocate;
unsigned int nrows=3;
unsigned int ncolumns=4;
test_allocate = dynamic_alloc_arrays(nrows,ncolumns);
printf("test_allocate=%x/n",test_allocate);
}
/*
array=911c70
array[0]=911c10
array[1]=911c20
array[2]=911c30
test_allocate=911c70
*/
在两种情况下, 动态数组的成员都可以用正常的数组下标 arrayx[i][j] 来访问 (for 0 <= i <nrows 和 0 <= j <ncolumns)。
另一种选择是使用数组指针:
int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));
但是这个语法变得可怕而且运行时最多只能确定一维。因为NCOLUMNS必须为定值
××××××××××××××××××××××××××××××××××××××
C语言里,数组名是被看作指针来使用的,一维数组是指针,二维数组是指向指针的指针,三维是......... 真的是这样的吗??看下面的例子:
void show (int * * info, int x, int y) //打印一个x*y的数组的内容
{
int i, j;
for (i=0;i<x;i++)
{
for (j=0;j<y;j++)
{
printf ("%d ",info[i][j]);
}
printf ("/n");
}
}
void Function (void)
{
int as[10][10];
show (as,10,10);
// error C2664: 'show' : cannot convert parameter 1 from 'int [10][10]' to 'int ** ' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
}
在C中没有安全类型检查,上述程序只是warning,但是程序运行会崩溃
在C++中,根本就无法编译通过,即as[10][10]和int * *根本不是一个类型
为什么?在c中,二维数组虽然是定义为指向指针的指针,但是实际上被指向的指针是不存在的,即没有一个内存来存储这个指针,只是在执行as
时返回一个指针罢了,as所指的不过是存放数组内容的地址!!
实际上从上面**P和动态二维数组的使用即可看出来,**P和静态二维数组的本质区别!
相关文章推荐
- C/C++面试之算法系列--二维动态数组定义及二维静态数组与**P的区别
- 二维动态数组定义及二维静态数组与**P的区别
- 二维动态数组定义及二维静态数组与**P的区别
- 二维动态数组定义及二维静态数组与**P的区别
- DelphiXe 中静态数组TByteArray和动态数组TBytes /array of byte 的区别
- C#超基础:静态数组与动态数组的区别
- DelphiXe 中静态数组TByteArray和动态数组TBytes /array of byte 的区别
- 静态视图 动态视图 区别 定义
- 关于[]静态数组和new分配的动态数组的区别
- 数组和指针、数组指针和指针数组、函数指针和指针函数、数组标识符的意义、静态和动态创建的数组的本质区别、标识符类型判断方法
- malloc动态分配与数组静态分配还有一个最重要的区别:
- malloc动态分配与数组静态分配的区别:
- c#数组练习:静态(规则与不规则)与动态数组的定义与输出
- 静态数组和动态数组的区别
- 静态数组与动态数组的区别
- 静态数组和动态数组的区别
- C++中关于[]静态数组和new分配的动态数组的区别分析
- 动态创建二维vector数组 C和C++ 及指针与引用的区别
- C++中关于一维、二维、三维动态数组的定义
- 直接定义的二维数组与动态非配分配的二维数组 数组名代表的指针的一些区别