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

这里有一篇文章  写的很好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\n");

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

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

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

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

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

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

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

}

void fun(char **data)

{

       printf("in fun\n");

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

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

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

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

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

       printf("&data[1][3]:%p\n", &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/[email protected]/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.\n", 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("\n");

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

    delete[] numbers;
}
时间: 2024-10-19 17:43:49

二维数组做函数参数、指向指针的指针做函数参数的相关文章

二维数组和指向指针的指针

引用地址: http://www.cnblogs.com/stoneJin/archive/2011/09/21/2184211.html 一道面试题引发的问题,首先要知道[]的优先级高于*,题目: char **p,a[6][8]; 问p=a是否会导致程序在以后出现问题?为什么? 直接用程序说明: #include<stdio.h> void main(){ char **p,a[6][8]; p = a; printf("\n");} 编译,然后就会发现通不过,报错:错

C++ 二维数组(双重指针作为函数参数)

本文的学习内容参考:http://blog.csdn.net/yunyun1886358/article/details/5659851 http://blog.csdn.net/xudongdong99/article/details/6723163 1.使用二维数组作为形参的例子: void func(int arr[][10]) { } int main() { int array[10][10]; func(array); //用二维数组名作为实参,调用函数 } 上面的例子可以编译通过,

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

        前几天和同学讨论数组作为函数参数,感觉各种困惑.花了一些时间在网上查看了一些资料,并加上自己的理解.记录一下! 一. 指向指针的指针和指向数组的指针 很多人以为"指向数组的指针"就是"指向指针的指针",于是有人写这样的代码: int a[3][4]; int **p = a; //错误 数组实际类型是int [3][4],在作为右值时可以被转化为int (*)[4],它们都和int **不同,自然不可用. 那么,你要用一个指针来指向a,就要用一个

二维数组和指针数组做形参

先回顾一下二维数组的写法: 1. int array[3][4]; 2. int array[][4]; 3. int (*array)[4]; 不管怎么样,二维的长度是不能省略的,多维数组(不管二维,三维,四维...)最多只能省略第一维的长度; 比较好玩的是第三种: 注意两种不同: int (*array1)[N]; int  *array2[N]; 我比较喜欢下面这种方式,那么两种有什么不同呢,int (*array1)[N] ------array1是一个指向一维数组的指针, 而  int

8.31 二维数组 字符串和指针

指针+1移动了相当于所指向类型的大小的字节 int *s1[100] 移动了4个字节 int (*s2)[100] 移动了400个字节 char *s3 移动了1 个字节 int *s4 移动了4个字节 ***p2如何理解? int *p0 = &i *p0  = i int **p1 = &p0 **p1 = i int ***p2 = &p1 ***p2 = i *p2 = p1的值 **p2 = p0的值 ***p2 = i的值 所以***p2就是p0的值        而p

一维数组,二维数组,三维数组,数组与指针,结构体数组,通过改变指针类型改变访问数组的方式

 打印数组中的每个元素,打印每个元素的地址: #include <stdio.h> #include <stdlib.h> void main(void) { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; for (int *p = a; p < a + 10;p++)  //指针类型决定4个字节 { printf("\n%p,%d", p, *p); } getchar(); } 指针数组 #inclu

C语言 二维数组与指针笔记

今天分析了C语言二维数组和指针的基本理解,感觉有点懵...代码记录一下,如果有大神临幸发现哪里有误,欢迎指正~~~ #include <stdio.h> #include <stdlib.h> #include <string.h> //void func(int p[][]) //这样写等同于void func(int **p) p++移动了四个字节,(*p)++移动了四个字节,不符合二维数组规律 //{ //} //列优先输出的函数(即竖着输出) void func

二维数组作为函数参数传递剖析

前言 很多文章不外乎告诉你下面这几种标准的形式,你如果按照它们来用,准没错: //对于一个2行13列int元素的二维数组 //函数f的形参形式 f(int daytab[2][13]) {...} //以下两种可以忽略行数 f(int daytab[][13]) {...} f(int (*daytab)[13]) {...} 甚至会有人告诉你多维数组作为参数传递可以省略第一维,其他维不能省略.然而你对这种形式并不满意:如果事先限定了二维数组的大小,函数的泛用性就要大打折扣了.因为你真正需要的,

参数 存在二维数组

声明函数如下void function(int** p),意图是想参数传递一个二维数组.于是就定义了一个二维数组,比如 int a[1][1],然后调用函数.结果如何?当然是失败了,编译器提示:cannot convert parameter 1 from 'int [1][1]' to 'int **',参数类型不匹配.上述过程我自己也试了,当然不匹配,类型完全不一样嘛.然后我就想了:如果要将一个二维数组作为形参,那么函数该怎么声明? 简单点 数组名作为形参 void func1(int Ar

二维数组名和二级指针

1. 指针 1.1 一个指针包含两方面:a) 地址值:b) 所指向的数据类型. 1.2 解引用操作符(dereference operator)会根据指针当前的地址值,以及所指向的数据类型,访问一块连续的内存空间(大小由指针所指向的数据类型决定),将这块空间的内容转换成相应的数据类型,并返回左值. 有时候,两个指针的值相同,但数据类型不同,解引用取到的值也是不同的,例如, 1 char str[] ={0, 1, 2, 3}; /* 以字符的ASCII码初始化 */ 2 3 char * pc