开发者

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

目录
  • 形参和实参
  • 形参和实参关系
  • 实参为值传值
  • 实参为指针传值
    • 实参本身为普通变量
    •  实参本身为指针
    • 引用传值
  • 总结

    形参和实参

    什么是形参(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

    上一篇:

    下一篇:

    精彩评论

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

    最新开发

    开发排行榜