二维数组(多维数组)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

跟晓雅数码学单片机之二维数组(多维数组)作为函数参数传递 (2013-05-06 15:42:35)转载▼
标签: it
跟晓雅数码学单片机之二维数组(多维数组)作为函数参数传递
二维数组(多维数组)作为函数参数如何传递呢?这里以二维数组作为例子讲解,多维数组以此类推。
方法1:将二维数组依旧当作二维数组来处理
依据:我们知道二维数组中a[i]=*(a+i),由此得a[i]+j=*(a+i)+j。由于*(a+i)+j是二维数组a的i行j列元素的地址,所以,该元素的值等于*(*(a+i)+j)。
例1:
#include
void PrintArrayMothod1(int test_array[3][3]) //形参依然以二维数组的形式声明
//可以省略行:void PrintArrayMothod1(int test_array[][3])也是可以的,但列是绝对不能少的
{
int i,j;
int tmp;

for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
tmp=*(*(test_array+i)+j); //得到第i行第j列的元素的值
printf("%d ",tmp);
if(0==((j+1)%3))
printf("\n");
}
}

int main()
{
int TestArray[3][3]={ {1,2,3} , {4,5,6} , {7,8,9} };

PrintArrayMothod1(TestArray); //函数调用,数组名代表数组的起始地址
sleep(5000);
return 0;
}

优点:形参一目了然就知道是多少维的数组;对数据的处理按照二维数组处理的方法即可
缺点:当实参的行或列发生变化,需要重写调用的函数

方法2:利用指向数组的指针
依据:C语言允许把一个二维数组分解为多个一维数组来处理。二维数组可以看作是数组的数组。
二维数组指针变量说明的一般形式为:类型说明符 (*指针变量名)[长度]
其中“类型说明符”为所指数组的数据类型。“*”表示其后的变量是指针类型。“长度”表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。应注意“(*指针变量名)”两边的括号不可少,如缺少括号则表示是指针数组,意义就完全不同了。


例2:
#include
void PrintArrayUsePtr(int (*prt_test)[3],int row,int colum)
{
int i,j;
int tmp;
for(i=0;ifor(j=0;j{
tmp=*(*(prt_test+i)+j); //因为用的是指向二维数组的指针变量,所以获得元
//素的值依然用*(*(a+i)+j)这种形式,a为数组名
printf("%d ",tmp);
if(0==((j+1)%colum))
printf("\n");
}
}

int main()
{
int TestArray[3][3]={ {1,2,3} , {4,5,6} , {7,8,9} };
PrintArrayUsePtr(TestArray,3,3);
sleep(5000);
return 0;
}
优缺点和上面差不多,调用的维数也是固定的。

方法3:利用普通的指针变量
依据:指针是存放地址的;在内存中二维数组是连

续存放的。例3:
#include
PrintArrayUseComPtr(int *test_array,int row, int colum)
{
int i;
int *tmp;
{
for(i=0;i{
tmp=*(test_array+i); //利用内存的连续存放挨个取值
printf("%d ",tmp);
if(0==((i+1)%colum))
printf("\n");
}
}
}

int main()
{
int TestArray[3][3]={ {1,2,3} , {4,5,6} , {7,8,9} };
int TestArray2[4][5]={ {1,2,3,4,5} , {1,2,3,4,5} , {1,2,3,4,5} };

PrintArrayUseComPtr(TestArray,3, 3);
PrintArrayUseComPtr(TestArray2,4, 5);
sleep(5000);
return 0;
}

缺点:看不出是二维数组,不够直观,比如要修改某一个元素的值就不方便了。
优点:数组的行数和列数可变

方法4:利用指向指针的指针变量或者说利用编译器原理
依据:从计算机编译原理知道编译器是这样处理数组的:
对于数组 int a[m][n];
如果要取a[i][j]的值(i>=0 && i例4:
#include
void PrintArrayUsePP(int **ptr_test,int row,int colum)
{
int i,j;
int tmp;
printf("use PP\n");
for(i=0;ifor(j=0;j{
tmp=*(ptr_test+colum*i+j); // tmp=*((int *)ptr_test+colum*i+j);
// tmp=*(*(ptr_test+i)+j); //这样写就错了
printf("%d ",tmp);
if(0==((j+1)%colum))
printf("\n");
}
printf("\n\n");
}

int main()
{
int TestArray[3][3]={ {1,2,3} , {4,5,6} , {7,8,9} };
int TestArray2[4][5]={ {1,2,3,4,5} , {1,2,3,4,5} , {1,2,3,4,5} };
PrintArrayUsePP(TestArray,3,3);
PrintArrayUsePP(TestArray2,4,5);
sleep(5000);
return 0;
}

注意tmp=*(ptr_test+colum*i+j);必须这样写编译器才能够识别,否则出错。
tmp=*(*(ptr_test+i)+j); //这样写就错了
从这里也可以看出,虽然在调用函数的时候传递的都是二维数组的首地址,但是不同的形参形式表示的意义是不一样的,因此读取数组中的某个元素的值的方法也就可能不一样。

优点:数组的列数和行数可变,同时需要修改数组中的某个元素也比较直观,比如修改TestArray2[2][2]这个值为100,可以令*(ptr_test+colum*2+2)=100;即可。
缺点:因为是直接对内存操作,如果不小心访问越界了是不会提示错误的(用指针操作都可能发生)。比如函数中出现*(ptr_test+colum*5+2)=100;也不会报错,但这个地址超出了数组TestArray和TestArray2的范围。因此在使用指针的时候要特别注意不要越界访问。

其他说明:
(1) 上面的程序是在aha-c(啊哈C乔布斯永久纪念版)上面运行成

功的,因为该软件会默认有sleep这个函数,所以在其他平台可能不需要这个函数;
(2) 为了在某些平台可以无差错运行,可能需要在某些地方进行强制转换,类似这样的代码:PrintArrayUsePP((int *)TestArray,3,3)或者tmp=*((int *)ptr_test+colum*i+j)等;
(3) 对于例子程序中的临时变量tmp是为了看的更简洁才定义的,可以不定义这个变量而直接用printf("%d ",*(ptr_test+colum*i+j));输出。

以上都是个人理解和总结,若有错误,欢迎指正,谢谢!

相关文档
最新文档