引例
编写一个程序,初始化一个double类型的3×5二维数组,使用一个处理变长数组的函数将其拷贝至另一个二维数组中。还要编写一个以变长数组为形参的函数以显示两个数组的内容。这两个函数应该能处理任意N×M数组。(《C Primer》10_6 编程练习)
代码如下
void copy2D(int ROW, int COL, double (*)[COLS], double(*)[COLS]);
//声明拷贝二维数组函数
void display(int ROW, int COL, double(*)[COLS]);
//声明显示数组函数
int main(){
double source[3][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
double target[3][5];
copy2D(3,5,source,target);
display(3,5,source);
display(3,5,source);
}
void copy2D(int ROW, int COL, double (*ar)[COLS], double(*new_ar)[COLS]){
int i,j;
for(i=0;i<ROW;i++)
for(j=0;j<COL;j++)
(*(new_ar+i))[j]=(*(ar+i))[j];
//上式可以写为*(*(new_ar+i)+j)=*(*(ar+i)+j)
}
void display(int ROW, int COL, double(*ar)[COLS]){
int i,j;
for(i=0;i<ROW;i++){
for(j=0;j<COL;j++)
printf("%.lf\t",(*(ar+i))[j]);//*(*(ar+i)+j)
}
}
二维数组指针
- 初始化:指针类型 (*数组名)[数组列下标],例如
double (*p)[COL]
,二维数组中列下表定义时不可省略 - 当我们定义一个数组:
double (*p)[COL]
时,*p表示p是一个指针,它指向一个以二维数组每一行为元素的一维数组,p数组每个元素包含COL个子元素 - 对于二维数组指针p,本质上是由二维数组每一行为元素组成的一维数组,它指向数组的第一行地址,*p表示第一行中的所有元素组成一维数组,也就是该数组第一个元素的地址,而**p才表示二维数组的第一个元素的值。数组每一行的地址和每一行的首元素地址相同,即
p==*p
。(*(p+i))[2]
和*(*(p+1)+2)
是等价的 - 对二维数组指针进行加减整数,操作为移动数组的行;进行列操作时要解引用后再进行加减整数操作,如获取二维数组元素
p[1][2]
的指针操作为*(*(p+1)+2)
- 定义二维数组指针时 不可以使用如 double **p的形式,在C中,不支持行列均是变长的二维数组,即无论何时二维数组的列下标一定要有!