国产丰满大乳无码免费播放_久草一级毛片_国产av黄色一区二区_亚洲一级 片内射欧美乱强上司_制服丝袜亚洲日韩中文字幕欧美_亚洲av中文小島_国产精品无码久久av嫩草下载_91视频黄片软件APP大全

XML|HTML|TXT
您當前位置: 軟件開發>> 新利在線娛樂>> 軟件開發行業資訊>> 瀏覽文章

C++中函數的用法小結-濟南軟件開發

  函數在C++中的使用,無非2種地方,一處是函數的定義,一處是函數的調用。而函數的定義則非常簡單,由三個部分組成:函數的返回類型、函數名和函數的形參表。當然,這里不同的函數定義可以還會稍有不同,比如類的成員函數、內聯函數等。這里我們主要討論函數的調用時需要注意的一些問題。

  一、參數傳遞

  我們將函數定義或聲明里的參數叫形參,而在調用函數時傳入的參數叫實參。那么根據形參類型的不同,有幾下形式的參數傳遞。

  1,非引用形參

  1)普通的內置類型

  普通非引用類型的參數通過復制對應的實參實現形參的初始化。當用實參的副本初始化形參時,函數并沒有訪問調用所傳遞的實參的本身,因此函數不可能改實參的值。比如下面的交換兩個數的程序:

  void swap(int v1, int v2)

  {

  int temp = v1;

  v2 = v1;

  v1 = temp;

  }

  swap(a, b);// 調用swap

  上面程序中,實參為a與b,但是在調用時,v1與v2接受的是a與b的副本,所以實際上a與b的值沒有變化。

  2)指針形參

  函數的形參可以是指針,此時將復制實參指針,其實這類跟1)原理類似,函數內并無法改變實參的指針值。只是函數可以通過復制到的地址改變實參指針所指向的值。

  void swap(int* v1, int* v2)

  {

  int temp = *v2;

  *v2 = *v1;

  *v1 = temp;

  }

  int main()

  {

  int a = 10,b = 20;

  int *p1 = &a,*p2 = &b;

  swap(p1,p2);

  return 0;

  }

  上面程序中定義的swap的形參為指針類型,main中調用swap,實際上swap并不能改變p1與p2的值,只是改變了它們所指向的值。

  3)const 形參

  對于普通的非引用類型用const修飾實際上是沒有意義的,因為本來函數就不會改變實參的值。像下面的定義,實際中編譯器會忽略const的定義,而將其視為int型。

  void fcn(const int i);

  2,引用形參

  1)在上面的程序中我們看到,如果想交換兩個變量的值,通過調用普通的非引用類型形參的函數,并不能實現。用它們的指針可以,同時我們也可以用引用。

  void swap(int& v1, int& v2)

  {

  int temp = v2;

  v2 = v1;

  v1 = temp;

  }

  int main()

  {

  int a = 10,b = 20;

  swap(a,b);

  return 0;

  }

  在實際調用swap時,v1與v2實際相當于a與b的另一個名字。

  2)在有的時候我們需要向函數傳遞大型對象,需要使用引用形參,如果直接使用復制實參的形式可以,但是它的效率太低了,甚至有些對象是無法復制的。但是使用引用形參時,我們不希望函數改變了實參傳入的值,我們就可以使用const來限定形參。下面程序用來判斷哪個字符串更長,明顯我們不希望函數會改變字符串的內容,我們就可以用const引用型的形參。

  bool isLonger(const string &s1, const string &s2)

  {

  return s1.size() > s2.size();

  }

  所以,如果使用引用形參的惟一的目的是避免復制實參時,則應將形參定義為const引用。

  3)在使用引用形參函數時,有兩點值得注意:

  不要用const限定的實參或字面值來調用非const引用形參函數。因為這樣函數內,可以改變實參的值,這不合法。

  非const引用形參只能與完全同類型的非const對象關聯。

  4)傳遞指向指針的引用

  如下有下面的程序:

  void swap(int* &v1, int* &v2)

  {

  int* temp = v2;

  v2 = v1;

  v1 = temp;

  }

  int main()

  {

  int a = 10,b = 20;

  int* p1 = &a, *p2 = &b;

  swap(p1,p2);

  return 0;

  }

  上面的程序依然不能改變a與b的值,但是它改變了p1與p2的值,現在p1指向了b,而p2指向了a。

  3,其他類型的形參

  1)vector和其他類型的形參:一般在這種類型作為形參時,為了避免復制應該考慮形參聲明為引用類型。C++程序員傾向于傳遞容器中需要處理的元素的迭代器來傳遞容器。

  2)數組形參:由于數組不能復制,所以不能直接編寫數組類型的形參函數,一般通過傳遞指向數組的元素的指針來處理數組。值得注意的是在通過引用傳遞數組時,在調用函數時形參與實參的類型要匹配。

  void printValues(int (&ar)[10]);

  int main()

  {

  int i = 0, j[2] = { 0, 1 };

  int k[10] = {0,1,2,3,4,5,6,7,8,9};

  printValues(i); //error int不能初始化 int(&)[10]

  printValues(j); //error int[2] 不能初始化 int(&)[10]

  printValues(k); // ok

  return 0;

  }

  二、函數的返回值

  1)沒有返回值

  很多函數并沒有返回值,尤其是現在C++風格,習慣于把需要的結果作為引用形參。這類型函數一般沒有return語句,有時候有return是使函數中途中斷執行。

  2)返回非引用類型

  這種情況在函數調用處,程序會用一個臨時變量復制函數的返回值。

  3)返回引用

  當函數返回引用類型時,并沒有復制返回值。相反,返回的是對象本身。

  在返回引用這種情況下,注意不要返回局部變量的引用,因為局部變量在函數體內定義,當函數執行完后就銷毀了,所謂的引用也就沒有意義了。同理,不要返回指向局部變量的指針。

  三、重載函數

  出現在相同作用域中的兩個函數,如果具有相同的名字而形參不同,則稱為重載函數。

  1)注意區分函數重載與重復聲明

  有些看起來不同的形參,本質是相同的。下面代碼中的都是重復聲明的例子

  typedef double newDouble;

  int func(double i);

  int func(newDouble i); // 沒有新類型

  int func1(int, int = 1); //只是提供默認參數

  int func1(int ,int);

  int func2(int);

  int func2(const int); //對于普通非引用形參用cosnt修飾是沒有意義的

  2)重載與作用域

  局部聲明的函數,將屏蔽所有全局作用的同名函數。下面例子顯示,即使全局作用的函數更加匹配調用的實參類型,但是仍然調用的是局部的函數。

  void print(int);

  int main()

  {

  void print(double);

  print(42);

  return 0;

  }

  上面程序中,將調用void print(double)函數,雖然42是int型。

  3)重載確定的三個步驟

  如果定義了眾多的函數重載,將存在函數調用到底與哪個重載函數相匹配的問題。我們通過下面的示例代碼來說明問題:

  void f(); // 1

  void f(int);// 2

  void f(double);// 3

  void f(int, int);// 4

  void f(double, double);// 5

  第一步:確定候選函數

  假如我們調用f(4.2),那么先找到同名函數,并且在作用域內可見,上面例子中5個函數都滿足。

  第二步:選擇可行的函數

  必須滿足2個條件:一是函數形參與該調用實參個數相同;第二,每個實參的類型必須與對應的類型匹配,或者可以被隱式轉換為對應的形參類型。這里我們再調用f(4.2)時,排除了1、4、5號函數,只剩下2與3。其中2號函數可以通過類型轉換來滿足。

  第三步:尋找最佳匹配

  在經過第二步確定后,剩下2與3函數,那么2需要進行類型轉換,顯然3是最佳匹配了。

  但是如果這樣調用f(42,4.2)。這時候就會出現二義性,編譯器將提示。

  還有一種要注意的就是有默認參數的函數,比如我們定義6號函數為void f(double,int =1);那么在調用f(4.2)時就會有二義性。

  可基于函數的引用形參是指向const對象還是指向非const對象實現函數重載。


手機:18678812288 E-Mail:1069706080@qq.com
地址:山東省濟南市舜耕路泉城公園東門園內向北50米 魯ICP備07011972號 版權所有2008-2013 新利體育18
Baidu