C++二维数组做函数参数
二维数组做函数参数的形式主要有:
/对于一个m行n列int元素的二维数组
//函数f的形参形式
f(int daytab[m][n]) {...}
//以下两种可以忽略行数
f(int daytab[][n]) {...}
f(int (*daytab)[n]) {...}
这里都不能忽略第二维的大小。主要 原因是二维数组在栈内分配的内存是连续的,它的每一行都有相同的元素,这样,array[i][j] 和 *(*(array +i) +j)是一样的,程序是知道array+i的i实际上偏移了i*N个单位,这也导致了在二维数组array[3][3]中,使用下标array[2][1]和array[1][4]是访问的同一个元素,尽管后者的下标对于一个3*3矩阵来说是非法的,但这并不影响访问。
以指针的指针来表示二维数组,动态分配内存的形式:
这样的方法可以让第二维(即每一行)的大小不必完全相等,严格来说,并不是二维数组,但这也有对应的好处。以这样分配的内存,可以直接以指针的指针作为函数参数,并在子函数中用双下标直接访问。
#include <iostream>
#include <stdio.h>
void out(double **a,int m, int n)
{
int i, j;
double b=0.0;
for(i=0; i<m; i++)
{
for (j=0; j<n; j++)
{
a[i][j] = b;
b += 1.2;
printf("%5.1f",a[i][j]);
}
std::cout << std::endl;
}
}
int main(int argc, char * agrv)
{
int i, j, m=2, n=3;
double **a;
a = new double*[m];
for (i=0; i<m; i++)
a[i] = new double[n];
out(a,m,n);
return 1;
}
====================================================================================================================================================================================================================================================================================================================================================================
AlanTu
随笔 - 953, 文章 - 0, 评论 - 3, 引用 - 0
C语言二维数组作为函数的参数
前言:今天在实现装配线调度程序时候,用到了二维数组,并将其作为函数的参数。在写程序的时候,遇到一些问题,即二维数组做函数的参数应该如何正确表示。我写程序的错误如下程序所示:
1 #include <cstdio>
2 void print(int *a[3]) 3 { 4 printf("%d\n",a[0][0]); 5 } 6 7 int main() 8 { 9 int a[2][3] = {1,2,3,4,5,6}; 10 print(a); 11 return 0; 12 }
编译程序时候,在第10行提示错误信息:|10|error: cannot convert 'int (*)[3]' to 'int**' for argument '1' to 'void print(int**)'|。根据错误提示我明白了, int *a[3]表示一个一维数组,数组的数据类型为整型指针(int*),数组的大小为3,这是因为[]的优先级高于*的优先级。如是我将程序改写如下,顺利通过编译,得到正确结果。
1 #include <cstdio> 2 void print(int (*a)[3]) //用括号将指针括起来 3 { 4 printf("%d\n",a[0][0]); 5 } 6 7 int main() 8 { 9 int a[2][3] = {1,2,3,4,5,6}; 10 print(a); 11 return 0; 12 }
下面来总结一下二维数组作为函数参数该如何表示。
1、二维数组的概念
在C语言中,二维数组实际上是一种特殊的一维数组,它的每个元素也是一个一维数组。因此,二维数组下标形式正确写法如下:int arrays[i][j]。数组元素是按照行顺序存储的,因此当按存储顺序访问树时,最右边的数组下标(列)变化的最快。
2、二维数组作为函数参数
规定:如果将二维数组作为参数传递给函数,那么在函数的参数声明中必须指明数组的列数,数组的行数没有太大关系,可以指定也可以不指定。因为函数调用时传递的是一个指针,它指向由行向量够成的一维数组。因此二维数组作为函数参数正确写法如下所示:
void Func(int array[3][10]);
void Func(int array[ ][10]);
因为数组的行数无关紧要,所以还可以写成如下形式:
void Func(int (*array)[10]); 注意*array需要用括号括起来。
这种形式的声明参数是一个指针,它指向具有10个元素的一维数组。因为[]的优先级比*的优先级高,故*array必须用括号括起来,否则变成了
void Func(int *array[10]);
这时候参数相当于是声明了一个数组,该数组有10个元素,其中每个元素都是一个指向整型对象的指针。
但是不能把第二维或者更高维的大小省略,如下面的定义是不合法的:
void Func(int array[ ][ ]);
因为从实参传递来的是数组的起始地址,在内存中按数组排列规则存放(按行存放),而并不区分行和列,如果在形参中不说明列数,则系统无法决定应为多少行多 少列,不能只指定一维而不指定第二维,下面写法是错误的:
void Func(int array[3][ ]);
实参数组维数可以大于形参数组,例如形参数组定义为:
void Func(int array[3][10]);
而实参数组定义为:int array[5][10]; 进行函数调用Func(array)时,由于数组在内存中是连续存放的,虽然形参与实参数组行数不对应,但是列数是相同的,具有相同的起始地址,这样可以访问到后续的值。如下述程序:
1 #include <stdio.h> 2 3 void print_array(int *array, int len) 4 { 5 int i = 0; 6 for ( ; i < len; i++) { 7 printf("%d ",array[i]); 8 } 9 putchar('\n'); 10 } 11 12 void func(int array[3][10]) 13 { 14 print_array(array[0], 10); 15 print_array(array[1], 10); 16 print_array(array[2], 10); 17 print_array(array[3], 10); 18 print_array(array[4], 10); 19 } 20 21 int main() 22 { 23 int array[5][10] = { 24 {0,1,2,3,4,5,6,7,8,9}, 25 {10,11,12,13,14,15,16,17,18,19}, 26 {20,21,22,23,24,25,26,27,28,29}, 27 {30,31,32,33,34,35,36,37,38,39}, 28 {40,41,42,43,44,45,46,47,48,49} 29 }; 30 func(array); 31 return 0; 32 }
参考资料:
1、http://www.cnblogs.com/yangxi/archive/2012/03/22/2411452.html
2、K&R《C语言程序设计》第二版P95-P97