精华内容
下载资源
问答
  • C语言函数参数引用类型回顾

    千次阅读 2019-07-26 17:12:21
    涉及:数组参数、指针参数... *函数参数是指针和指针引用的区别在于: 参数是指针:参数可以看作传的是地址,不能改变实参所指向的地址。 参数是指针引用:参数可以看作是实参指针本身,可以改变内部所指向的地址...

      涉及:数组参数、指针参数、普通类型引用参数、指针引用。

    #include<stdio.h>
    #include<iostream> 
    using namespace std;
    
    /*
     *函数参数是指针和指针引用的区别在于:
       参数是指针:参数可以看作传的是地址,不能改变实参所指向的地址。
       参数是指针引用:参数可以看作是实参指针本身,可以改变内部所指向的地址。 
     *共同点:两者都可以改变地址中所存数据。 
    */ 
    
    void array1(int a[],int n) //数组是引用类型,函数内部操作的传入函数参数数组本身 
    {
    	for(int i=0;i<n;i++){ //这里可以越界,且不会报错。 
    		a[i]=0;
    	}
    }
    
    void add(int &a)
    {
    	++a;
    }
    
    void in(int *a)//传指针
    {
    	++*a;
    	printf("in(p)中*a指针的地址:%d\n",a); 
    }
    
    
    void add2(int *&a)
    {
    	++a; //传进来的指针变量中的地址加一个int类型的长度 
    	*a=6; 
    	printf("add2(p)中*a指针的地址:%d\n",a); 
    }
    
    int main() {
    	int a=2;
    	int *p;
    	int array[6]={1,2,3,4,6,5};
    	p=&a; //指针赋值必须是变量地址,不能直接是变量 
    	printf("指针修改前p=%d *p=%d\n",p,*p);
    	add(a); //整型数据引用函数调用
    	add2(p); //指针引用参数函数调用
    	printf("整型引用函数调用后a=%d\n",a);
    	printf("指针引用参数函数修改后p=%d *p=%d\n",p,*p);
    	
    	array1(array,6);
    	for(int i=0;i<6;i++){
    		printf("%d ",array[i]);
    	}
    	printf("\n");
    	in(p);//传的是指针变量P ,只能传指针变量 
    	printf("指针参数函数调用后:%d",*p) ;
    	return 0;
    }

    结果如下:

    展开全文
  • (2)使用引用传递函数参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还

    (1)传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。

    (2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。

    (3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。

    --------------------------------------------------

    如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const 类型标识符 &引用名=目标变量名;
    例1
    int a ;
    const int &ra=a;
    ra=1; //错误
    a=1; //正确
    例2
    string foo( );
    void bar(string & s);
    那么下面的表达式将是非法的:
    bar(foo( ));
    bar(“hello world”);
    原因在于foo( )和”hello world”串都会产生一个临时对象,而在C++中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的。
    引用型参数应该在能被定义为const的情况下,尽量定义为const 。


    
    展开全文
  • 指针作为函数参数 1. 函数参数概念:  形参:被调函数中的参数  实参:主调函数中的参数  形参和实参:  C 中函数中实参和形参是按值传递的,调用函数后,会将实参的值拷贝给形参(即形参和实参之间是没有...

    指针作为函数参数

    1.  函数参数概念:

           形参:被调函数中的参数

           实参:主调函数中的参数

           形参和实参:
           C 中函数中实参和形参是按值传递的,调用函数后,会将实参的值拷贝给形参(即形参和实参之间是没有关系的,只是它们的值是相同的)。在被调函数中不可以改变实参的值, 同样形参定义在被调函数中,在整个函数体内都可以使用, 离开该函数则不能使用。

           (1) 形参变量只有在被调用时才分配内存单元,在调用结束时, 即刻释放所分配的内存单元。

           (2) 在进行函数调用时,实参都必须具有确定的值,以便把这些值传送给形参。

           (3) 实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量。

           (4) 实参和形参在数量上,类型上,顺序上应严格一致, 否则会发生“类型不匹配”的错误。

    2.  指针作函数参数使用 

            实际编程中,经常要改动传入参数的值。这时,我们需要使用指针作为实参,用指针作为参数,即传入的是参数的地址而不是参数本身,形参中拷贝的也是内存地址,当对形参去(*)运算时,就可以得到指针实参所指向的值,改变该地址就可以直接改变实参所指向的值

            C中函数的变量是局部变量,也就是说主用函数与被调用函数的实参和形参在内存中占用的是不同的存储空间,但它们内存空间中的值是相同的。当指针作为函数参数时,它们的内存空间中即存储着相同的内存地址(指向另一块内存空间),所以取(*)运算之后,它们的值是相同的,并且是同一块地址中的值。

           这也就是我们在实际编程中会看见某些C函数会用到char ***的原因(一般编程,char** 已经够用了),它只是把想把char** 传入函数中,赋值之后返回。

    main()
    {
       int i;
       MyFun(&i);
    }
    MyFun(int *p)
    {
       (*p) = 2;
    }

           在上面简单的程序中&i则是i的地址,传入被调函数后,指针p所指向的内存地址即i的地址,(*p)则就是i,所以函数执行后i也会变成2。并且这里i是编译器自动对其进行了初始化,并分配了内存,所以&i是有值的(实参必须有确定的值)。

     3. 引用概念

          定义引用使用&符号。引用只在C++中可以使用,C中没有引用的概念。

          引用等于是对象的另一个名字,与原对象一模一样,并都指向同一块内存地址。

    int a = 5;
    int & b = a;

          这里定义了引用b,它就是a的一个别名,那么a=6和b=6效果是一样的。
          定义引用时应注意:

                1).  定义引用是必须给它初始化,并且不能初始化NULL,int &b;这样的定义是不正确的。

                2).  引用并不是对象的拷贝,也不是指针。

                3).  &这里并不是取地址,它只是代表引用。

               4).   引用不是一种数据类型,所以没有引用的引用,没有引用的指针。

    4. 引用作函数参数

           实际编程中,要经常要改动传入参数的值,除了使用指针,还可以使用引用。这时,我们需要使用变量或类对作为实参,用引用作为形参,则形参和实参就是一样的。改变形参后,实参的值也会改变。

    主调函数: 
    void main(void)
    { 
       String str(_T"Hello World!");  
         Fun(str);  
     }
    被调函数:  
    void Fun(String & Ref_str)  
    {  
    ......  
    }  
    

     

    在Fun函数中改变形参的话,实参也会跟着改变。
     
    5. 内存概念
         在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区.
    1.       栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。
    2.       堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。在源程序里,堆里的变量等都是没有名字的,它们是通过指针被访问的。在堆区里生成变量的过程称为动态内存分配。
    3.       自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
    4.       全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
    5.       常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)。

           内存泄漏,用动态存储(new,malloc)分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。即所谓内存泄漏。如果程序一直执行,则长时间之后,会内存耗尽,发生死机等现象。

    6. 内存释放

           在栈中的变量所占内存会自动释放,就像第二节中的局部变量i,由编译器自动进行了初始化,并分配了内存空间以存放 i 的值,在main函数结束时,变量i会自动释放其在栈内存中所占的空间。栈中内存由编译器自己控制,程序员可以不用管它,只管定义和使用即可。

          但是new出来的内存空间存储在堆内存空间中,它们则不会自动释放。例如,如果是int *a = new int,(*a)是动态分配的内存单元,a是指向该内存单元的指针,则函数执行完成后,(*a)所占的内存空间则不会自动释放,如果要释放该内存空间,必须使用

    delete a,否则会出现内存泄露。 而int a;就不存在这种问题,程序会自动回收内存的。所以堆中内存由程序员来控制,在用new初始化内存空间后,需要考虑在什么时候去释放它。

           malloc分配的内存则需要由free();来释放内存空间。

           另外,需要注意的是 delete(&),参数是一个地址。假如有个指针p,delete(p)释放的是p所指向的内存,p指针并没有释放,p指针这时是个野指针;但p还是指向那个地址,如果那块内存被其他程序使用了,再用*p来修改其内容,这样对程序来说是非常危险的事,所以我们在delete删除指针所指向内存后,会加上p = NULL; 使指针指向为空。

    int *p = new int;
    .....
    .....
    delete p;
    p = NULL;

           再需要注意的一个地方,delete p;实际上只是将p所指向的内存空间标记为可使用,让其他程序去使用该内存空间,并没有删除内存空间中所存储的数据,在该内存被其他程序使用之前 (*p)还是原来的值

    展开全文
  • C++ 引用引用作为函数参数

    万次阅读 多人点赞 2017-03-05 15:49:20
    对一个数据建立一个“引用”,他的作用是为一个变量起一个别名。这是C++对C语言的一个重要补充。

    对一个数据建立一个“引用”,他的作用是为一个变量起一个别名。这是C++对C语言的一个重要补充。

    如何建立一个引用

    	int a = 5;
    	int &b = a;
    	cout<<a<<endl;
    	cout<<b<<endl;
    	cout<<&a<<endl;
    	cout<<&b<<endl;
    

    以上声明了b是a的引用,并把a,b的值和它们的地址打印出来。经过声明后b是a别名,b与a代表的是同一个变量,占内存中同一个存储单元,具有同一地址。

    注意&符号作为取地址符合作为引用声明符的区别,在上述程序中的第2行,&在数据类型后,为引用声明符。而第5、6行,&为取地址符。可以用这个方法作区分:只有在数据类型后&才是引用声明符。

    打印结果:
    这里写图片描述

    从上述结果可以看到,a与b地址是相同的。

    使用引用的一些注意事项:
    (1)声明一个引用时,必须同时使之初始化,及声明它代表哪一个变量。(有一个例外,引用作为函数参数时,不需要初始化)
    (2)在声明一个引用后,不能再使之作为另一变量的引用。
    (3)不能建立引用数组。

    引用的作用:

    C++加入了在C语言的基础加入了引用机制,那么引用到底有什么用呢?不会只是为了给函数起一个小名吧?显然不是,引用最用要的意义在于作为函数的参数,以扩充函数传递参数的能力。它是如何实现的?这要从C语言参数传递开始说起:

    我们知道,C语言在调用函数时,传参主要有两种形式:
    (1)变量名作为实参和形参
    这种方式传给形参的是变量的值,传递是单向的。如果在执行函数器件形参的值变了,不会回传给实参。也就是说如果想要实现一个这样的功能:调用函数后实参的值随之改变。显然此方式无法实现。

    举个例子:
    执行swap函数后,想要主函数内的变量值变化,用上述方式写出代码:

    #include <iostream>
    using namespace std;
    int main()
    {
          void swap(int ,int);
    	  int i =3,j = 5;
    	  swap(i,j);
    	  cout<<"i="<<i<<endl<<"j="<<j<<endl;
          getchar();
    	  return 0;
    }
    
    void swap(int a,int b)
    {
    	int temp;
    	temp = a;
    	a =b;
    	b= temp;
    }
    
    

    运行结果:
    i = 3
    j = 5

    显然值没有带回,i和j的值在执行后没有发生变化。

    (2)传递变量的地址

    该方式形参是指针变量,实参是一个变量的地址,调用函数时,形参得到的实参变量的地址,因此指向实参的变量单元。
    然后我们修改下上面的程序:

    #include <iostream>
    using namespace std;
    int main()
    {
          void swap(int * ,int*);
    	  int i =3,j = 5;
    	  swap(&i,&j);
    	 cout<<"i="<<i<<endl<<"j="<<j<<endl;
          getchar();
    	  return 0;
    }
    
    void swap(int *a,int *b)
    {
    	int temp;
    	temp = *a;
    	*a =*b;
    	*b= temp;
    }
    

    运行结果:
    i = 5
    j = 3

    在程序的第13行,定义的函数的形参是指针,在第6行,调用的函数是传入的函数实参是变量的地址,实现了i和j的交换,但是这种方法不够直观,而且依旧是“值传递”的方式,只不过传递的是变量的地址而已。

    然后,如果我们使用引用功能,可以很简单的实现这个功能,而且很容易理解:
    (3)引用作为函数参数

    #include <iostream>
    using namespace std;
    int main()
    {
          void swap(int & ,int&);
    	  int i =3,j = 5;
    	  swap(i,j);
    	 cout<<"i="<<i<<endl<<"j="<<j<<endl;
          getchar();
    	  return 0;
    }
    
    void swap(int &a,int &b)
    {
    	int temp;
    	temp = a;
    	a =b;
    	b= temp;
    }
    
    

    运行结果:
    i = 5
    j = 3

    第13行,形参是声明的引用,注意这个引用并没有初始化,这就是上面提到的特例。而在第7行调用函数的过程中,实现了引用的初始化,这是传入的实参就是变量,而不是数值,所以做到了真正意义上的“变量传递”。

    展开全文
  • 博文结构: ...传址:被调函数局部变量改变会影响主调函数局部变量传值就是传入一个参数的值,传址就是传入一个参数的地址,也就是内存的地址(相当于指针)。他们的区别是如果函数里面对传入的参数
  • 引用作为函数参数”与 “引用作为函数返回值” 一、引用作为函数参数 作为函数参数引用有两种原因: 1、在函数内部会对此参数进行修改 2、提高函数调用和运行效率   关于第一点,都知道C++里提到函数就会...
  • 引用作为函数参数”与 “引用作为函数返回值” 转自:http://blog.csdn.net/u012273127/article/details/52446832 一、引用作为函数参数 作为函数参数引用有两种原因: 1、在函数内部会对此参数进行修改 2、...
  • CCS3.3关于函数参数引用

    千次阅读 2012-05-05 20:52:52
    在CCStudio3.3中编写程序时,为了让函数返回多个值,想到了引用参数的用法,于是在函数参数中采用&a方式。但编译时发现CCS中不支持函数参数引用,总是报错,将引用参数的方式换为指针,编译链接通过! 通过查找...
  • 指针和引用 作为函数参数

    千次阅读 2018-11-05 18:23:11
    引用和指针作为函数参数 背景说明 :C语言和C++中将变量名作为实参和形参。这时传给形参的是变量的值, 传递是单向的 。如果在执行函数期间形参的值发生变化,并不传回给实参。因为在调用函数时,形参和实参不是同...
  • C++引用作为函数参数

    千次阅读 2017-01-17 19:14:32
    引用很容易与指针混淆,它们之间有三个主要的不同: 1.不存在空引用引用必须连接到一块合法的内存。 2.一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。 3.引用必须...
  • C++函数参数引用和指针有什么区别?
  • Java没有指针,在需要由参数直接带回结果的情况下,较C语言相比有一点差别,C任何类型可通过指针传递,在Java中,需要自定义一个类,而类可以通过函数参数返回结果。   public class testParameter { public ...
  • 新手的困惑,python函数参数到底是值引用还是地址引用?为什么函数内部修改一个变量外部输入却没改变?
  • Python函数参数传递:传值还是传引用

    万次阅读 多人点赞 2016-03-30 11:46:53
    引子首先来看一个列子:def change(val): val.append(100) ...按照C++语言的思维,如果Python函数参数的传递是传值的话,结果应该是[0, 1],如果是传引用的话,结果应该是[‘T’, ‘Z’, ‘Y’]。 可
  • PHP 函数 数组引用参数

    千次阅读 2017-11-26 17:27:08
    function addElement(&$arr2,$school2) //数组是拷贝传值,数组作形参需要在前面加"&"符号,表示引用参数。也可以在函数调用时,在实参前加"&"符号。 { $arr2[] = $school2; } $arr = array("张三","男",24); $...
  • 函数参数作为引用 Python 唯一支持的参数传递模式是共享传参(call by sharing)。共享传参指函数的各个形参获得实参中各个引用的副本。也就是说,函数内部的形参是实参的别名。 解释 Python 中参数传递的方式...
  • 函数参数与函数作为参数

    千次阅读 2016-08-08 22:05:57
    变量、指针、引用用作函数参数的区别: (1)变量作函数参数,形参要额外开辟内存,形参和实参占用不同的内存。 (2)指针类型作函数参数,是将实际参数的地址指针传给形参,操作效率很高。 void swapint(int *a,int...
  • 函数参数有直接变量(如int、char、double等)类型、指针类型和引用类型。 如果参数是变量,传递方式是传值,就是将实参的值复制(复制,意味着空间消耗和时间消耗)到“栈”空间中。 如果参数是指针,传递方式是传址,...
  • python中函数参数引用与传值

    千次阅读 2018-08-14 15:43:41
    最近自己写了个函数,实现numpy数组180度旋转的功能: import numpy as np def rotate(matrix): if matrix.ndim == 2: matrix = list(matrix) for i in range(2): #一次顺时针旋转90度 matrix[:]...
  • 指针和引用作为函数参数的区别

    千次阅读 2018-12-02 10:37:50
    这个问题是在写平衡树的时候遇见的,到网上看了很多,也没明白,自己...在AVL树的函数操作里,需要返回的改变较多,所以无法定义返回值函数,只能定义含参函数通过对参数的改变对树进行维护。 这里大家想到的肯定是...
  • 函数参数——普通形参和引用形参

    千次阅读 2015-09-12 20:04:16
    在调用函数时候,引用形参和普通型参是有着很大的区别。 首先看函数在使用普通型参时候,编译器是怎么工作的。在函数调用的时候,编译器为被调函数在栈空间申请一块内存,此时普通形参也在这块内存取,被实参初始化...
  • 关于为什么拷贝构造函数参数必须使用引用

    千次阅读 多人点赞 2019-07-30 10:53:44
    Data(const Data&d) :_year(d._year) ...首先要明确一点,拷贝构造函数只有一个函数,而且必须引用传参 如果直接传对象,比如这样 Data(const Data d) {} 这里参数的Data d又会实例化一个对象,调用拷贝函数,...
  • php函数引用参数参数个数

    千次阅读 2012-11-04 18:52:30
    今天用到一个公共函数,但是 这个函数 有的地方参数只要两个,有的需要三个参数,经过分析,如下代码:  function f(&$a,&$b){  $a=45; $b=64;   $c=$a+$b; return $c;  }    $x=0;$y=0;   ...
  • 本文和大家重点讨论一下Perl函数参数中传递数组和引用的使用,今天看到这个问题可以通过传递参数引用来解决,所以打算写下来,希望可以帮到大家。 Perl函数参数中传递数组和引用 今天看到了在Perl函数参数中...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,059,812
精华内容 423,924
关键字:

函数参数引用怎么设置