C++基础-函数

匿名 (未验证) 提交于 2019-12-02 23:55:01

1. 函数简介


传值和传址
在函数调用结束后,实参不会跟随形参而改变。 如果要改变实参的值, 只能通过指针传递。如果函数是“只读函数”,为了防止数据/地址传递增加破坏数据的风险,需要在形参中增加const标识符来解决。
1.2 函数的递归
递归常用于重复性的程序当中。在递归中,每次递归调用都会创建自己的一套变量,保存在不同的地址空间当中。如下所示,可以用栈的入栈和出栈来表示递归。

  void countdown(int n){      cout<<"Counting down ..."<<n<<" (Address at "<<&n<<")"<<endl;      if(n>0)          countdown(n-1);     cout<<n<<" Up"<<" (Address at "<<&n<<")"<<endl;  } int main(){     countdown(5); //递归调用 }

1.3 内联函数 inline
。但是,如果一个函数内部没有几条语句,执行时间本来就非常短,那么这个函数调用产生的额外开销和函数本身执行的时间相比,就显得不能忽略了。
将整个函数体的代码插人调用语句处,就像整个函数体在调用处被重写了一遍一样。

内联函数 (inline) 与宏 (#define) 的区别
内联函数是通过参数的传递实现的,而宏定义是通过文本的替换实现

 #define SQUARE(X) X*X    //宏定义 #define SQUARE1(X) ((X)*(X))    //宏定义 inline double square(double x){    //内联函数     return x*x; } int main(){         cout<<square(5.0+3.0)<<endl;  // (5.0+3.0)*(5.0*3.0) 输出结果为64     cout<<SQUARE(5.0+3.0)<<endl;  // 5.0+3.0*5.0+3.0  输出结果为23     cout<<SQUARE1(5.0+3.0)<<endl;  // ((5.0+3.0)*(5.0+3.0))  输出结果为64 }

1.4 函数默认参数
函数参数默认值设置必须通过函数原型进行设置,且带参数函数必须从右向左添加默认值

 char *left(const char *str,int n=1);  // √ 函数原型,带参数函数必须从右向左添加默认值 char *left(const char *str,int m=1,int j); // × 从右向左添加默认值,不能跳过任何参数 char *left(const char *str,int m=1,int j=2);  // √  left("theory",3);  //函数调用,3将覆盖默认值 left("theory");    //函数调用,使用原型默认参数

1.5 函数重载
函数重载是根据函数的参数列表(函数特征标)而不是根据函数类型。两个函数的参数数目和类型相同,同时参数的排序也相同时,他们的特征标也相同。其中类型引用和类型本身视为同一个特征标。

 void staff(double & rs); void staff(const double & rcs);  //函数重载  long gronk(int n,float m) ; double gronk(int n, float m);  //不是函数重载

当函数基本上执行相同的任务,但使用不同形式的数据时,才应采用函数重载。如果两个重载函数,只是参数的个数不同,类型相同,则可以使用一个带默认参数的函数要简单一些。

 char *left(const char *str,int n);  使用默认参数 char *left(const char *str);         ========>  char *left(const char *str,int n=1);

1.6 函数模板
函数模板不能缩短可执行程序,最终的代码不包含任何模板。编译器使用模板为特定类型生成函数定义得到的是模板的实例,模板并非函数的定义,使用模板实例是函数定义。模板的实例分为显式实例化和隐式实例化。当模板显式实例化时的参数类型不同时,可强制类型转换。

 template <typename T>  //template和typename 为关键字,T为任意名称 void Swap(T &a, T &b); void Swap(T *a, T *b,int n);     //函数模板原型  template <typename T>  //函数模板定义  template和typename 为关键字,T为任意名称 void Swap(T &a, T &b){     T temp;     temp=a;     a=b;     b=temp; } void Swap(T *a, T *b,int n){   //函数模板的重载     T temp;     for(int i=0;i<n;i++){         temp=a[i];         a[i]=b[i];         b[i]=temp;     }   } int main(){     int aa=13,bb=19;       //函数模板可以代入不同类型的数据     double daa=1.3,dbb=1.9;     Swap(aa,bb); // aa=19,bb=13;  //隐式实例化     Swap<double>(daa,dbb);  // 显式实例化,编译器直接创建特定的实例 }

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!