内联函数以及两种传值方式的比较 - lidoublewen的专栏 - 博客频道 - CSDN.NET
今天去参加UCweb的笔试,呵呵,里面涉及了一些c++的基础知识,原来自己还有些知识是很模糊的,回来查了一下。。。为下次笔试做好准备。
一.关于内联函数: 引入内联函数的目的是为了解决程序中函数调用的效率问题。
函数是一种更高级的抽象。它的引入使得编程者只关心函数的功能和使用方法,而不必关心函数功能的具体实现;函数的引入可以减少程序的目标代码,实现程序代码和数据的共享。但是,函数调用也会带来降低效率的问题,因为调用函数实际上将程序执行顺序转移到函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。这种转移操作要求在转去前要保护现场并记忆执行的地址,转回后先要恢复现场,并按原来保存地址继续执行。因此,函数调用要有一定的时间和空间方面的开销,于是将影响其效率。特别是对于一些函数体代码不是很大,但又频繁地被调用的函数来讲,解决其效率问题更为重要。引入内联函数实际上就是为了解决这一问题。
在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替换。显然,这种做法不会产生转去转回的问题,但是由于在编译时将函数休中的代码被替代到程序中,因此会增加目标程序代码量,进而增加空间开销,而在时间代销上不象函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。
内联函数的定义方法
定义内联函数的方法很简单,只要在函数定义的头前加上关键字inline即可。内联函数的定义方法与一般函数一样。如: inline int add_int (int x, int y, int z) { return x+y+z; }
在程序中,调用其函数时,该函数在编译时被替代,而不是像一般函数那样是在运行时被调用。
使用内联函数应注意的事项
内联函数具有一般函数的特性,它与一般函数所不同之处公在于函数调用的处理。一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换。
在使用内联函数时,应注意如下几点:
1.类内定义的函数是内联函数,类外定义的函数是非内联函数(短函数可以定义在类内,长函数可以定义在类外)。
2.可以为类外定义的函数指定 inline 关键字,强行为内联函数。
3.在内联函数内不允许用循环语句和开关语句。
4.内联函数的定义必须出现在内联函数第一次被调用之前。
二.引用传递与指针传递的比较 a.比较一 引用是C++中的概念,初学者容易把引用和指针混淆一起。 一下程序中,n是m的一个引用(reference),m是被引用物(referent)。 int m; int &n = m; n相当于m的别名(绰号),对n的任何操作就是对m的操作。 所以n既不是m的拷贝,也不是指向m的指针,其实n就是m它自己。 引用的规则:
(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。
(2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。
以下示例程序中,k被初始化为i的引用。 语句k = j并不能将k修改成为j的引用,只是把k的值改变成为6。 由于k是i的引用,所以i的值也变成了6。 int i = 5; int j = 6; int &k = i; k = j; // k和i的值都变成了6; 引用的主要功能是传递函数的参数和返回值。 C++语言中,函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递。
以下是"值传递"的示例程序。 由于Func1函数体内的x是外部变量n的一份拷贝,改变x的值不会影响n, 所以n的值仍然是0。 void Func1(int x) { x = x + 10; } ... int n = 0; Func1(n); cout << "n = " << n << endl; // n = 0 以下是"指针传递"的示例程序。 由于Func2函数体内的x是指向外部变量n的指针,改变该指针的内容将导致n的值改变,所以n的值成为10。
void Func2(int *x) { (* x) = (* x) + 10; } ... int n = 0; Func2(&n); cout << "n = " << n << endl; // n = 10
以下是"引用传递"的示例程序。
由于Func3函数体内的x是外部变量n的引用,x和n是同一个东西,改变x等于改变n,所以n的值成为10。
void Func3(int &x) { x = x + 10; } ... int n = 0; Func3(n); cout << "n = " << n << endl; // n = 10
对比上述三个示例程序,会发现"引用传递"的性质象"指针传递",而书写方式象"值传递"。 实际上"引用"可以做的任何事情"指针"也都能够做,为什么还要"引用"这东西? 答案是"用适当的工具做恰如其分的工作"。 指针能够毫无约束地操作内存中的任何东西,尽管指针功能强大,但是非常危险。 如果的确只需要借用一下某个对象的"别名",那么就用"引用",而不要用"指针",以免发生意外。 引用就是传递的原始变量,指针传递的是变量的地址,两者没什么关系, 引用主要用于函数参数的传递,相对于传值,可以节省内存空间, 指针可以直接传递变量地址,也可以可以节省内存空间,但是指针功能强大一些,可以在自由操作数组变量。
b.比较二
(1)非空区别。在任何情况下都不能使用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让他指向一个对象,但是该变量在某些时候也可能不指向任何对象,这是你应该把变量声明为指针,因为这样你可以赋予空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。不存在指向空值得引用这个事实意味着使用引用的代码效率比使用指针要高。
(2)合法性区别。在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
(3)可修改区别。指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则是总是指向在初始化时被指定的对象,以后不能改变,但是指定的对象其内容可以改变。
(4)应用区别。总的来说,在以下情况下你应该使用指针:一是你考虑到存在不指向任何对象对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。 三.char* a=0? 原来以为这个是非法的赋值,查了下百度,原来char* a = 0就是char* a = NULL的意思~~