美文网首页C语言
C语言参数传递

C语言参数传递

作者: Moclin | 来源:发表于2018-05-08 16:30 被阅读0次

    C语言参数传递

    前言

    最近复习Block相关知识,其中有个问题:block中为什么不能改变(这里值重新复制)被截获的自动变量,这个问题涉及到C语言参数传递,所以回头看了一下,并做了一些整理。

    下面是C语言的几种参数传递方式:值传递、引用传递、指针传递、指针引用传递。

    PS:为方便表述,以下内容的图片对内存的描述作了简化,如int类型是4个字节,指针类型是8个字节,这里统一用相同大小的一个格子表示。

    1. 值传递

    代码:

    void func(int p)
    {
        printf("\n-----------func start-----------");
        printf("\n&p : %x", &p);
        printf("\np : %x", p);
        p = 0xff;
        printf("\n-----------func end-----------\n");
    }
    
    void test()
    {
        int a = 0x10;
        printf("\n&a : %x", &a);
        printf("\na : %x", a);
        func(a);
        printf("\na : %x", a);
    }
    

    输出:

    &a : efbfde3c
    a : 10
    
    -----------func start-----------
    &p : efbfde1c
    p : 10
    -----------func end-----------
    
    a : 10
    

    通过上面的代码及输出可知,变量a的地址为efbfde3c,值为10;通过调用func(a),通过输出可知:变量p的地址为efbfde1c,值为10。也就是说参数传递只把变量a的值传递给了变量p,此时变量a与变量p是值相同的两个不同变量,在内存不同的两个地址中,所以对变量p赋值只是修改了变量p的值,并不能修改变量a的值,如下图所示。总结一句话就是:值传递不传递变量本身,只传递变量的值。

    1.png

    2.引用传递

    代码:

    void func(int &p)
    {
        printf("\n-----------func start-----------");
        printf("\n&p : %x", &p);
        printf("\np : %x", p);
        p = 0xff;
        printf("\n-----------func end-----------\n");
    }
    
    void test()
    {
        int a = 0x10;
        printf("&a : %x", &a);
        printf("\na : %x\n", a);
        func(a);
        printf("\na : %x", a);
    }
    

    输出:

    &a : efbfde2c
    a : 10
    
    -----------func start-----------
    &p : efbfde2c
    p : 10
    -----------func end-----------
    
    a : ff
    

    与值传递不同,func的参数是int &p,表示引用传递。如输出所示,通过引用传递,变量a的地址与变量p是相同的,也就是说引用传递把a的地址传给了变量p,所以对变量p进行赋值之后,变量a的值也改变了,因为变量a与变量p实际是同一个变量。如下图所示:

    2.png

    3. 指针传递

    代码:

    void func(int *p)
    {
        printf("\n-----------func start-----------");
        printf("\n&p : %x", &p);
        printf("\n*p : %x", *p);
        printf("\np : %x", p);
        *p = 0xff;
        printf("\n-----------func end-----------\n");
    }
    
    void test()
    {
        int a = 0x10;
        printf("&a : %x", &a);
        printf("\na : %x\n", a);
        func(&a);
        printf("\na : %x", a);
    }
    

    输出:

    &a : efbfde2c
    a : 10
    
    -----------func start-----------
    &p : efbfde08
    *p : 10
    p : efbfde2c
    -----------func end-----------
    
    a : ff
    

    指针传递,顾名思义,int *p表明p是一个指针变量,调用func(&a)是把变量a的内存地址传递过去赋值给指针变量p,此时指针变量p的值是变量a的内存地址,故可看到输出p为efbfde2c(变量a的内存地址)。*p是对指针p的值(即变量a的内存地址)进行取值,相当于*&a,所以对*p进行赋值也就改变了变量a的值。如下图所示:

    3.png

    4. 指针引用传递

    代码:

    void func(int *&p)
    {
        printf("\n-----------func start-----------");
        printf("\n&p : %x", &p);
        printf("\n*p : %x", *p);
        printf("\np : %x", p);
        *p = 0xff;
        printf("\n-----------func end-----------\n");
    }
    
    void test()
    {
        int a = 0x10;
        printf("&a : %x", &a);
        printf("\na : %x\n", a);
        int *b = &a;
        printf("\n&b : %x", &b);
        printf("\n*b : %x", *b);
        printf("\nb : %x", b);
        func(b);
        printf("\na : %x", a);
    }
    

    输出:

    &a : efbfde2c
    a : 10
    
    &b : efbfde20
    *b : 10
    b : efbfde2c
    -----------func start-----------
    &p : efbfde20
    *p : 10
    p : efbfde2c
    -----------func end-----------
    
    a : ff
    

    其实理解了前面的,这里也就明了了。首先把变量a的地址即&a赋值给指针变量b,指针变量b的值就是efbfde2c(后面的的输出证明了这一点)。然后调用
    func(b),这里跟前面的引用传递一样道理,指针变量p实质是是指针变量b,而指针变量b的值又是变量a的内存地址,所以*p等同于*b,对其进行赋值相当于对变量a进行赋值(a = 0xff)。可见下图:

    4.png

    相关文章

      网友评论

        本文标题:C语言参数传递

        本文链接:https://www.haomeiwen.com/subject/blrwrftx.html