zoukankan      html  css  js  c++  java
  • (转载)C中实参与形参的“值传递”只能“单向传送”(透彻的理解)

    链接地址:https://blog.csdn.net/sdkhy0808/article/details/38121269?locationNum=8&fps=1

    今天又彻底地把这部分知识回顾了一下,好好地理解了一番。还是记下来比较靠谱,加深印象,省的以后再忘。

    主调函数(比如main函数)中,调用函数(比如numpp函数)时,如果swap的参数在函数中改变了,那么此参数必须是指针类型的。还是例子好说话。

    目的:实现main中的一个整形变量加1。(当然实际情况,如果简单的功能,不会采取调用函数方式,仅作说明)

    错误的例子:

        void numpp(int x)  
        {  
            x++;  
        }  
        main()  
        {  
            int a=2;  
            numpp(a);  
            printf("a=%d
    ",a);  
        }  

    上述代码运行结果为:a=2,并没有加1。

    正确的写法为:

        void numpp(int *x)  
        {  
            (*x)++;  
        }  
        main()  
        {  
            int a=2;  
            numpp(&a);  
            printf("a=%d
    ",a);  
        }  

    这次的运行结果是正确的:a=3。

    这是为什么呢?

    错误的例子分析:main中,a=2,调用numpp函数时,实参a的值传如x,然后x+1,于是x=3,函数调用结束后,x被释放掉,而a的值依旧没有改变,还是2,形参x的值并不会再传给a,只能实参向形参单向传送。

    正确的例子分析:main中,a=2,&a是a的地址,即指针,调用numpp函数时,a的指针传送给指针变量x,那么x就指向了变量a,(*x)++,也就是x指向的变量加1,也就是a+1,变成了3,函数调用结束后,x被释放掉,但a的变化被保留了下来,所以是加1后的值3。

    总结1:“单向传送”的“值传递”方式,就是形参值的改变不能改变实参的值。不可能通过执行调用函数改变实参变量的值,但是可以改变实参指针变量所指向的变量的值。

    经验:为了使函数中改变了的变量值能被主调函数所用,不能把要改变值的变量作为函数参数,而应该用指针变量作为函数参数。在函数执行过程中,使指针变量所指向的变量值发生变化,函数调用结束后,这些变量值的变化依然保留下来。

    其实还有一个经典的例子,就是swap函数,交换两个变量的值。

    两个经典的错误:

    1、

        void swap(int x,int y)  
        {  
            int t;  
            t=x;  
            x=y;  
            y=t;  
        }  
        main()  
        {  
            int a,b;  
            int *p1=&a,*p2=&b;  
            swap(p1,p2);  
            printf("a=%d,b=%d
    ",a,b);  
        }  

    2

        void swap(int *x,int *y)  
        {  
            int *tp;  
            tp=x;  
            x=y;  
            y=tp;  
        }  
        main()  
        {  
            int a,b;  
            int *p1=&a,*p2=&b;  
            swap(p1,p2);  
            printf("a=%d,b=%d
    ",*p1,*p2);  
        }  

    例1中的错误同最上面的错误一样,必须用指针变量做参数才行。但例2中,就是用指针变量做的参数,但还是不对,下面分析一下:main中,p1指向a,p2指向b,调用函数swap时,p1的值传送给x,p2的值传送给y,也就是说x指向a,y指向b,在函数中,x和y作了交换,于是x指向b,y指向a。但是,形参x和y的值并不会回头再传给实参p1和p2,所以p1依旧指向a,p2依旧指向b。a和b的值也依旧没有改变。

    总结2:其实本质跟总结1一样。“单向传送”的“值传递”方式,就是形参值的改变不能改变实参的值。不可能通过执行调用函数改变实参指针变量的值,但是可以改变实参指针变量所指向的变量的值。

    最后总结:函数执行过程中,不能通过改变形参变量的值,也不能通过改变形参指针变量的值,来改变实参变量或实参指针变量,而是通过改变形参指针变量指向的变量值,来改变实参变量的值。

    如果这句话看明白了,那就真正理解了。

    还有一句话可以体会一下:函数的调用,只可以得到一个返回值(即函数值),而使用指针变量做参数,可以得到多个变化了的值。

     

     

  • 相关阅读:
    JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别
    Transact-SQL 示例
    Transact-SQL 示例
    JQuery Easyui引入easyui-lang-zh_CN.js后出现乱码的问题解决方法
    easyui 表格底部加合计
    VS调试技巧之附加进程
    c#如何读取相机手机的拍摄时间
    调用 webapi的put和delete 报"Method Not Allowed" 405 错误。
    sqlserver数据库 去除字段中空格,换行符,回车符(使用replace语句)
    C#中yield return用法分析
  • 原文地址:https://www.cnblogs.com/Fy1999/p/9210656.html
Copyright © 2011-2022 走看看