C++Primer 函數

1.函數的調用:用對應的實參初始化函數的形參,並將控制權轉移給被調用函數。

2.形參和實參:形參在函數定義的形參表中進行定義,是一個變量,其作用域爲整個函數。而實參是出現在函數調用中的表達式。進行函數調用時用傳遞給函數的實參對形參進行初始化。實參和形參必須數目相同,類型可以轉換。

3.非引用形參:這類形參其實只在函數內部修改了實參的副本,並不影響實參真正的值。

void swap(int &v1,int &v2)
{
  int tmp = v2;
  v2 = v1;
  v1 = tmp;
}

而如果是指針形參,則他指向的元素可以修改,他本身在函數中的修改並不在函數外呈現。即跳出函數後ip仍然指向原來的元素。

如果要保護指針指向的值,則形參需要定義爲const int *ip。


4.引用形參:在希望改變實參的值,或者希望避免複製大量實參的情況下,使用引用形參。這裏的引用形參直接關聯到所綁定的對象,而並不是這些對象的副本。

void swap(int &v1,int &v2)
{
  int tmp = v2;
  v2 = v1;
  v1 = tmp;
}

指向指針的引用:這裏v1是一個引用,與指向int型對象的指針相關聯。

void ptrswap(int *&v1,int *&v2)
{
  int *tmp = v2;
  v2 = v1;
  v1 = temp;
}


在希望得到另外的信息時,occurs作爲引用形參,可以同步改變值,並最終在主函數中得到這個值。

it = find_val(ivec.begin(),ivec.end(),find_value, ctr)
vector<int>::const_iterator find_val(
vector<int>::const_iterator beg,
vector<int>::const_iterator end,
int value,
vector<int>::size_type &occurs)


const引用:將不需要修改的應用形參都定義爲const引用,普通的非const引用形參既不能用const對象初始化,也不能用字面值或產生的右值表達式初始化。


5.容器類型的形參:要避免複製容器,通常傳輸指向容器中元素的迭代器作爲形參。

6.數組形參:數組不能複製,數組名會自動轉化爲指向其第一個元素的指針。因此數組形參其實就是指針,可以直接定義爲指針。可以通過函數改變這個指針指向的數組值。除非指針定義爲const int*。

void printValues(int *)
void printValues(int[])
void printValues(int[10])//這裏雖然定義了長度,其實並沒有強制實現這個長度

通過引用傳遞數組:數組大小稱爲形參和實參類型的一部分,這裏是數組,不是指針。

void printValues(int (&arr)[10])

多維數組的傳遞:第一個指針,是指向二維數組的第一組內層數組的指針。

void printValues(int (*matrix)[10],int rowSize)

7.main:int main(int argc, char *argv[])//argv是一個c風格字符串數組

8.return語句:不帶返回值的return;只能用在返回類型爲void的函數,其實這時並不必須在末尾寫return;因爲函數會在最後一個語句之後隱式的完成return,通常在函數中間用return,是爲了提前結束函數的運行,類似break的作用。

返回非引用類型:編譯器會創建一個臨時對象,存這個返回值。

返回引用類型:沒有複製返回值,返回的是對象本身。一定不能返回局部變量的引用或指針。返回引用時可以給這個返回值賦值,因爲他是左值。


9.函數的聲明:可以聲明多次,定義一次,通常在頭文件中。

函數原型:函數返回值類型,函數名,形參列表。不需要形參名。

void print(int *array, int size);

默認實參:給形參列表中的形參提供明確的初始化,在調用時沒有實參,則用默認實參,有則覆蓋。

string screenInit(string::size_type height = 24,
                  string::size_type width = 80,
                  char background = '')

10.局部對象與自動對象:只有當定義它的函數被調用時才存在的對象稱爲自動對象,包括形參。自動對象在定義他們的快語句結束時撤銷。

靜態局部對象,一旦被創建在程序結束前都不會撤銷。

size_t count_calls()
{
  static size_t ctr = 0;
  return ++ctr;
}


11.內聯函數:避免函數調用的開銷。一個只有幾行,經常使用的函數,如果一直去調用會很耗費資源。將他定義爲內聯函數,可以在程序中的每個調用點內聯的展開函數。因此內聯函數必須在編譯時是可見的,要在頭文件中定義。

inline const string &shortString(const string &s1,const string &s2)
{ return (s1.size()<s2.size() ? s1 :s2);} 

cout<< shourterString(s1,s2)<<endl;
cout<< (s1.size()<s2.size() ? s1 :s2) <<endl;


12.指向函數的指針:pf聲明爲指向函數的指針,所指向的函數帶有兩個const string類型的形參和bool類型的返回值。這裏的cmpFcn則是一種指向函數的指針類型的名字。

bool (*pf)(const string &, const string &);
typedef bool (*cmpFcn) (const string &, const string &);

以下兩種賦值是等效的。

cmpFcn pf1 = lengthCompare;
cmpFcn pf2 = &lengthCompare;

調用也是等效的:

lengthCompare("hi","bye");
pf("hi","bye");
(*pf)("hi","bye");

返回指向函數的指針:ff(int)是一個函數,返回的是一個指向函數的指針 int (*)(int*,int);

int (*ff(int))(int*,int);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章