C语言-第27课 - 数组参数和指针参数分析

第27课 - 数组参数和指针参数分析

  1. 思考:为什么C语言中的数组参数会退化为指针?

答:

l C语言中只会以拷贝的方式传递参数

l 当向函数传递数组时有两种传递方式

(1)将整个数组拷贝一份传入函数

(2)将数组名看做常量指针传数组首元素地址

上面的两种方式,显然第二种更合理。C语言以高效为最初的设计目标,在函数传递的时候,如果拷贝整个数组执行效率将大大下降。

我们看下面的例程:

#include<stdio.h>

void f(int *p)

{

*p = 5;

}

int main()

{

int i;

f(&i);

printf("i = %d\n",i);

}

只是一个简单传址调用(传地址的值),但是C语言中实际上只有一种传值的方式,它实际也是一种传值调用的方式,和下面的程序是一样的:

#include<stdio.h>

void f(int *p)

{

*p = 5;

}

int main()

{

int i;

int *pi = &i;

f(pi);

printf("i = %d\n",i);

}

  1. 二维数组参数

1)二维数组参数同样存在退化的问题

l 二维数组可以看做是一维数组

l 二维数组中的每个元素都是一维数组

2)二维数组参数中第一维的参数可以省略

void f(int a[5]);---void f(int a[]);---void f(int *a);

void g(int a[3][3]);---void g(int a[][3]);---void g(int (*a)[3]);

等效关系:

注意事项:

l C语言中无法向一个函数传递任意的多维数组

为了提供正确的指针运算,必须提供除第一维之外的所有维长度。

l 限制:
一维数组参数,必须提供一个标示数组结束位置的长度信息

二维数组参数,不能直接传递给函数

三维或更多维数组参数,无法使用

例程:

#include<stdio.h>

void f(int p[3][3])

{

printf("sizeof(p) = %d\n",sizeof(p));

}

int main()

{

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

f(a);

}

运行结果:4

若改为:void f(int p[][])就无法运行,改成:void f(int p[][3])就可以运行。

改成:void f(int (*p)[3])也就是数组指针的形式,一样可以运行。

以上说明数组类型需要限定大小。这就好比在函数中有:printf(“%d\n”,(*(p+1)[1]));这样的语句,不限定大小,就是打印不出来的语句。

自我领悟:在C语言中除了本身给的一些数据类型外,还在默认下自我组成了好多不同类型的数据类型。我们分析数据类型,不就是分配了不同大小的一些连续的数据嘛。所以,即使是我们自定义的数据类型(包括不同长度的数组),只有同类型的可以相互转换。当然有时我们可以用到强制转换符。这是因为,数据的存储都是线性的,可以进行重新的数据整合。

实例分析--传递与访问二维数组的方式

#include <stdio.h>

void access(int a[][3], int row) //不用传递有多少列,因为我们能推出来

{

int col = sizeof(*a) / sizeof(int);  //*这把钥匙打开a这扇门,得到的是一个一维数组。

//其中有多少个元素,就是整体的长度除以每个元素的长度。

    int i = 0;

    int j = 0;

    printf("sizeof(a) = %d\n", sizeof(a));

    for(i=0; i<row; i++)   //

    {

        for(j=0; j<col; j++)  //

        {

            printf("%d ", a[i][j]);

        }

    }

}

int main()

{

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

    access(a, 3);

printf("\n");

}

运行结果:sizeof(a) = 4

0 1 2 3 4 5 6 7 8

猜你喜欢

转载自www.cnblogs.com/free-1122/p/9783856.html