C++Primer 5th Chap6 Functions(未完)

局部静态变量,关键字static修饰,即使函数结束执行也不受影响,生存期直到程序终止。

  java中static的单一存储空间的概念与其或有异曲同工之妙。

函数的形参可以无名,但有名可以使其意义更加清晰。

分离式编译的一种模式:头文件中声明函数,在name.cpp文件中定义,最后在name_main.cpp中实现

 若函数传值调用,则实参和形参为两个独立的个体;若函数传引用调用,形参为实参的别名,即同一个体

形参为指针

  例如:void reset(int *p){

      *p=0;//解引用改变所指对象的值

      }

     int i=24;

     reset(&i);//此时i==0

形参为引用

  例如:void reset(int &p){

      p=0;}//p所引用的对象的值被改变

    int j=24;

    reset(j);//此时j==0,reset内部对 p 的操作即为对 j 的操作

  如果类类型过大或者就不支持拷贝,则需要以引用为函数形参(如果不希望改变对象的值,参数类型应为const)

  另外传引用可以获得额外信息,在函数使用完毕后,传入的参数其值保留

若函数的形参为顶层const,传入非const参数作为实参是允许的(此时顶层const被忽略,故仅仅有无const不能重载函数)

  与上一条相对地,若形参为非常量,则禁止传入常量实参

若非必要,引用型形参尽量是常量引用,若函数嵌套调用时内外层引用形参不同为常量/非常量,易引发错误

  例如:void func1(const string &s){

      /*.........................*/

      func2(/*string*/ s);}//此例即不通

数组形参

  例如:void func(const int*);

     void func(const int [ ]);

     void func(const int [10]);//仅表示希望的元素个数,实际调用不一定,与前两条等价

  防止越界的操作:

  例如:void print(const char *cp){

      if(cp)//非空指针

        while(*cp)//非空字符

          cout<<*cp++;}//向后位移

  也可:void print  (const char *beg,const char *end){//end是尾后元素

      while(beg!=end)//输出不含end的所有元素,end可由end(arr)获取,begin可由begin(arr)获取

        cout<<*beg++;}

  也可:void print  (const int ia[ ],size_t size){

      for(size_t i=0 ; i != size; i++){

        cout<<ia[ i ];}//显式固定大小

数组引用形参

  例如:void print( int (&arr)[10]){//注意括号位置

      for(auto elem:arr)

        cout<<elem;}//不足是大小固定  

多维数组形参

  例如:void print( int (*matrix)[10], int rowsize){/*.............*/}

处理命令行选项时,main函数需要参数:int main(int argc,char* argv[ ])

可变形参

  initializer_list形参:(形参数目未知,类型相同)

  

initializer_list<T> lst 默认初始化,T类型空列表
initializer_list<T>lst{a,b,c...} const T 类型元素与lst列表中数量相同,是对应初始值的副本
lst2(lst)或lst2=lst 拷贝或赋值initializer_list对象,但不赋值列表中的元素,原列表和副本共享元素
lst.size() 列表元素数量
lst.begin() 指向lst首元素的指针
lst.end() 指向lst尾后元素的指针

 

  例如:void print(initializer_list<string> lst){

      for(auto beg=lst.begin();beg!=lst.end();beg++)

        cout<<*beg;   }

     print({"FunctionX","Okey"});//调用时必须带花括号

  省略符形参:(并不好用,传递参数容易出错)

  例如:void foo(int,...);

     void foo(...);//省略符必须在参数列表末尾

返回值和return:

  不要返回局部对象的指针或引用(函数完成后,局部对象就已经不存在了)   

   调用一个返回引用的函数得到左值,其他返回类型得到右值。

   c++11允许返回一组花括号括起来的列表(列表初始化返回值),若为内置类型列表内仅能包含最多一个值:

   例如:vector<string>process(){

      /*..........*/return{};

      /*..........*/return{"Hello","World"}; }

  返回数组指针(指向数组的指针):(如果不想使用类型别名,定义的名字后面数组的元素个数要记住)

  例如: int(*func(int i))[10];

  尾置返回类型(c++11):像是返回数组指针或者数组引用之类的复杂类型较为合适,当然所有类型返回值都可用

  例如:auto func(int i)->int(*)[10];(得到了与上一条相同的效果,而且更加清晰)

   使用decltype(c++11):(已知返回的指针指向哪个数组)

  例如:int odd[ ]={1,3,5,7,9};

     int even[ ]={2,4,6,8,10};

     decltype(odd) *func(int i){//注意此处*不能省

       return (i%2)?&odd:&even;}

     

猜你喜欢

转载自www.cnblogs.com/hfut-freshguy/p/11495755.html