函數(shù)總結(jié)

函數(shù)的基本構(gòu)成

  • 輸入
  1. 實參傳值給形參
  • 傳值參數(shù):拷貝復制,基本類型和指針。
int n = 0; i = 42;
int *p = &n, *q = &i;
*p = 42; // n的值發(fā)生改變,p的值并不會發(fā)生改變。
p = q; // p 的指向發(fā)生了改變

所以說,指針作為形參,只是存儲了變量的地址。就是說調(diào)用函數(shù)的時候,實參地址傳遞給形參,形參拷貝實參的值,也就是地址。說明了參數(shù)調(diào)用時,發(fā)生的是值拷貝。但是通過解引用運算符(*)可以進行實參的賦值操作

void reset (int *ip){
*ip = 0; // 解引用操作,改變其所指對象的值;
ip = 0; // 只改變了ip 的局部拷貝,并不影響實參的值。
}

換句話來說,由于指針也是對象,所以當指針作為形參時,指針的值完成了從實參到形參的拷貝。形參作為被調(diào)函數(shù)的局部參數(shù)。當調(diào)用結(jié)束后,函數(shù)的形參被銷毀。
經(jīng)典例子

// 并不能交換實參的值
int a = 1; b= 2;
void swap(int x, int y){
int temp;
temp = x;
x = y;
y = temp;
}

理解思路:程序順序執(zhí)行的時候,其實是不斷地開棧清棧的過程,作為聲明的全局變量,他擁有屬于他的內(nèi)存。調(diào)用函數(shù)的過程是值拷貝的過程。被調(diào)函數(shù)想改變?nèi)值淖兞?,只有可能通過綁定地址來操作。因為本質(zhì)上來說,形參與實參都會開辟內(nèi)存,只不過形參的生存期僅在函數(shù)調(diào)用的時間段。當被調(diào)用結(jié)束后,形參的生存期結(jié)束。釋放內(nèi)存。引用和指針都是一種綁定的操作。
但是現(xiàn)在基本上程序中基本上不會出現(xiàn)這種代碼,因為形參基本上都是傳引用參數(shù),這樣的好處有很多,避免了拷貝會出現(xiàn)的大規(guī)模開內(nèi)存的情況。因此,引用傳遞參數(shù)會天然的綁定到實參中,如果程序的本意并不是改變實參,那么常見const 形參,如果要改變實參,就可以使用引用,避免拷貝。

  • 傳引用參數(shù)
    綁定類型的典范,建議使用引用作為形參,來避免拷貝。
    當不修改,實參的值時:建議使用 const 引用傳參。
    修改實參時,也建議通過引用來避免拷貝運算。
  • 初始化與賦值操作是兩種不同的操作
  1. 非const 的初始化操作注意值對應。
  2. const 形參注意底層const 的誤區(qū)。
    建議常量引用的類型避免了底層const的報錯;
void fcn(const int i) // fcn 能讀取i ,但不能寫;
void fcn(int i ) // 重復定義,因為初始化的時候會忽略掉頂層const
  1. 數(shù)組作為形參
    數(shù)組這種類型不允許拷貝(感覺所有占大內(nèi)存的數(shù)據(jù)類型都是不允許拷貝的會消耗棧的空間)。所以當其作為形參時,數(shù)組會被轉(zhuǎn)化成指針。
void print(const int*);
void print(const int[]);//等價表達
void print(const int[10]);//傳遞的函數(shù)類型是const int *
  • 由于數(shù)組有大小限制,因此要特別注意數(shù)組形參的大小。
void print(const int *beg, const int *end){
while (beg != end)
cout <<  *beg++ << endl;
}
void print(const int ia[], size_t size){
for (size_t i = 0; i != size; i++)  // for (auto elem : ia)
cout << ia[i] << endl;   // cout << elem << endl;
}
  • 多維數(shù)組
    多維數(shù)組的定義實際上是數(shù)組的內(nèi)容是數(shù)組。因此執(zhí)行拷貝操作,實際上是做的將指針指向數(shù)組。
void print (int (*matrix) [10],int rowsize)
void print (int matrix[] [10], int rowsize) // 等價操作

[] 下標操作符,& 取地址操作符,實質(zhì)上都會反饋迭代器操作,也就是指針。

  • main :處理命令行選項
    有時候要給main 函數(shù)傳遞參數(shù),根據(jù)一組選項來確定函數(shù)要執(zhí)行的操作。
int main (int argc,char *argv[]); // argv大小為argc的裝著C風格字符串的數(shù)組。
int main (int argc, char **argv[]) //等價寫法
  • 形參可變
    intitializer_list <T> lst; 存儲可變大小的相同類型的一種形參,支持迭代器操作。

2.返回值

  • 可以飲用返回,不發(fā)生臨時變量的拷貝動作,同時還可以作為左值;
    deltype (左值) 返回 引用類型。引用類型是可以作為左值的,也就是說要賦值。
  • auto 和 deltype 的用法
  • 不要返回局部對象的引用或者指針
  • 返回數(shù)組數(shù)組指針的寫法
int arr[10];
int *p1[10]; // 十個指針的數(shù)組
int (*p) [10] = &arr; // 指向數(shù)組的指針
int (*func(int i))[10];
auto func(int i) -> int (*) [10];
  • 函數(shù)指針和lambda 表達式
bool lengthCompare(const string &, const string &);
bool (*pf) (const string &,const string &);// 函數(shù)指針
pf = lengthCompare;// pf 指向lengthCompare 函數(shù)
pf = &lengthCompare //等價說法,&可選;
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,536評論 1 51
  • 307、setValue:forKey和setObject:forKey的區(qū)別是什么? 答:1, setObjec...
    AlanGe閱讀 1,586評論 0 1
  • 1. C++基礎知識點 1.1 有符號類型和無符號類型 當我們賦給無符號類型一個超出它表示范圍的值時,結(jié)果是初始值...
    Mr希靈閱讀 18,040評論 3 82
  • 旅行中,靈魂常常會滯后于身體的存在,常常是你人已經(jīng)回家啦,可靈魂還沒有回來噢,在時空的轉(zhuǎn)換之間。
    麥小然閱讀 107評論 0 0
  • 26歲,你看著身邊的人都結(jié)了婚 婚禮的份子錢逐年遞增 春節(jié)回家,父母從帶你串親戚 變成了帶你去見相親對象 見了十幾...
    快樂的小博兒閱讀 259評論 2 3