二维数组作为函数参数深度详解



       前几天和同学讨论数组作为函数参数,感觉各种困惑。花了一些时间在网上查看了一些资料,并加上自己的理解。记录一下!

一. 指向指针的指针和指向数组的指针

很多人以为“指向数组的指针”就是“指向指针的指针”,于是有人写这样的代码:

int a[3][4];

int **p = a; //错误

数组实际类型是int
[3][4],在作为右值时可以被转化为int (*)[4]
,它们都和int **不同,自然不可用。

那么,你要用一个指针来指向a,就要用一个能表示 " 数组 ” 的指针,以下代码是正确的:int
(*p)[4] = a; p是指向一维数组的指针,并且这个一维数组有4个元素。

a[0][0] 需要一个指向整型的指针 :int *p = &a[0][0];

a[0]     需要一个指向数组的指针 :int (*p)[4] = &a[0]; ( 同 int (*p)[4] =  a ,

[4]不能少,因为指向数组的指针必须知道他所指向的数组的维度 )

a         需要一个指向数组的数组的指针,即指向二维数组的指针: int (*p)[3][4] = &a;

测试:

 

int a[3][4];

 int (*p1)[4] = a;

 int (*p2)[3][4] = &a;

 cout<<a<<endl;

 cout<<p1+1<<endl;

 cout<<p2+1<<endl;

输出:

    从结果可以看出p1+1偏移了一行的长度,p2+1偏移了整个数组的长度。

 二. 二维数组作为函数参数

数组做为形参时,退化为指针

三维数组,退化为指向二维数组的指针

二维数组,退化为指向一维数组的指针

一维数组,退化为指向类型(如int)的指针

1,这种方式形参为一级指针,即指向整型的指针,这个简单。

int func(int *array, int m, int n) {

int i,j;

cout<<sizeof(array)<<endl;

cout<<sizeof(array[0])<<endl;

for(i=0;i<m;i++) {

for(j=0;j<n;j++)

printf("\t%d", *(array +i*n +j));

printf("\n");

}

return 0;

}

return 0;

}

int main(int argc,char** argv)
{

int m=3,n=3,i;

int array[][3] = {{1,2,3},{4,5,6},{7,8,9}};

func(*array,m,n); //或者func2((int
*)array,m,n);

int b[2][3];

return 0;

}

输出:

2. 这种方式是实参转化为指向数组的指针 (即: (int*)[])

int func(int array[][3], int m, int n) {

int i,j;

cout<<sizeof(array)<<endl;

cout<<sizeof(array[0])<<endl;//输出每一行的大小

for(i=0;i<m;i++) {

for(j=0;j<n;j++)

printf("\t%d", array[i][j]);

printf("\n");

}

return 0;

}

int main(int argc,char** argv) {

int m=3,n=3,i;

int array[][3] = {{1,2,3},{4,5,6},{7,8,9}};

func(array,m,n);

return 0;

}

输出:

3. 一种错误的方式:

int func1(int **array, int m, int n) {

int i,j;

cout<<sizeof(array)<<endl;

for(i=0;i<m;i++) {

for(j=0;j<n;j++)

printf("\t%d", *(*array +i*n +j));

printf("\n");

}

return 0;

}

int main(int argc,char** argv) {

int m=3,n=3,i;

int array[][3] = {{1,2,3},{4,5,6},{7,8,9}};

func1((int **)array,m,n);

return 0;

}

如前所述,数组array[3][3]作为右值的时候会转化为(int *)[3],若不加强制转换代码是不能编译通过的。

加了以后虽然编译不错,但是运行的时候有非法内存访问。下面详细解析一下这一代码:*(*array
+i*n +j)

当 i=0, j=0时:

*array, 实际上就是取了array这个地址所存的内容,当然就是数组的第一个元素" 1 ",  从而 *array
+i*n +j = 1;

对地址1来解引用还报内存错误吗?

4. 数组的引用作为函数的参数

形参用引用,形式上和指针作为参数差不多,但是可以在函数里面通过sizeof计算数组的大小,

void Test( int (&array)[2][3] )

{

cout << sizeof(array) << endl;

}

