精华内容
下载资源
问答
  • c语言参数传递方式

    2015-08-07 15:33:36
    四、函数参数传递方式之三:引用传递 看题三的代码: void Exchg3(int &x, int &y) /* 注意定义处的形式参数的格式与值传递不同 */ {  int tmp = x;x = y;  y = tmp;  printf("x = %d, y = %d....


    原文链接:http://c.biancheng.net/cpp/html/494.html

    一、三道考题

    开讲之前,我先请你做三道题目。(嘿嘿,得先把你的头脑搞昏才行……唉呀,谁扔我鸡蛋?)

    考题一,程序代码如下:
    void Exchg1(int x, int y)
    {
       int tmp;
       tmp = x;
       x = y;
       y = tmp;
       printf("x = %d, y = %d\n", x, y);
    }
    main()
    {
       int a = 4,b = 6;
       Exchg1(a, b);
       printf("a = %d, b = %d\n", a, b);
       return(0);
    }
    输出的结果为:
    x = ____, y=____.
    a = ____, b=____.
    问下划线的部分应是什么,请完成。

    考题二,程序代码如下:
    void Exchg2(int *px, int *py)
    {
       int tmp = *px;
       *px = *py;
       *py = tmp;
       printf("*px = %d, *py = %d.\n", *px, *py);
    }
    main()
    {
       int a = 4;
       int b = 6;
       Exchg2(&a, &b);
       printf("a = %d, b = %d.\n", a, b);
       return(0);
    }
    输出的结果为为:
    *px=____, *py=____.
    a=____, b=____.
    问下划线的部分应是什么,请完成。

    考题三,程序代码如下:
    void Exchg3(int &x, int &y)
    {
       int tmp = x;
       x = y;
       y = tmp;
       printf("x = %d,y = %d\n", x, y);
    }
    main()
    {
       int a = 4;
       int b = 6;
       Exchg3(a, b);
       printf("a = %d, b = %d\n", a, b);
       return(0);
    }
    输出的结果为:
    x=____, y=____.
    a=____, b=____.
    问下划线的部分应是什么,请完成。你不在机子上试,能作出来吗?你对你写出的答案有多大的把握?正确的答案,想知道吗?(呵呵,让我慢慢地告诉你吧!)

    好,废话少说,继续我们的探索之旅了。
    我们都知道:C语言中函数参数的传递有:值传递、地址传递、引用传递这三种形式。题一为值传递,题二为地址传递,题三为引用传递。不过,正是这几种参数传递的形式,曾把我给搞得晕头转向。我相信也有很多人与我有同感吧?

    下面请让我逐个地谈谈这三种传递形式。

    二、函数参数传递方式之一:值传递

    (1)值传递的一个错误认识
    先看考题一中Exchg1函数的定义:
    void Exchg1(int x, int y) /* 定义中的x,y变量被称为Exchg1函数的形式参数 */
    {
       int tmp;
       tmp = x;
       x = y;
       y = tmp;
       printf("x = %d, y = %d.\n", x, y);
    }
    问:你认为这个函数是在做什么呀?
    答:好像是对参数x、y的值对调吧?
    请往下看,我想利用这个函数来完成对a,b两个变量值的对调,程序如下:
    main()
    {
       int a = 4,b = 6;
       Exchg1(a, b); /*a,b变量为Exchg1函数的实际参数。*/
       printf("a = %d, b = %d.\n”, a, b);
       return(0);
    }
    我问:Exchg1()里头的printf("x = %d, y = %d.\n", x, y);语句会输出什么啊?我再问:Exchg1()后的printf("a = %d, b = %d.\n”, a, b);语句输出的是什么?
    程序输出的结果是:
    x = 6, y = 4.
    a = 4, b = 6.
    为什么不是a = 6,b = 4呢?奇怪,明明我把a、b分别代入了x、y中,并在函数里完成了两个变量值的交换,为什么a、b变量值还是没有交换(仍然是a = 4、b = 6,而不是a = 6、b = 4)?如果你也会有这个疑问,那是因为你根本就不知实参a、b与形参x、y的关系了。

    (2)一个预备的常识
    为了说明这个问题,我先给出一个代码:
       int a = 4;
       int x;
       x = a;
       x = x + 3;
    看好了没,现在我问你:最终a值是多少,x值是多少?
    (怎么搞的,给我这个小儿科的问题。还不简单,不就是a = 4、x = 7嘛!)
    在这个代码中,你要明白一个东西:虽然a值赋给了x,但是a变量并不是x变量哦。我们对x任何的修改,都不会改变a变量。呵呵!虽然简单,并且一看就理所当然,不过可是一个很重要的认识喔。

    (3)理解值传递的形式
    看调用Exch1函数的代码:
    main()
    {
       int a = 4,b = 6;
       Exchg1(a, b) /* 这里调用了Exchg1函数 */
       printf("a = %d, b = %d.\n", a, b);
    }
    Exchg1(a, b)时所完成的操作代码如下所示。
    int x = a; /* ← */
    int y = b; /* ← 注意这里,头两行是调用函数时的隐含操作 */
    int tmp;
    tmp = x;
    x = y;
    y = tmp;
    请注意在调用执行Exchg1函数的操作中我人为地加上了头两句:
       int x = a;
       int y = b;
    这是调用函数时的两个隐含动作。它确实存在,现在我只不过把它显式地写了出来而已。问题一下就清晰起来啦。(看到这里,现在你认为函数里面交换操作的是a、b变量或者只是x、y变量呢?)

    原来,其实函数在调用时是隐含地把实参a、b 的值分别赋值给了x、y,之后在你写的Exchg1函数体内再也没有对a、b进行任何的操作了。交换的只是x、y变量。并不是a、b。当然a、b的值没有改变啦!函数只是把a、b的值通过赋值传递给了x、y,函数里头操作的只是x、y的值并不是a、b的值。这就是所谓的参数的值传递了。

    哈哈,终于明白了,正是因为它隐含了那两个的赋值操作,才让我们产生了前述的迷惑(以为a、b已经代替了x、y,对x、y的操作就是对a、b的操作了,这是一个错误的观点啊!)。

    三、函数参数传递方式之二:地址传递

    继续!地址传递的问题!
    看考题二的代码:
    void Exchg2(int *px, int *py)
    {
       int tmp = *px;
       *px = *py;
       *py = tmp;
       printf("*px = %d, *py = %d.\n", *px, *py);
    }
    main()
    {
       int a = 4;
       int b = 6;
       Exchg2(&a, &b);
       printf("a = %d, b = %d.\n”, a, b);
       return(0);
    }
    它的输出结果是:
    *px = 6, *py = 4.
    a = 6, b = 4.
    看函数的接口部分:Exchg2(int *px, int *py),请注意:参数px、py都是指针。再看调用处:Exchg2(&a, &b);
    它将a的地址(&a)代入到px,b的地址(&b)代入到py。同上面的值传递一样,函数调用时作了两个隐含的操作:将&a,&b的值赋值给了px、py。
       px = &a;
       py = &b;
    呵呵!我们发现,其实它与值传递并没有什么不同,只不过这里是将a、b的地址值传递给了px、py,而不是传递的a、b的内容,而(请好好地在比较比较啦)整个Exchg2函数调用是如下执行的:
       px = &a; /* ← */
       py = &b; /* ← 请注意这两行,它是调用Exchg2的隐含动作。*/
       int tmp = *px;
       *px = *py;
       *py = tmp;
       printf("*px =%d, *py = %d.\n", *px, *py);
    这样,有了头两行的隐含赋值操作。我们现在已经可以看出,指针px、py的值已经分别是a、b变量的地址值了。接下来,对*px、*py的操作当然也就是对a、b变量本身的操作了。所以函数里头的交换就是对a、b值的交换了,这就是所谓的地址传递(传递a、b的地址给了px、py),你现在明白了吗?

    四、函数参数传递方式之三:引用传递

    看题三的代码:
    void Exchg3(int &x, int &y) /* 注意定义处的形式参数的格式与值传递不同 */
    {
       int tmp = x;x = y;
       y = tmp;
       printf("x = %d, y = %d.\n", x, y);
    }
    main()
    {
       int a = 4;
       int b = 6;
       Exchg3(a, b); /*注意:这里调用方式与值传递一样*/
       printf("a = %d, b = %d.\n”, a, b);
    }
    输出结果:
    x = 6, y = 4.
    a = 6, b = 4. /*这个输出结果与值传递不同。*/
    看到没有,与值传递相比,代码格式上只有一处是不同的,即在定义处:
       Exchg3(int &x, int &y)
    但是我们发现a与b的值发生了对调。这说明了Exchg3(a, b)里头修改的是a、b变量,而不只是修改x、y了。

    我们先看Exchg3函数的定义处Exchg3(int &x, int &y)。参数x、y是int的变量,调用时我们可以像值传递(如: Exchg1(a, b); )一样调用函数(如: Exchg3(a, b);)。但是x、y前都有一个取地址符号“&”。有了这个,调用Exchg3时函数会将a、b 分别代替了x、y了,我们称:x、y分别引用了a、b变量。这样函数里头操作的其实就是实参a、b本身了,也就是说函数里是可以直接修改到a、b的值了。

    最后对值传递与引用传递作一个比较:
    1)在函数定义格式上有不同:
    值传递在定义处是:Exchg1(int x, int y);
    引用传递在这义处是:Exchg3(int &x, int &y);

    2)调用时有相同的格式:
    值传递:Exchg1(a, b);
    引用传递:Exchg3(a, b);

    3)功能上是不同的:
    值传递的函数里操作的不是a、b变量本身,只是将a、b值赋给了x、y。函数里操作的只是x、y变量而不是a、b,显示a、b的值不会被Exchg1函数所修改。
    引用传递Exchg3(a, b)函数里是用a、b分别代替了x、y。函数里操作的就是a、b变量的本身,因此a、b的值可在函数里被修改的。
    展开全文
  • 传递 地址传递 引用传递 https://blog.csdn.net/u013097971/article/details/77983810  

     

    • 值传递
    • 地址传递
    • 引用传递

    https://blog.csdn.net/u013097971/article/details/77983810

     

    展开全文
  • C语言参数传递

    千次阅读 2012-06-03 15:20:03
    C语言参数传递方式有传值和传地址两种方式。  1、传值方式  原理:形参和实参占不同内存单元,传递的实际上是实参变量或表达式的一个拷贝副本,将这个副本值传给形参,形参内存单元内容保存的正是这个副本值,...

    C语言参数传递方式有传值和传地址两种方式。

           1、传值方式

            原理:形参和实参占不同内存单元,传递的实际上是实参变量或表达式的一个拷贝副本,将这个副本值传给形参,形参内存单元内容保存的正是这个副本值,相当于给形参进行初始化,形参的值发生变化也不会传回给实参,因此是单向传递。

           例如:

                    void increase(int x)

                          {

                               x++;

                          }

        当在主函数中调用上面这个函数时,会在ncrease函数内存栈中为形参x分配一个内存单元,然后把实参的值传到这个内存单元中,相当于给形参初初化了,然后形参x自增1,它改变的仅仅是形参内存单元中的内容,而实参内存单元中的内容并没有改变。当被调用函数执行完毕后,形参所分配的内存单元也被收回。

         

     

             2、传地址方式

            原理:和传值方式一样,当调用函数时也要为形参分配内存,被调函数执行完毕后也要收回内存。不同的是传递的是实参变量地址的拷贝值,而不是实参变量的值,在被调函数中对地址所指对象的操作会改变实参的值。但是形参的内容即存放的实参变量地址并不会改变。

              例如:

                      void increase(int * x)

                          {

                              *x++;

                          }

                      int main()

                      {

                           int i,*x;

                           i=10;

                           *x=20;

                          increase(&i);//如果定义的不是指针变量,那变要加上个取址号&,当然如果形参实参是数组的话,直接用数组名即可,因为数组名本身代表的就是数组的首地址

                          increase(x);

                      }

                    主函数调用被调函数后,主函数中的i*x的值都会改变。

     

     

     

    我曾经在做关于链表的实验时,想先写一个初始化结点的函数,用malloc给结点分配内存,然后给主函数调用。

    struct node
    {
     int data;
     struct node *next;
    }

    当初始化函数按下面这样写就会有问题:

    int  init(struct node *n)
    {
     n=(struct node *)malloc(sizeof(struct node));
     if(!n)
     {
      printf("Failed to create node\n");
      return -1;

     }
     return 0;

    }

    在主函数中定义struct node *n;然后执行init(n);编译能通过,但运行会报错。
    因为虽然用了指针传递方式,但是被调函数只能改变n所指对象即结构体中成员的值,但其本身的值即地址并不会改变。

    有两种解决办法,一是形参用双指针变量,一是被调用函数返回值类型设为结构体指针类型。

    如:

    int  init(struct node **n)
    {
     (*n)=(struct node *)malloc(sizeof(struct node));
     if(!(*n))
     {
      printf("Failed to create node\n");
      return -1;

     }
     return 0;
    }

    n是一个双指针变量,它存放结构体指针变量的地址。

    如:

    或是被调用函数返回值类型设为结构体指针类型

    struct node *  init()
    {
     struct node *n=NULL;
     n=(struct node *)malloc(sizeof(struct node));
     return n;
    }

     

    展开全文
  • C语言参数传递的三种方式

    千次阅读 2020-09-04 14:11:38
    C语言中函数参数传递的三种方式 (1)传值,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值。 (2)传址,就是传变量的...

    C语言中函数参数传递的三种方式

    (1)传值,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值。
    (2)传址,就是传变量的地址赋给函数里形式参数的指针,使指针指向真实的变量的地址,因为对指针所指地址的内容的改变能反映到函数外,也就是能改变函数外的变量的值。
    (3)传引用,实际是通过指针来实现的,能达到使用的效果如传址,可是使用方式如传值。
    说几点建议:如果传值的话,会生成新的对象,花费时间和空间,而在退出函数的时候,又会销毁该对象,花费时间和空间。
    因而如果int,char等固有类型,而是你自己定义的类或结构等,都建议传指针或引用,因为他们不会创建新的对象。

    例1:下面这段代码的输出结果为:

    //引用交换
    void swip(int &a, int &b)
    {
    	int temp = a;
    	a = b;
    	b = temp;
    }
    //值传递
    void swip1(int a, int b)
    {
    	int temp = a;
    	a = b;
    	b = temp;
    	cout << "swip1 a = " << a << "swip1 b = " << b << endl;
    }
    //地址传递值传递
    void swip2(int *a, int *b)
    {
    	int temp = *a;
    	*a = *b;
    	*b = temp;
    }
    int main()
    {
    	int a = 10, b = 20;
    	swip1(a, b);
    	cout << "a = " << a << "b = " << b <<endl;
    	system("pause");
    	return 0;
    }
    

    解析:
    该题考察函数传参问题。
    1,指针传参 -> 将变量的地址直接传入函数,函数中可以对其值进行修改。
    2,引用传参 -> 将变量的引用传入函数,效果和指针相同,同样函数中可以对其值进行修改。
    3,值传参 -> 在传参过程中,首先将c的值复制给函数c变量,然后在函数中修改的即是函数的c变量,然后函数返回时,系统自动释放变量c。而对main函数的c没有影响。

    转载:https://blog.csdn.net/weibo1230123/article/details/75541862

    展开全文
  • C语言参数传递----值传递与地址传递

    千次阅读 多人点赞 2017-09-15 23:32:58
    最近开始复(yu)习(xi)C语言,看到参数传递这里,又遇到了以前一直没有搞清楚的一个问题,我相信这个问题大家许多初学者也会遇到过,就是C语言函数的参数传递方式C语言中参数的传递有两种方式: 1)值传递 ...
  • C语言函数传递方式-值传递和地址传递

    千次阅读 多人点赞 2020-03-02 12:10:20
    C语言函数传递方式 值传递 定义 所谓的值传递,顾名思义就是使用变量、常量、数组等作为函数的参数。 地址传递
  • C语言参数传递方式

    千次阅读 2007-04-05 22:28:00
    很多教材上说:C语言参数传递方式有传值调用和传址调用,真是瞎掰~C语言参数传递方式只有传值调用一种!最简单的就是:void fun1(int a);这是传值调用void fun2(int *a);//这也是传值调用,不知道为什么要说它是...
  • /** Copyright (c) 2015, 烟台大学计算机与控制工程学院* All rights reserved.* 文件名称:cpp1.cpp* 作者:巩凯强* 完成日期:2015年9月7日* 版本号:v6.0** 问题描述:C语言中函数参数传递的三种方式* 输入描述:...
  • C语言参数传递方式: 值传递(swap1函数) 地址传递(swap2函数) 引用传递(swap3函数) #include<stdio.h> #include<windows.h> void swap1(int,int); //值传递 void swap2(int *p1,int *p2); ...
  • C语言三种参数传递方式

    千次阅读 2015-11-12 15:55:23
    C语言中存在三种参数传递方式,分别是值传递,地址传递,引用传递;三种方式之间形式参数的区别到底是什么?三种方式在内存中的操作到底是什么样的? 本文通过几个例子来分析、总结。
  • 参数传递,是在程序运行过程中,实际参数就会将参数值传递给相应的形式参数,然后在函数中实现对数据处理和返回的过程,方法有3种方式值传递地址传递引用传递tips:被调用函数的形参只有函数被调用时才会临时分配存储...
  • c语言三种参数传递方式

    万次阅读 2018-01-10 20:49:55
    传递,创建变量x和y,x的值等于a的值,y的值等于b的值 void Exchg1(int x, int y) { int tmp; tmp=x; x=y; y=tmp; printf(“x=%d,y=%d/n”,x,y) } void main() { int a=4,b=6; Exchg1 (a,b) ; printf(
  • 函数参数有三种传递方式值传递、指针传递、引用传递。1、值传递将已经初始化的变量值(或常量)传递到函数中。例如:int func(int value){int ret = value++;return ret;}//调用函数时,实参需要先进行初始化int num =...
  • 这次,我们只是详细描述一下第一种参数传递方式,另外一种方式在这里不做详细介绍。 首先,我们看一下,下面一个简单的调用例程: int Add (int a, int b, int c) { return a+b+c; } void ...
  • C语言的三种参数传递方式

    千次阅读 2019-04-02 13:06:51
    C语言的3种参数传递方式 2017年09月14日 18:30:26 采香行处 阅读数:14619 </div> <div class="operating"> ...
  • C语言参数传递

    千次阅读 2006-10-08 11:03:00
    C语言的参数传递:一直没有好好研究C语言参数传递,只是从书上看,知道有传值和传地址两种方式,但调用函数时,他们内部发生什么变化并不清楚,现在写下来。C语言的参数传递有传值和传地址两种方式。传值的过程:(1...
  • C语言中函数参数传递方式:值传递,地址传递 ** 值传递:将实参的值复制至形参的相应存储单元中,实参与形参占用不同存储单元,单向传递 地址传递:使用数组名或者指针作为函数参数,传递的是该数组的首地址或指针...
  • C语言形式参数传递的两种方式

    千次阅读 2018-10-22 20:06:15
    C语言中实际参数(实参)与形式参数(形参)之间的传递方式有传值和传地址两种函数调用方式。 1.直接传值。 直接传值,在fun函数里面改变a,b的值,不会改变主函数里面a,b的值。 #include&lt;stdio.h&gt;...
  • 学习计算机已经两年了,参数传递已经成功恶心了我两年,今天在写二叉树遍历的时候成功对此忍无可忍。本文是在阅读https://blog.csdn.net/u013097971/article/details/77983810后写下的,算是对参数传递的总结,请...
  • C语言中,函数传递方式是以传值的方式进行传递的,实际所传递的是实参的一份拷贝。所以函数可以自由的修改他的形参(实参的拷贝),而不会对程序传递参数造成改变。在传递数组时,数组名其实也是通过传值的...
  • C语言中函数参数传递的三种方式

    万次阅读 多人点赞 2017-07-22 21:09:40
    C语言中函数参数传递的三种方式(1)传值,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值。(2)传址,就是传变量的地址...
  • 当一个表达式作为参数传递给函数时,这个表达式将首先进行求值,然后把结果传递给函数。 作为参数传递给函数的变量在调用环境中并不会被修改。 #include int main(void) { int a=1; void try_to_change_it...
  • C语言函数参数传递原理

    千次阅读 2014-07-29 10:34:19
    这次,我们只是详细描述一下第一种参数传递方式,另外一种方式在这里不做详细介绍。 首先,我们看一下,下面一个简单的调用例程: int Add (int a, int b, int c) { return a+b+c; } void main() { int x =0 , y =...
  • int x=1; int *y=&x; //用于指针传递,y有自己独立的内存地址,存储的内容是x的地址,*y是x的值 int &z=x; //用于引用传递,可以理解为z就是x,x就是z,只不过名字不一样

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,467
精华内容 586
关键字:

c语言参数传递方式

c语言 订阅