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

这里有一篇文章  写的很好http://blog.csdn.net/f81892461/article/details/8974087

该文章中有一句话  总之就是:数组无法作为参数,总会被编译器将地址赋值给形参指针的,即使指针定义成数组形式,也还是指针。然后各种差别都是由数组和指针不同的定位元素的方式导致的。

这句话说的很对啊,数组做形参的是时候都是被当成指针来处理的。不明白这句话的可以看一下,参考文章链接里的那幅图,注意比较一下下图中的两个:data+1,第一个data+1指向的是元素data[1][0]的地址,而第二个data+1指向的是元素data[0][4],为什么呢?就是因为data数组做形参的时候被当成指针处理了,在32位数组中任何类型的指针都占4个字节,所以data+1和data相差4个字节。

顺遍贴一下文中的代码

#include <stdio.h>;

#include <stdlib.h>;

void fun(char **data);

int main(void)

{

       char data[2][5];

       printf("in main
");

       printf("data:%p
", data);

       printf("*data:%p
", *data);

       printf("data+1:%p
", data+1);

       printf("*(data+1):%p
", *(data+1));

       printf("data[1]:%p
", data[1]);

       printf("&data[1][3]:%p
", &data[1][3]);

       fun((char**)data);
       getchar();
       exit(0);

}

void fun(char **data)

{

       printf("in fun
");

       printf("data:%p
", data);

       printf("*data:%p
", *data);

       printf("data+1:%p
", data+1);

       printf("*(data+1):%p
", *(data+1));

       printf("data[1]:%p
", data[1]);

       printf("&data[1][3]:%p
", &data[1][3]);

       return ;

}

那么,既然上面的代码里的方法不行,怎么样才行?

又看了一篇文章http://blog.csdn.net/xinshen1860/article/details/20620227

文中提到了:

int data[3][4] = { {1, 2, 3, 4}, {5, 5, 7, 8}, {9, 10, 11, 12} }
int total = sum(data, 3);
int sum( int (*arr) [4], int size);
//其中的括号是必不可少的,因为下面的声明将声明一个由四个指向int的指针组成的数组,而不是一个指向由4个int组成的数组的指针。

int *arr[4];   //声明了一个指针数组,这个数组包含4个int指针变量
int (*arr)[4] //声明了一个指针变量,这个指针指向由4个int组成的数组int sum(int arr[][4], int size);

还有另外一种声明格式,含义与上述正确原型完全相同,但是可读性更强:

int sum(int arr[][4], int size);

还有一篇文章http://blog.163.com/tianhit@yeah/blog/static/165747821201052195212719/

文章分别对一维数组和二维数组做函数参数进行了讨论并给出了代码,且对二维数组的引用做形参进行了讨论,指出

int   fun(int (&a)[2][3])         //ok,引用作形参,数组作引用形参,必须指定清楚所有维数
// int  fun(int (&a)[ ][3],int n)     //error C2265: '<Unknown>' : reference to a zero-sized array is illegal
// int  fun(int &a[2][3])             // error C2234: '<Unknown>' : arrays of references are illegal

但是注意一种情况,即它本身就是一个指向指针的指针的时候:比如下面的代码 ,代码来字《剑指offer》,完成顺时针打印矩阵的功能,在test函数里,它直接利用指针的申请的空间,在函数的参数列表中也是直接以指针的指针的形式出现,在test函数里调用其他函数时,是可以直接调用的,如printMatrix(numbers, columns, rows); 这句代码。

void PrintMatrixInCircle(int **a,int columns,int rows,int start)
{
    int endX=columns-1-start;
    int endY=rows-1-start;

    //从左到右打印一行
    for (int i=start;i<=endX;i++)
    {
        int number=a[start][i];
        cout<<number<<"  ";
    }

    //从上到下打印一行
    if (start<endY)
    {
        for (int i=start+1;i<=endY;i++)
        {
            int number=a[i][endX];
            cout<<number<<"  ";
        }
    }

    //从右向左打印一行
    if (start<endX&&start<endY)
    {
        for (int i=endY-1;i>=start;i--)
        {
            int number=a[endY][i];
            cout<<number<<"  ";
        }
    }

    //从下到上打印一行
    if (start<endX&&start<endY)
    {
        for (int i=endY-1;i>=start+1;i--)
        {
            int number=a[i][start];
            cout<<number<<"  ";
        }
    }
    cout<<endl;
}

void  printMatrix(int **a,int columns,int rows)    //行和列
{
    if (a==NULL||columns<=0||rows<=0)
        return;
    int start=0;
    while(columns>start*2&&rows>start*2)
    {
        PrintMatrixInCircle(a,columns,rows,start);
        start++;
    }
}


// ====================测试代码====================
void Test(int columns, int rows)    //row行   column列
{
    printf("Test Begin: %d columns, %d rows.
", columns, rows);

    if(columns < 1 || rows < 1)
        return;

    int** numbers = new int*[rows];        //int后的*不是乘号  是个指针运算符
    for(int i = 0; i < rows; ++i)
    {
        numbers[i] = new int[columns];
        for(int j = 0; j < columns; ++j)
        {
            numbers[i][j] = i * columns + j + 1;
            cout<<numbers[i][j]<<"  ";
        }
    }
    cout<<endl;
    printMatrix(numbers, columns, rows);
    printf("
");

    for(int i = 0; i < rows; ++i)
        delete[] (int*)numbers[i];

    delete[] numbers;
}
原文地址:https://www.cnblogs.com/audi-car/p/4645896.html