精华内容
下载资源
问答
  • 引用传参和指针传参

    因为数据结构的算法设计题要求手写代码,书上函数的形参部分中用到了c++里引用(&)的概念,当时老师只讲了“在形参前面加&符号可以改变传进来的实参的值,如果不熟悉引用也可以用指针传参去改变实参的值”。
    现在打算后面统一用引用传参的形式,原因如下:

    • 教材和各种辅导书都是用的引用传参,方便核对答案;
    • 指针传参有两方面缺点:
      (1)如果用指针传参的话,需要在函数里重复使用“*指针变量名”的形式来对实参进行操作,容易产生错误且程序的阅读性较差;
      (2)在主调函数的调用点处,需要用变量的地址作为实参,而这就导致需要额外定义一个该变量类型的指向该变量的指针;

    函数通过指针传参:

    int Init_by_pointer(SqList *pL, Elemtype e1, Elemtype e2)
    {
        //Initial sequence list L = (e1, e2) by using pointer pL
        (*pL).base = (Elemtype *)malloc(INIT_LIST_SIZE * sizeof(Elemtype));
        if(!(*pL).base) exit(-1);
        (*pL).length = 2;
        (*pL).listsize = INIT_LIST_SIZE;
        (*pL).base[0] = e1;
        (*pL).base[1] = e2;
        return 0;
    }
    

    函数通过引用传参:

    int Init_by_reference(SqList &L, Elemtype e1, Elemtype e2)
    {
        //Initial sequence list L = (e1, e2) by using reference &L
        L.base = (Elemtype *)malloc(INIT_LIST_SIZE * sizeof(Elemtype));
        if(!L.base) exit(-1);
        L.length = 2;
        L.listsize = INIT_LIST_SIZE;
        L.base[0] = e1;
        L.base[1] = e2;
        return 0;
    }
    

    主函数部分:

    #include <stdio.h>
    #include <stdlib.h>
    #include <status.h>
    
    #define INIT_LIST_SIZE 10
    
    typedef struct SqList
    {
        Elemtype *base;
        int length;
        int listsize;
    }SqList;
    
    int main(void)
    {
        SqList L1;
        SqList *pL1 = &L1; //额外定义
        Init_by_pointer(pL1, 1, 2);
        printf("L1 = (%d, %d)\n", L1.base[0], L1.base[1]);
    
        SqList L2;
        Init_by_reference(L2, 3, 4);
        printf("L2 = (%d, %d)\n", L2.base[0], L2.base[1]);
        return 0;
    }
    

    结果:显然这两种方式实现的效果是一样的
    在这里插入图片描述

    引用的原理:从编译的角度来讲,在创建符号表的时候,引用在符号表上对应的地址值为引用对象的地址值(与实参名字不同,地址相同)。所以我理解的“引用”实际上就是一个变量的“别名”,所以任何对于引用参数的处理都会通过寻址,操作到主调函数中的相关变量(即实参)。

    展开全文
  • 引用传参和指针传参

    2014-09-15 09:18:06
    指针/引用参数 (2010-12-19 21:36:34) ...在C++中,函数参数主要采用两种传递方式:值传递和引用传递。所谓值传递是指在调用函数时将实际参数复制一份传递到函数中,这样,在函数中如果对参数进行修改,将不会影响到实

    在编写函数时,如果函数需要采用引用方式传递,使用指针和引用作为参数类型都是可以的。使用指针和引用类型作为函数参数各有优缺点,视具体环境而定。对于引用类型,引用必须被初始化为一个对象,并且不能使它再指向其他对象,因为对引用赋值实际上是对目标对象赋值。这是引用类型的缺点,但也是引用类型的优点,因为在函数调用时需要验证引用参数的合法性。例如,如果函数OutputNumber采用引用参数类型,则语句"OutputNumber(0);"是非法的。如果函数OutputNumber采用指针类型参数,则语句"OutputNumber(0);"是合法的。因为0被认为是一个空指针,对空指针操作必然会导致地址访问错误。因此对于指针对象作为函数参数,函数体中需要验证指针参数是否为空。这是使用指针类型作为函数参数的缺点。但是,使用指针对象作为函数参数,用户可以随意修改指针参数指向的对象,这是引用类型参数所不能的。

    展开全文
  • 在C++中,如果函数的实参的类型是数据类型比较大的数据类型...其实引用传参和指针传参都能够在条用函数内部对源数据进行修改,这是它们的共同点,但是它们也是有区别的。下面是一个例子: #include &lt;iostr...

    在C++中,如果函数的实参的类型是数据类型比较大的数据类型,这是如果使用一般传参就会有很大的不方便,这是如果能够传递一个地址或者是对原来参数的一个引用对提高性能会有很大的帮助。

             本文研究一下引用传参和指针传参的区别和联系。其实引用传参和指针传参都能够在条用函数内部对源数据进行修改,这是它们的共同点,但是它们也是有区别的。下面是一个例子:

    #include <iostream>
    
    using namespace std;
    
    void SwapByPoint(int* x,int* y);      //指针传参函数的声明
    
    void SwapByReference(int &x,int &y);   //引用传参函数的声明
    
    
    
    int main()
    
    {
    
             int x = 3;
    
             int y = 5;
    
             cout<<"转化前: x="<<x<<" y="<<y<<"/n";
    
        SwapByPoint(&x,&y);    //如果这里使用 SwapByPoint(x,y) 则报错:cannot convert parameter 1 from 'int' to 'int *'
    
             cout<<"指针传参转换后:x="<<x<<" y="<<y<<"/n";
    
    
             SwapByReference(x,y); //如果这里用SwapByReference(&x,&y) 则报错 cannot convert parameter 1 from 'int *' to 'int &'
    
             cout<<"引用传参调用转换后:x="<<x<<" y="<<y<<"/n";
    
             system("pause");
    
             return 0;
    
    }
    
    
    /*交换函数 使用指针传参*/
    
    void SwapByPoint(int *x,int *y)
    
    {
    
             int temp = *x;
    
             *x = *y;
    
             *y = temp;
    
    }
    
    
    /*
    
    使用引用传参
    
    */
    
    void SwapByReference(int &x,int &y)
    
    {
    
    int temp = x;
    
    x = y;
    
    y = temp;
    
    }
    
    

    指针传参和引用传参的效果是一样的。

    它们的差别个人认为:

    Ø 指针传参传递的是一参数(这里是Int实参)的地址,这样,虽然实参和形参不一样,但是它们只想的地址是一样的,所以对相同地址的数的操作会影响到原来的数。

    Ø 引用传参传递的是一个参数本身,但是在调用函数中,把保存它们的地址的值做了交换。

    两种传参方式的调用必须是上述这样的,否则会报错,在相应的代码中有提示…..

    展开全文
  • c++ 引用传参和指针传参的区别

    千次阅读 2019-05-26 19:32:47
    指针从本质上讲是一个变量,变量的值是另一个变量的地址,指针在逻辑上是独立的,它可以被改变的,包括指针变量的值(所指向的地址)和指针变量的值对应的内存中的数据(所指向地址中所存放的数据)。 引用从本质上...

    概念

    • 指针从本质上讲是一个变量,变量的值是另一个变量的地址,指针在逻辑上是独立的,它可以被改变的,包括指针变量的值(所指向的地址)和指针变量的值对应的内存中的数据(所指向地址中所存放的数据)。
    • 引用从本质上讲是一个别名,是另一个变量的同义词,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化(先有这个变量,这个实物,这个实物才能有别名),而且其引用的对象在其整个生命周期中不能被改变,即自始至终只能依附于同一个变量(初始化的时候代表的是谁的别名,就一直是谁的别名,不能变)。

    区别

    指针 变量,独立,可变,可空,替身,无类型检查
    引用 别名,依赖,不变,非空,本体,有类型检查
    • 指针参数传递本质上是值传递,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,会在栈中开辟内存空间以存放由主调函数传递进来的实参值,从而形成了实参的一个副本(替身)。值传递的特点是,被调函数对形式参数的任何操作都是作为局部变量进行的,不会影响主调函数的实参变量的值(形参指针变了,实参指针不会变)。

    • 引用参数传递过程中,被调函数的形式参数也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参(本体)的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量(根据别名找到主调函数中的本体)。因此,被调函数对形参的任何操作都会影响主调函数中的实参变量。

    • 引用传递和指针传递是不同的,虽然他们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将应用不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量(地址),那就得使用指向指针的指针或者指针引用。

    • 从编译的角度来讲,程序在编译时分别将指针和引用添加到符号表上,符号表中记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值(与实参名字不同,地址相同)。符号表生成之后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。

    以上内容来源网络

    如何使用

    如果我们编程只是为了做一些简单的工作,不想在技术上有什么质的突破,那么使用指针就够了。这样做的问题就是,你写的代码很容易出bug。可是,如果我们想要对c++有更深的了解,那么一定要区分指针传参与引用传参的区别。

    使用指针传递参数,是为了避免拷贝副本,从而提高程序执行效率,大所数初学者(也包括我)都习惯使用指针传递参数,因为还没有建立起引用的概念,我们以为指针就是引用,殊不知,引用的内涵比指针更丰富。因为用的少,所以对引用的概念懵懵懂懂。其实有经验的程序员在传递参数时很少使用指针。下面通过代码来说明我们为什么要使用引用传参,放弃指针传参。

    • 首先定义一个结构体
    struct ST
    {
    public:
    	int num;
    	string name;
    	ST(int num, string name)
    	{
    		this->num = num;
    		this->name = name;
    	}
        void putInfo()
    	{
    		cout << "学号:" << num << endl;
    		cout << "姓名:" << name << endl;
    	}
    };
    

    1.使用指针传参

    void dealProcess(ST* st)
    {
    	ST *newST =new ST(320, "小明");
    	st = newST;//为临时指针变量赋予了新值,已和输入脱离了联系。
    }
    
    int main()
    {
    	int num = 1;
    	ST st1(310, "小红");
    	dealProcess(&st1);
    	st1.putInfo();
    	system("pause");
    	return 0;
    }
    
    • 输出结果
      在这里插入图片描述

    使用指针传参,想返回处理后的结果,但是我们得到的结果却和预想的不一致。因为在处理的过程中,形参的地址发生了变化,和输入脱离了联系。

    • 正确的写法:
    void dealProcess(ST* st)
    {
    	ST *newST =new ST(320, "小明");
    	*st = *newST;
    }
    
    • 严谨的写法(但不简洁)
    void dealProcess(ST* const st)//指定形参为常量指针,不能修改值
    {
    	ST *newST =new ST(320, "小明");
    	*st=*newsT;
    	st = newST;    //编译错误,不允许修改常量
    }
    

    void dealProcess(ST* const st)等价于void dealProcess(ST* st const)

    2.既严谨又简洁的写法,使用引用

    void dealProcess(ST& st)
    {
    	ST newST(320, "小明");
    	st = newST;    
    	&st=&newsT;//编译错误,不允许改变输入的地址
    }
    int main()
    {
    	int num = 1;
    	ST st1(310, "小红");
    	dealProcess(st1);
    	st1.putInfo();
    	system("pause");
    	return 0;
    }
    

    3.如果仅仅是使用输入的值,应该限定输入为常量

    • 首选是使用引用
    void dealProcess(const ST& st)
    {
    	ST newST(0,"");
    	newST.putInfo();
    	//输入的值不允许被改变
    	st = newST;  //编译错误,只允许使用输入,不允许改变输入的值  
    	&st = &newsT;//编译错误,不允许改变输入的地址
    	//使用输入的值,
    	newST = st;
    	newST.putInfo();
    }
    int main()
    {
    	int num = 1;
    	ST st1(310, "小红");
    	dealProcess(st1);
    	system("pause");
    	return 0;
    }
    

    在这里插入图片描述

    • 如果一定要使用指针,等价代码如下
    void dealProcess(const ST* const st)
    {
    	ST newST(0,"");
    	newST.putInfo();
    	//使用输入的值
    	newST = *st;
    	newST.putInfo();
    }
    int main()
    {
    	int num = 1;
    	ST st1(310, "小红");
    	dealProcess(&st1);
    	system("pause");
    	return 0;
    }
    
    展开全文
  • 按址传递可以通过指针(pointer)和引用(reference)的方式传递,效果相同,但用法不同。 可通过下面冒泡排序的例子来理解: #include <iostream> #include <vector> using namespace std; /*交换两个...
  • 值传参、指针传参引用传参

    千次阅读 2017-07-02 01:46:25
    3种传参方式:值传参、指针传参引用传参我们知道传参方式有3种:值传参、指针传参引用传参。这三种方式书写方式各有不同,接下来,我们简单介绍3种传参方式实现的机制。首先看一个程序:这个程序实现的是交换2个...
  • 1、值传参,对形参的任何操作都不会对实参产生影响 1.1:值传参方法 //值传参 void NoChangeValue(int v) { printf("值传参修改前的值 = %d\n", v); v = 10; printf("值传参修改后的值 = %d\n", v); } 1.2:主...
  • 引用 ...3、定义时指针引用符号要靠近类型值。 4、一旦引用就不能再改变,即c是a的引用,就不能再变成b的引用。 1、三种传参示例 (1)值传参 # include <iostream> using std::cout; usin...
  • 指针数组数组传参、指针引用传参

    千次阅读 2016-09-17 23:47:02
    指针和数组作为参数传入函数时,传入...),我们无法对指针和数组的地址进行操作(如:地址赋值,分配内存等),要进行地址操作需要使用指针引用指针指针。 示例: int main() { int i = 1; int *p = &i;
  • 个人原创: 1. 形参:形式上的参数,一般多在函数声明、函数定义的参数上;...5. 引用传参:只有在C++中才有,C中没有引用传参,其意义就是传递了一个实参的别名,有实参和指针的优点,但没有其占用那么多的...
  • go的函数传参和指针

    千次阅读 2018-08-15 23:08:25
    go的函数传参默认是值类型,想要按引用传参,那么需要的就是传指针,go的传指针类似于c++的传引用,指针并不能改变,因为指针的地址也是按值传递的.看测试代码如下: package main import ( "fmt" ) type ...
  • 引用符号&...虽然引用和指针的方式作为传参方式都会保留该函数对传入参数的改变,但这两种方法还是有区别的。这个区别表现在,引用的方式下可以直接使用该参数,而指针的方式通常都需要解引用,或

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,091
精华内容 8,836
关键字:

引用传参和指针传参