• 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 ",i);

    }

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

    #include<stdio.h>

    void f(int *p)

    {

    *p = 5;

    }

    int main()

    {

    int i;

    int *pi = &i;

    f(pi);

    printf("i = %d ",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 ",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 ”,(*(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 ", 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(" ");

    }

    运行结果:sizeof(a) = 4

    0 1 2 3 4 5 6 7 8

  • 相关阅读:
    在DataList控件中删除数据记录
    java中进行二进制,八进制,十六进制,十进制间进行相互转换
    Java中重载重写
    WCF 第七章 寄宿 在Windows 进程激活服务中寄宿服务
    .NET 中的十进制浮点类型(译文)
    .NET 中的二进制浮点类型(译文)
    WCF 第六章 序列化和编码 总结
    WCF 第六章 序列化和编码 为自定义序列化使用XmlSerializer
    WCF 第七章 寄宿 在IIS7中寄宿服务
    WCF 第七章 寄宿
  • 原文地址:https://www.cnblogs.com/free-1122/p/9783856.html
Copyright © 2020-2023  润新知