int main(int argc,char** argv) {

int b[2][3];

Test(b);

return 0;

}

输出:

参考:

http://blog.sina.com.cn/s/blog_4c3b679a0100e2xb.html

http://www.cnblogs.com/fickleness/p/3148983.html

http://www.cnblogs.com/wuyuegb2312/archive/2013/06/14/3135277.html

时间: 2024-09-30 18:16:58

二维数组作为函数参数深度详解的相关文章

二维数组作为函数参数的几种方法

#include <stdio.h> #define N 5 void fun1(int a[N][N]) { int i,j; for (i=0;i<N;i++) { for (j=0;j<N;j++) { if (i>j) { a[i][j]+=a[j][i]; a[j][i]=0; } } } } void fun2(int **a,int m,int n) { int i,j; for (i=0;i<m;i++) { for (j=0;j<n;j++) {

二维数组做函数参数、指向指针的指针做函数参数

这里有一篇文章  写的很好http://blog.csdn.net/f81892461/article/details/8974087 该文章中有一句话  总之就是:数组无法作为参数,总会被编译器将地址赋值给形参指针的,即使指针定义成数组形式,也还是指针.然后各种差别都是由数组和指针不同的定位元素的方式导致的. 这句话说的很对啊,数组做形参的是时候都是被当成指针来处理的.不明白这句话的可以看一下,参考文章链接里的那幅图,注意比较一下下图中的两个:data+1,第一个data+1指向的是元素dat

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

C++_二维数组作为函数参数的使用方法

二维数组作为函数参数的使用方法 /*01)恒等式:ar2[r][c] == *(*(ar2+r)+c)03) ar2+r指向编号为r的元素,该元素由c个int型(或其他类型)数组成,编号从0开始02)int a[100][4]; ....   int total = sum(a,100); //在主函数中调用sum()函数,使用二维数组中的全部的数据   int total = sum(a,10); //在主函数中调用sum()函数,使用二维数组中的前十行数据   int total = sum

如何将二维数组作为函数参数

如何将二维数组作为函数的参数传递 今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不至于再在这上面浪费时间. 正文: 首先,我引用了谭浩强先生编著的<C程序设计>上面的一节原文,它简要介绍了如何 将二维数组作为参数传递,原文如下(略有改变,请原谅): [原文开始] 可以用二维数组名作为实参或者形参,在被调用函数中对形参数组定义时可以指定所有维数的

二维数组作为函数参数

#include<stdio.h> //#include<> //二位数组作为函数参数时,可以不指定第一个下标 void print_buf(int (*p)[3],int a,int b) //void print_buf(int p[][3],int a,int b) { int i,j; for(i = 0 ; i < a; i++) { for(j = 0; j < b; j++) { printf("p[%d][%d] = %d ",i,j

C++ 数组、二维数组、函数参数

一维数组: 1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 /**为了方便 数组的类型全部都是int类型的*/ 6 int numbers[5] = {1,2,3,4,5}; 7 /**通过指针的方式访问数组*/ 8 int * p = numbers; 9 cout << "普通指针的方式访问:\n"; 10 for (int i = 0; i < 5; i++) 11 co

C++基础知识——二维数组做函数参数

1.确定大小的二维数组 void Func(int array[3][10]); void Func(int array[][10]); 2.不确定大小的二维数组转为二维指针: 从实参传递来的是数组的起始地址,在内存中按数组排列规则存放(按行存放),而并不区分行和列,所以可以转换成二维指针. void Func(int **array, int m, int n); 调用时候要把数组名转换位二维指针 Func((int**)a, 3, 3); 获取具体数组元素 *((int*)array + n

C语言二维数组作为函数的参数

前言:今天在实现装配线调度程序时候,用到了二维数组,并将其作为函数的参数.在写程序的时候,遇到一些问题,即二维数组做函数的参数应该如何正确表示.我写程序的错误如下程序所示: #include <cstdio> void print(int *a[3]) { printf("%d\n",a[0][0]); } int main() { int a[2][3] = {1,2,3,4,5,6}; print(a); return 0; } 编译程序时候,在第10行提示错误信息:|