开发者

关于函数传参问题(指针传参,值传参,引用传参)

开发者 https://www.devze.com 2024-01-02 10:22 出处:网络 作者: 不是杠杠
目录形参和实参形参和实参关系实参为值传值实参为指针传值实参本身为普通变量 实参本身为指针引用传值总结形参和实参
目录
  • 形参和实参
  • 形参和实参关系
  • 实参为值传值
  • 实参为指针传值
    • 实参本身为普通变量
    •  实参本身为指针
    • 引用传值
  • 总结

    形参和实参

    什么是形参(parameter),什么是实参(argument)

    在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参

    给形参传递值的变量称为实际参数,简称实参

    形参和实参关系

    1) 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。 

    2) 实参可以是常量、变量、python表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。 

    3) 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。当然,如果能够进行自动类型转换,或者进行了强制类型转换,那么实参类型也可以不同于形参类型。

    实参为值传值

    代码:

    #include<IOStream>
    using namespace std;
    void swap(int a,int b)
    {
        cout<<"a address1 = "<<&a<<endl;
        cout<<"b address1 = "<<&b<<endl;
        int temp = a;
        a = b;
        b = temp;
    }
     
    int main()
    {
        int a = 10;
        int b = 20;
        cout<<"a address = "<<&a<<endl;
        cout<<"b address = "<<&b<<endl;
        cout<<"original "<<"a = "<<a<<"编程客栈 b="<<b<<endl;
        swap(a,b);
        cout<<"swaped "<<"a = "<<a<<" b="<<b<<endl;
        return 0;
    }

    执行结果:

    关于函数传参问题(指针传参,值传参,引用传参)

    分析结果:

    实参a,b 和形参a,b的地址是不一样的,因为形参a,b是整型变量,他们在函数调用时分配内存,里面只是存放了和实参对应得整型值,所以改变形参变量a,b的值并没有改变实参a,b的值。形参a,b是临时变量,当函数运行结束时,他们的生命周期也就结束了。所以实参a,b的值并没有改变。

    图解:

    关于函数传参问题(指针传参,值传参,引用传参)

    实参为指针传值

    实参本身为普通变量

    代码:

    #include<iostream>
    using namespace std;
    void swap(int *a,int *b)
    {
        cout<<"parameter a address1 = "<<&a<<endl;
        cout<<"parameter b address1 = "<<&b<<endl;
     
        cout<<"a value address1 = "<<a<<endl;
        cout<<"b value address1 = "<<b<<endl;
        int temp = *a;
        *www.devze.coma = *b;
        *b = temp;
    }
     
    int main()
    {
        int a = 10;
        int b = 20;
        cout<<"a address = "<<&a<<endl;
        cout<<"b address = "<<&b<<endl;
        cout<<"original "<<"a = "<<a<<" b="<<b<<endl;
        swap(&a,&b);
        cout<<"swap "<<"a = "<<a<<" b="<<b<<endl;
        return 0;
    }
     

    执行结果:

    关于函数传参问题(指针传参,值传参,引用传参)

    分析结果:

    *p 指的是 指针变量p所指向的地址所存放的内容

    &p指的是指针本身的地址

    p指的是指针所指向的内容的地址

    实参传递的是实参a,b的地址,形参a,b为指针类型的变量,也就是对应存放的是实参a,b变量的地址,函数内交换形参a,b指针所指向地址的内容,也就是交换了实参a,b地址指向空间的内容,所以实参a,b的内容被交换。

    图解:

    关于函数传参问题(指针传参,值传参,引用传参)

     实参本身为指针

    一级指针

    代码:

    #include<iostream>
    using namespace std;
     
    void newpoint(int *p)
    {
        cout<<"parameter p address = "<<&p<<endl;
        p = new int;
        *p = 10;
    }
     
     
    int main()
    {
        int *p = NULL;
        cout<<"argument p address = "<<&p<<endl;
        newPoint(p);
        cout<<"*p = "<<*p<<endl;
        delete p;
        return 0;
    }
    ~           

    执行结果:

    关于函数传参问题(指针传参,值传参,引用传参)

    分析结果:

    实参指针p 没有指向任何类容为空,当实参给形参传递值时,传递的实际上是NULL,形参指针p 分配空间,仅仅只是给形参p分配了空间,当函数退出时,实参指针指向的内容还是为空,这时去访问实参p指向的内容,因为指针没有指向确切地址,就会产生段错误,同时因为函数new了空间没有释放,还会造成内存泄漏。

    关于函数传参问题(指针传参,值传参,引用传参)

    二级指针

    代码:

    #include<iostream>
    using namespace std;
     
    void newPoint(int **p)
    {
        cout<<"parameter p address = "<<&p<<endl;
        *p = new int;
        cout<<"parameter p value = "<<p<<endl;
        cout<<"parameter *p value = "<<*p<<endl;
        **p = 10;
    }
     
     
    int main()
    {
        int *p = NULL;
        cout<<"argument p address = "<<&p<<endl;
        newPoint(&p);
        cout<<"argument p value = "<<p<<endl;
        cout<<"*p = "<<*p<<endl;
        delete p;
        return 0;
    }
    ~       

    执行结果:

    关于函数传参问题(指针传参,值传参,引用传参)

    结果分析:

    实参给形参传递的值是实参本身的地址 0x7ffe7feaa980,形参类型是二级指针,形参p存放的是一级指针实参http://www.devze.comp的地址,调用new之后,相当于是给实参指针p分配了空间,实参指针指向的地址为0x55d013b6d280,给**p赋值,相当于是给地址0x55d013b6d280指向的空间赋值,所以当函数返回时,实参指针指向了确定的地址0x55d013b6d280,并且地址0x55d013b6d280指向的空间值为10;

    图解:

    关于函数传参问题(指针传参,值传参,引用传参)

    引用传值

    代码:

    #include<iostream>
    phpusing namespace std;
     
    void swap(int& a,int& b)
    {
        cout<<"parameter a address = "<< &a<<endl;
        cout<<"parameter b address = "<< &b<<endl;
        a = a+b;
        b = a-b;
        a = a-b;
     
    }
     
    int main()
    {
        int a = 10;
        int b = 20;
     
        cout<<"argument a address = "<<&a<<endl;
        cout<<"argument b address = "<<&b<<endl;
        cout<<"original value"<<"a = "<<a<<" b ="<<b<<endl;
        swap(a,b);
        cout<<"swap value"<<"a = "<<a<<" b ="<<b<<endl;
        return 0;
    }
    ~     

    运行结果:

    关于函数传参问题(指针传参,值传参,引用传参)

    结果分析:

    引用传值,函数形参并没有给形参分配内存,而是和实参相同的内存地址,节省了开销,建议能用引用传值的就用引用。

    图解:

    关于函数传参问题(指针传参,值传参,引用传参)

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消