关于引用传参

最近在巩固基础知识,对指针传递方式有了很大的想法。这里简单的以一篇博文来做一个理解的记录。

首先简单的讲解一下引用

在编译语言中引用基本可以理解为指针的别名。
如传统C/c++中指针 实际是内存中的一个地址。这个地址保存着指针类型的值。实际就是在此地址上取几个字节 然后作为什么数值处理。

int *a = &b;
print *a;

以上可以理解为一个伪代码。
下面翻译一下为汇编代码

mov dword ptr:ds[0x0],eax
push dword ptr:ds[0x0]
call print

好久不写汇编代码基本记不住了。估计语法是错误了。

这里翻译的比较直观,可以理解为一个变量放入了一个内存地址。
但以上例子是没有任何意义的。因为在同作用域中这个例子完全没有存在的必要。

所以下面必须要解释一下指针的使用场景及优劣性了。

下面来看两个C语言函数的参数

int add(int a,int b,int c=0)
{
    c = a + b;
    return c;
}

int add(const int * a,const int * b,int & c)
{
    *c = *a + *b;
    return *c;
}

两个函数最终效果是一样的。区别在于一个采用指针传递了参数。
一个并未采用指针传递参数,那么在汇编中两种方式的执行结果是怎么样的呢?
先来翻译一下汇编代码

mov eax,c
push eax
mov eax,b
push eax
mov eax,a
push eax //居然后进现出都没有忘记
call address
address:
sub esp 12 //申请12个字节 3*typeof(int)
pop esp

最后从栈中弹出数据到申请的3个int变量中就不写了。
都记不清楚基础知识了所以有必要巩固一下。
再来看一下指针版本的。

mov eax,c
push eax
mov eax,b
push eax
mov eax,a
push eax
call address
address:
//前面就不写了太懒了
pushad
pushfd
//保存所有寄存器到堆栈
//结束后再弹回

pop eax // a
pop ebx // b 
pop ecx // c

由于不是分析汇编语言哈。就不写那么正式了。当成伪代码读就好了。

可以看出在汇编中处理的数据是不一样的,一个是缓存了一个值到自己临时申请的空间中。

而采用指针形式的是直接操作原始变量的地址,省略了申请空间和维护堆栈的开销。

所以由指针进行传参效率更高。

传递指针也需要四个字节。八位。

所以如果你只传递一个字节char类型的数据可以直接以局部变量形式传递。可由你自己去考虑。

那么理解了指针的传递。就进入这个博文的主题了。

引用实际是指针的一种copy。

只不过实现更加优美。

引用在内存中的表现形式与指针相同这里就不在阐述

引用是把指针的语法* 替换为&

就为一个引用。

int add(int &a);

此声明函数方法 传入一个引用类型的int类型

此方法速度更快,同时又不用担心指针的弱点。

所以很多书籍建议传输超过四个字节的参数全部使用引用传参

添加新评论