天天看點

C++ 回憶錄5

1. 函數定義中的傳回值不能缺少,

test();//在早期的C++ standar 這個是可以的,因為會隐隐式假定傳回int. but  now ,can not .

2.函數可以傳回built-in type like int,double. class type,compound type such as :int &,string * and void.

但卻不可以傳回另外的函數,或者數組, 如果有這需要,可以用函數指針,或者數組的指針.

int * fool(){.............} ,傳回指向數組的第一進制素的位址..

3.函數在調用時候, 起參數清單才會初始會,這個普通變量是一樣的,如果不是應用類型, 則是用傳給函數的argument 去初始化(copy  方式,即傳值)這些參數,然後作為函數的local varible 使用,如果是reference type,則隻是傳的argument 的另外一個引用,不會copy.,,

就算傳指針,也做copy.

int testfunction(int b,int & c,int * k); //c,k 都會改變傳遞的argument 值,除非定義成const

int arg=10;

const int arg2=10;  //arg2 的位址是不能傳給k的. 因為const int * 不能轉成int *. ,當然可以傳遞給 b,因為可以copy 10去初始化b.

testfunction(arg,arg,&arg); b- copy, c, not copy, k, 會copy arg 的位址給k,初始化

k的改變會影響到arg 的值.

*k=20;// 此時arg=20;

k=0;//k的位址置空了,但不會影響到arg  的位址. but can not delete K, or else *k will be deleted

如果不想在函數内部把arg的值改變,則可以這樣定義:

int testfunction(int b,int & c,const int * k); 把這個指針定義成const

此時arg2 也可以傳遞給k 了.

是以const int *  好..

copy 的方式去初始化,還是有limitation 的,比如大對象的時候...這時候傳遞位址,或引用,,多快,,

int testfunction(int b,const int & c,const int * k);這樣c,k都不可以改變argument 的值了... c 沒有copy initilize , k 需要copy 一個位址..

如果想讓指針也不copy ,有辦法reference

int testfunction(int b,const int & c,const int *  &k);  這樣k也不copy initilize 了.

4 使用數組作為參數

void testArray1(int k[])

{

  cout<<"testArray1"<<k[0]<<endl;

}

void testArray2(int k[10])

{

 cout<<"testArray2"<<k[0]<<endl;

}

void testArray3(int * k)

{

 cout<<"testArray3"<<k[0]<<endl;

}

void testArray4(int (&k)[10])

{

 cout<<"testArray4"<<k[0]<<endl;

}

void testArray5(const int k[])

{

  cout<<"testArray5"<<k[0]<<endl;

}

void testArray6(const int (&k)[10])

{

 cout<<"testArray6"<<k[0]<<endl;

}

void testArray7(const int (*k)[10])

{

 cout<<"testArray6"<<k[0][0]<<endl;

}

1,2,3 是等價的

4,是為了指定數組的次元

5.不改變數組的内容

6 不改變數組的内容 指定數組的次元  ,注意括号不能少

7 多元數組

如何管理數組的長度,有三中辦法

a.象字元數組那樣,給一個結束标志 char * str="adfasfsaf";//  null結尾,我們可以在函數中檢查這個标志

b.傳遞 數組的開始,結束+1 的位址

void printValue(const int * begin,const int * end)

{

   while(begin!=end)

  {

 cout<<*begin++<<endl;

}

}

int a[2]={1,3};

printValue(a,a+2);

3. C,pre-stadandar C++ 的做法,多傳遞一個數組長度的參數,main 就就是個很好的例子

void printValue(int  [] a, size_t len)................

5. 可省略可參數

void foo(para_list,...)

void foo(...);

沒有type checking for ellipsis parameter.

6 關于傳回值

6.1 return NONReference  ,函數會在最後傳回的時候,傳回值copy 一份給調用者

string makString()

{

 return string("abcd");

}

即使是類對象也是一樣copy的.

string k=makString();//ok.

6.2 return Reference ,傳回引用的話,no copy to caller. 但是,不能傳回local Object

const string & shortString(const string & s1,const string & s2)  傳回值加上const ,是使傳回值不可以被改變. 因為傳回值是Lvalue.

{

  return s1.size()<s2.size()?s1:s2;  //ok.

  string a2;

  if(s1.size()<s2.size())

  a2=s1;

else

a2=s2;

return a2;// 不能傳回local Object

}

6.3 return Pointer, copy 一個位址,但是,不能傳回local Object Pointer

7 函數的聲明可以是多次,但定義隻能是一次..

8.參數預設值.

void kkkk(int a,int b=10)

kkk(5);//ok ,equal kkk(5,10);

如果函數的定義中聲明了參數的預設值,那麼聲明裡就不用了,反之亦然.

fff.h

void kkkk(int a,int b=10);

fff.c

void kkkk(int a,int b=10)  //error....

{

.................

}

9 static local Object

函數中定義的對象是local scope,will destroy after call end.

but if we define it as static ,then will exit even thoug the call end.

10 inline function

函數的調用是要做很多工作的,如儲存和恢複寄存器,copy argument,ect. 如果我們的函數隻是少數幾個statment,no for,那我們可以用inline function

inline function will ben expand during compilation. ie:

inline string getshortStr(const string  & s1,const string & s2)

{

 return  s1.size()<s2.size()? s1:s2;

}

cout <<getshortStr(s1,s2)<<end;

while compile ,will expand like this below:

cout <<s1.size()<s2.size()? s1:s2 <<end;

if we use this will save the function invocatino

注意inline function 隻能定義在.h 檔案中.

11 類成語函數後面的const

class A

{

 public :

 double var1;

 double getVar1() const   //類中的成員函數後面加上const ,意思是這個 隐藏的this 指針是const ,那麼就是說, 通過這個指針你不能改變其成語var1 的值.

 {

this.var1=10;// error .

 return this.var1;

}

};