C++——函數及調用


1.函數調用:實參初始化形參;控制權交給被調函數

2.函數返回(return語句):返回return中的值;控制權交回主函數

3.參數傳遞

  傳值 傳引用 傳指針
初始值 不變,拷貝給形參

可變,形參是實參的別名

若不想變,加const

拷貝指針給形參
       
//1.傳指針
void reset(int *p)
{
  *ip=0;//改變了指針所指向對象的值
  ip=0;// 只改變ip的局部拷貝,實參未被改變。指針本身可以在局部內任意變化,但指針指向的值沒變    
}
int i=42;
reset(&i);//改變I的值,而非地址
cout<<i<<endl;//i=0

//2.傳引用
void reset(int &i)
{
    i=0;
}
int j=42;
reset(j);//改變I的值,而非地址
cout<<j<<endl;//j=0

 

4.const參數傳遞

void reset(int &i)//引用傳遞
{
    i=0;
}

void reset(int *ip)//指針傳遞
{
    *ip=0;
}

int i=0;
const int ci=i;
string::size_type ctr=0;

reset(i);//引用傳遞
reset(&i);//引用傳遞
reset(ci);//×,int類型不能傳遞給const int類型
reset(&ci);//×,const in *類型不能傳遞給int *類型
reset(42);//×
reset(ctr);//×

如果函數參數是const呢?能接受什么參數傳入?

 

5.數組形參

//三個函數等價,形參是const int*
void print(const int*);
void print(const int[]);//
void print(const int[10]);//期望含有10個元素的數組,實際不一定,那實際怎么操作,如果元素>10的話?

int i=0,j[2]={0,1};
print (&i);//int*類型
print(j);//自動轉為int *

5.1 判斷數組長度

  1.使用標記(字符串末尾空)

void print(const char*cp)
{
    if(cp)
    {
         while(*cp)//判斷方法
            cout<<*cp++
    }
}

  2.使用標准庫

void print(const int *beg,const int *end)
{
  while (beg!=end)
      cout<<*beg++<<endl;        
}

int j[2]={1,2};
print(begin(j),end(j));

  3.顯式傳遞大小

void print(const int ia[],size_t size)
{
    for (size_t i=0;i!=size;i++){
        cout<<ia[i]<<endl;
    }
}

 

6.main命令行,傳遞參數

int main(int argc, //
    char *argv[])//argv是數組,元素是char*指針
{
}

//與上式等價
int main(int argc,//
    char ** argv)//argv  指向char*
{
}

prog -d -o file data0//可執行文件prog,輸入參數
//argc=5
//argv[0]= "prog";
//argv[1]= "-d";
//argv[2]="-o";
//argv[3]=" file";
//argv[4]=" data0";

 

7.可變形參

7.1 類型相同,數量不同——initializer_list標准庫類型

常量值,無法改變,只讀

void error_msg(initializer_list<string> istring)
{
  for (auto beg=istring.begin();beg!=istring.end();++beg)
        cout<<*beg<<" ";
  cout << endl;     
}

if (expected !=actual)//2 個string 對象
    error_msg({"FunctionX output:",expected, actual });//{}用於傳遞initializer_list序列
else
    error_msg({"FunctionX output:","Okay"});

可根據實際改寫為先打印錯誤代碼,再打印內容:

void error_msg(ErrorCode e, initializer_list<string> string)
{
  cout<<e.print()<<":"  
  for (const auto & elem:string)
      cout<< elles<<" ";
  cout<<endl;      
}

7.2 省略符形參:varargs標准庫

 

8.函數返回

8.1 不要返回局部對象的引用或指針

8.2 返回數組

1.聲明返回數組指針的函數

int (*func(int i))[10];//解引用的結果是一個10個int元素的數組
//func(int i):
//(*func(int i)):對函數調用的結果解引用
//

2.尾置返回?

auto func(int i)->int(*)[10];

3.decltype返回?

int odd[]={1,3,5,7,9};
int even[]={0,2,4,6,8};
decltype (odd) *arrptr(int i)//decltype不會把數組轉為指針
{
  return (i%2)?&odd:&even;  //返回一個指針,該指針指向含有5個整數的數組
}

 

9.函數重載

9.1.不能定義兩個除了返回值類型不同外,其他都相同的函數

9.2 有時候兩個形參看起來類型不一樣,實際上相同,也是不許的

9.3 帶頂層const的形參和不帶const的形參是無法區分的

bool lookUp(Phone);//1
bool lookUp(const Phone);//2,與1重復。/?
bool lookUp(Phone*);//3
bool lookUp(Phone* const);//4,與3重復。/?

bool lookUp(Phone&);//5,作用於Phone的引用
bool lookUp(const Phone&);//6,作用於常引用,同時存在會優先選用
bool lookUp(Phone*);//7,作用於指向Phone的指針
bool lookUp(const Phone *)//8,作用於指向常量的指針,同時存在會優先選用
 
        

 

10.默認實參:一旦有一個參數為默認,其他必須給默認值

string screen(size_type hight=24, size_type width=80);

window=screen();
window=screen(100,200);

 

11.內聯函數

1.定義在頭文件中(文件中多次要用)

 

12.constexpr函數

1. 函數的返回類型、形參類型都是字面值類型

2.函數中有且僅有一條return語句

3.定義在頭文件中

constexpr int new_size()
{
    return 42;
}

constexpr size_t scale(size_t cnt)
{
    return new_sz()* cnt;
}

int arr[scale(2)];

 

13.函數調用時的實參匹配

1.精確匹配

2.const轉換實現匹配

3.類型提升實現匹配

4.算術類型轉換(或指針轉換)實現匹配

5.類類型轉換實現匹配

bool lookUp(Account &);
bool lookUp(const Account &);

Account b;
lookUp(b);//兩個都可以調用,但是第一個優先

 

14.函數指針

bool lengthCompare(const string &,const string &);

bool (*pf)(const string &,const string &);//pf是指向函數的指針
//bool *pf(const string &,const string &);//聲明一個名為pf的函數,返回bool *

pf = lengthCompare;
pf =& lengthCompare;//與上等價

bool b1=pf("hello","goodbye");
bool b2=(*pf)("hello","goodbye");
bool b3=lengCompare("hello","goodbye");//三式等價

14.1 返回指向函數的指針

14.2 auto 和decltype用於函數指針類型

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM