函数基础
1 非引用形参(复制实参的值给形参)
1)非引用形参表示对应实参的局部副本。这类形参的修改仅仅修改了局部副本的值。一旦函数执行结束,这些局部变量的值就没有了。
2)指针形参。操纵地址和地址的值。
3)const形参。如void fcn(const int i)
不可以改变实参的局部副本。
可以传递给fcn非const对象或者const对象。
什么时候不适合复制实参?
1)需要在函数中修改实参的值。
2)需要大型对象作为实参传递。这样复制对象付出的时间和存储空间代价太大。
怎样解决?
可将形参定义为引用或者指针类型。
2 引用形参(它是实参的别名)
1)函数运行时,对实参进行操纵(非引用形参,对实参的副本进行操纵)
2)const引用。不可以修改实参的值。
应该将 不修改相应实参的形参 定义为const引用。
非const引用既不能用const对象初始化,也不能用字面值或者产生右值的表达式实参初始化。
3 main:处理命令行选项
#include<stdlib.h> #include<iostream> int main(int argc,char **argv) { if(argc!=3) { std::cout<<"You should input three "<<std::endl; return -1; } std::cout<<(atof(argv[1])+atof(argv[2]))<<std::endl; return 0; }
输入: ./main 2 3
( argv[0] argv[1] argv[2] )
输出:5
4 返回值
1)没有返回值的函数,{return;...}是为了引起函数的强制结束。
2)主函数可以没有返回值。
3)不要返回局部对象(函数内部定义的对象)的引用。也不要返回局部对象的指针。因为当函数执行完毕后,局部对象占用的存储空间被释放。
(考虑:这个引用指向哪个在调用改函数前存在的对象?)
5 局部对象
1)函数被调用时,函数内的对象被创建和撤销。
2)静态局部对象。在函数结束时依然保留,在程序结束时才撤销。但是它依然是局部变量,仅在函数内部有效。
#include<iostream>
int getCount() { static int str = 0; return ++str; } int main() { std::cout<<getCount()<<std::endl; std::cout<<getCount()<<std::endl; std::cout<<getCount()<<std::endl; std::cout<<getCount()<<std::endl; std::cout<<getCount()<<std::endl; }
输出:1 2 3 4 5
6 内联函数
函数在程序中直接展开。
调用函数的开销:调用前保存寄存器,并在返回时恢复;复制实参;程序转向一个新位置。
内联函数直接被展开,无须调用。内联机制适用于优化小的,只有几行且经常被调用的函数