在我们刚学习C/C++的时候通常会混淆二者,特别是在各种C++的教材、书籍的轰炸下很容易形成C是C++的子集的概念。这个想法也不能说就不对,至少在C++的早期设计上是这样想的。但无论是在实际的二者演化过程中还是在编程实际使用中,二者的差异实际上是非常大的,甚至现在有种思想认为二者是完全不同的两种语言。甚至在业界还有超级C粉LinusTorvalds(linux的作者)大骂C++是狗屎的大论战。C++的初学者们一定很震惊,但也不好反驳这位大牛啊,但C++的作者也是大牛啊,让我等如何是好?我只能从个人经历来说,两者都很有用,另外两者的差异有时候确实是非常大的,不了解的话有时候是非常致命的。所以我们两者都是应该学,二者间的区别就是更应该掌握了。这一次,我们要说到的引用的概念就是其中的一个典型。另外,这个概念还涉及到我后面文章要说的一个比较重要的内容,那个内容也要先理解引用等等许多概念,所以大家要听仔细了。
如果我们在这里象其他教程那样直接解释引用,那估计大家都听不懂。其实不光是大家听不懂,其实在多种语言中对二者的概念的区分都是比较模糊的。我们以最常见的string类来看看以下的函数声明:
不同的参数形式前两种大家很容易理解,第一个是传值,第二个是传引用:
voidf3(std::strings){}voidf4(std::string*s){}
而第三个函数的参数前有一个符号,这在C语言里可没有啊?说实在的,从我的角度来说前两种已经够用了,为什么要第三种呢?因为这个原因所以一般的学校里的教程或者是简单的书籍就绕道走了--不讲解。很多教程都说这是为了避免使用危险的指针,我想说:这......
作为现在的程序员来说我觉得这种说法最好是不要接受的好,我们应当接受现实就是当它是更多的一个选择,知道它的特性就可以了。引用的特性一名话可以概括:可以直接当变量用而不是当指针用,而且当变量使用完退出函数后它会像使用指针一样改变原来传进来的参数的值。在编程中这样做除了能代替指针以外,还有个很大的好处,就是如果这个变量是类的话,就可以只用一个.引出成员,而不用-操作符号了。所以在C++编程里还可以根据这个操作符是否存在来判断这个变量是否是指针。不过这仅仅局限于C++,其实现在大多数的新语言比如java、delphi甚至直接从C而来的golang里都主要是用的.符号,在objectC里因为arc的原因,指针和引用的界限就更加模糊了。
引用这个概念引出其他语言中的实现的话可能更好理解,在各个语言中引用其实基本上就代替了指针。例如java中就一直声称只有引用没有指针。至于它们和C++中的引用是否是一回事,那就要打大大的打问号了,很多时候恐怕只是借了一下引用的名称。在所有的其他语言中,我觉得和C++引用最相似的应该是delphi里的var修饰符号,这在delphi里是非常常见的:
delphi中的var修饰就是其实引用同时在使用delphi的同学一定会恍然大悟:我说var是干什么的呢!
所以我说了,学习其他语言的同学最好也学习好C语言。delphi里就有很多借鉴C/C++概念的地方,不懂引用概念基本上很难和他说清var的作用。delphi里引入这个var应该主要是为了语法,因为delphi里的指针写法很是怪异,这样就可以避免了,当然了这是我的猜测,只是大家不妨就按这个思想来做就好了,我保证很是方便。delphi中的var还有一个常用的用途,那就是性能优化,这是一个巨大的好处,原因就是引用不会重新再生成一个类的实例或者是字符串的拷贝,在字符串很大的会大大的节省内存分配和释放所花的时间。这种做法在C++中也是一样可行的,所以加上引用符不影响最后运算结果的我们都应当加上,这样能大大的优化性能。我们随意在stl中就能找到这样的代码,原因就是这个,如下图:
引用修饰符很多时候能提高性能当然了,对于纯C来说,我们直接使用指针就好了。我个人并没觉得有什么不好,当然了,我很羡慕golang中的.运算符号也能用在指针当中,什么时候纯C也能这样做就太好了。