-
二维数组定义以及动态分配空间
(
转
)
下面三种定义形式怎么理解?怎么动态分配空间?
(1)
、
int
**Ptr;
(2)
、
int
*Ptr[
5
];
我更喜欢写成
int*
Prt[5];
(3)
、
int
(
*Ptr
)[
5
];
此文引自网上,出处不详,但是觉得非常好。略改了一点。
<
/p>
多维数组一向很难,一般都采用一维数组,但是一旦要用到还真是头疼。
< br>
闲话少说,这里我就以三个二维数组的比较来展开讨论:
(1)
、
int
**Ptr;
(2)
、
int
*Ptr[
5
];
我更喜欢写成
int*
Prt[5];
(3)
、
int
(
*Ptr
)[
5
];
以上三例都是整数的二维数组,都可以用形如
Ptr[
1
][
1
]
的
方式访问其内容;但它们的差别却是很大的。下面我从四个方
面对它们
进行讨论:
一、内容:
它们本身都是指针,它们的最终内容都是整数。注意我这里说
的是最终内容,而不是中间内容,比如你写
Ptr[
0
]
,对于三者来说,
其内容都是一个整数指针,即
int
*
;
Ptr[
1
][
1
]
这样的形式才
是其最终内容。
二、意义:
(1)
、
int
**Ptr
表示指向
一群
指向整数的指针的指针。
(2)
、
int
*Ptr[
5
]
表示指向
5
个指向整数的指针的指针
,
或者说
P
tr
有
5
个指向
一群
整数
的
指针,
Ptr
是这
5
< br>个指针构成的数组的地址
(3)
、
int
(
*Ptr
)[
5
]
表示指向
一群
指向
5
个整数数组的指针的指针。
三、所占空间:
(1)
、
int
**Ptr
和
(3)
、
int
(
*Ptr
)[
5
]
一样,在
32
位平台里,
都是
4
字节,
即一个指针。
但
(2)
、
int
*Ptr[
5
]
不同,它是
5
个指针,它占
5
*
4
=
20
个字节的内存空间。
四、用法:
(1)
、
int
**Ptr
因为是指针的指针,需要两次内存分配才能使用其最终内容。首
先,
Ptr
=
(
int
**
)new
int
*[
5
]
;这样分配好了以后,它和
(2)
的
意义相同了;然后要分别对
5
个指针进行内存分配,例如:
Ptr[
0
]
=
new
int[
20
];
它表示为第
0
个指针分配
20
个整数,分配好以后,
Ptr[
0
]
为指
向
20
个整数的数组。这时可以使用下标用法
Ptr[
0
][
0
]
到
Ptr[
0
][
19
]
了。
如果没有第一次内存分配,该
Ptr
是个
野
指针,是不能使用
的,如果没有第二次内存分配,则
Ptr[
0
]
< br>等也是个
野
指针,也
是不能用的。当然,
用它指向某个已经定义的地址则是允许的,那是另外
的用法(类似于
借鸡生蛋
的做法),这里不作讨论(下同)。
例子:
C
语言:
//
动态分配二维数组空间
{
m_iHight=10;//
二维数组的高度
m_i;//
二维数组的宽度
//
动态分配一个二维数组
m_ppTable
内存空间
//
其类型为
int
//m_ppTable
指向该数组
int
**m_ppTable;
m_ppTable=new
int
*[m_iHight];
//
动态
分配
m_iHight
个类型为
int
*
的内存空间
//
分配的是行地址空间
for(int
i=0;i
m_ppTable[i]=
new
int[m_iWidth];
//
动态分配
m_iWidth
个类
型为
int
的内存空间
//
分配的是某行的数值空间
}
//
由此分配的二维数组空间并非是连续的
//
可以使用
m_ppTable[row][col]
来给该二维数组赋值
//
其中
0<=row
//
释放所分配的内存空间
{
for(int
i=0;i
delete[m_iWidth]m_ppTable[i];
//
以行为单位释放数值空间
delete
[m_iHight]m_ppTable;
//
释放行地址空间
}
int
**a;
a=(int
**)calloc(sizeof(int
*),n);
for
(i=0;i
a[i]=(int
*)calloc(sizeof(int),n);
这样就可以了
使用的时候就和普通的二维数组一样
最后用
for(i=0;i
cfree(a[i]);
cfree(a);
释放内存
就可以了
(2)
、
int
*Ptr[
5
]
这样定义的话,编译器已经为它分配了
5
个指针的空间,这相当
于
(1)
中
的第一次内存分配。根据对
(1)
的讨论可知,显然要对其进行
一次
内存分配的。否则就是
野
指针。
(3)
、
int
(
*Ptr
)[
5
]
这种定义我觉得很费解,不是不懂,而是觉得理解起来特别吃力,
也许是我不太习惯这样的定义吧。怎么描述它呢?它的意
义是
一群
指针,每个指针都是指向一个
5
个整数的数组。如果想分配
k
个指针,
这样写:
Ptr
=
(
int
(
*
)[
5
]
)
new
int[
5
*
k
]
。
这是一次性的内存分配。分配好以后,
Ptr
指向一片连续的地址空间,
其中
Ptr[
0
]
指向第
0
个
5
个整数数组的首地址,
Ptr[
1
]
指向第
1
个
5
个整数数组的首地址。
综上所述,我觉得可以这样理解它们:
int
**
Ptr
<==>
int
Ptr[
x
][
y
];
int
*Ptr[
5
]
<==>
int
Ptr[
5
][
x
];
int
(
*Ptr
)[
5
]
<==>
int
Ptr[
x
][
5
];
这里
x
和
y
是表示若干的意思。
_______
__________________________________________________
______
1.
C
语言动态分配二维数组
(1)
已知第二维
Code-1
char
(*a)[N];
//
指向数组的指针
a
=
(char
(*)[N])malloc(sizeof(char
*)
*
m);
printf(
sizeof(a));
//4
,指针
printf(
sizeof(a[0]))
;
//N
,一维数组
free(a);
(2)
已知第一维
Code-2
char*
a[M];
//
指针的数组
< br>
int
i;
for(i=0;
)
sizeof(a)); <
br> <
br>
i
i++)
a[i]
=
(char
*)malloc(sizeof(char)
*
n);
printf(
sizeof(a));
//4*M
,指针数组
printf(
sizeof(a[
0]));
//4
,指针
for(i=0;
i
i++)
free(a[i]);
(3)
已知
第一维,一次分配内存
(
保证内存的连续性
Code-3
char*
a[M];
//
指针的数组
int
i;
a[0]
=
(char
*)malloc(sizeof(char)
*
M
*
n);
for(i=1;
i
i++)
a[i]
=
a[i-1]
+
n;
printf(
sizeof(a));
//4*
M
,指针数组
printf(
sizeof(a[0]));
//4
,指针
free(a[0]);
(4)
两维都未知
Code-4
char
**a;
int
i;
a
=
(char
**)malloc(sizeof(char
*)
*
m);
//
分配指针数组
for(i=0;
i
i++)
{
a[i]
=
(char
*)malloc(sizeof(char)
*
n);
//
分配每个指针所指向的数组
}
printf(
sizeof(a));
//4
,指针
printf(
sizeof(a[0]));
//4
,指针
for(i=0;
i
i++)
{
free(a[i]);
}
free(a);
(5)
两维都未知
,一次分配内存
(
保证内存的连续性
)
Code-5
char
**a;
int
i;
a
=
(char
**)malloc(sizeof(char
*)
*
m);
//
分配指针数组
a[0]
=
(char
*)malloc(sizeof(char)
*
m
*
n);
//
一次性分配所有空间
for(i=1;
i
i++)
{
a[i]
=
a[i-1]
+
n;
}
printf(
sizeof(a));
//4
,指针
printf(
sizeof(a[0]));
//4
,指针
free(a[0]);
free(a);
2.C++
动态分配二维数组
(1)
已知第二维
Code-6
char
(*a)[N];
//
指向数组的指针
a
=
new
char[m][N];
printf(
//4
,指针
printf(
sizeof(a[0]));
//N
,一维数组
delete[]
a;
(2)
已知第一维
Code-7
char*
a[M];
//
指针的数组
for(int
i=0;
i
i++)
a[i]
=
new
char[n];
printf(
s
izeof(a));
//4*M
,指针数组
printf(
sizeof(a[0]));
//4
,指针
for(i=0;
i
i++)
delete[]
a[i];
-
-
-
-
-
-
-
-
-
上一篇:二维数组定义以及动态分配空间(精)
下一篇:1553B简单介绍与分析