ï»?!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  函数在C++ä¸çš„使用åQŒæ— é?¿U地方,一处是函数的定义,一处是函数的调用。而函数的定义则éžå¸¸ç®€å•,ç”׃¸‰ä¸ªéƒ¨åˆ†ç»„æˆï¼šå‡½æ•°çš„返回类型ã€å‡½æ•°å和函数的形å‚表。当ç„Óž¼Œ˜q™é‡Œä¸åŒçš„函数定义å¯ä»¥è¿˜ä¼šç¨æœ‰ä¸åŒï¼Œæ¯”如¾cÈš„æˆå‘˜å‡½æ•°ã€å†…è”函数ç‰ã€‚这里我们主è¦è®¨è®ºå‡½æ•°çš„调用旉™œ€è¦æ³¨æ„的一些问题ã€?/span>
  一ã€å‚æ•îC¼ é€?/span>
  我们ž®†å‡½æ•°å®šä¹‰æˆ–å£°æ˜Žé‡Œçš„å‚æ•°å«åÅžå‚ï¼Œè€Œåœ¨è°ƒç”¨å‡½æ•°æ—¶ä¼ å…¥çš„å‚æ•°å«å®žå‚ã€‚é‚£ä¹ˆæ ¹æ®åÅžå‚类型的ä¸åŒåQŒæœ‰å‡ 下形å¼çš„傿•îC¼ 递ã€?/span>
  1åQŒéžå¼•用形å‚
  1åQ‰æ™®é€šçš„内置¾cÕdž‹
  普通éžå¼•用¾cÕdž‹çš„傿•°é€šè¿‡å¤åˆ¶å¯¹åº”的实å‚实现åÅžå‚çš„åˆå§‹åŒ–。当用实å‚的副本åˆå§‹åŒ–åÅžå‚æ—¶åQŒå‡½æ•°åƈ没有讉K—®è°ƒç”¨æ‰€ä¼ 递的实å‚的本íw«ï¼Œå› æ¤å‡½æ•°ä¸å¯èƒ½æ”¹å®žå‚的倹{€‚比如下é¢çš„交æ¢ä¸¤ä¸ªæ•°çš„½E‹åºåQ?/span>
  void swap(int v1, int v2)
  {
  int temp = v1;
  v2 = v1;
  v1 = temp;
  }
  swap(a, b);// 调用swap
  上颽E‹åºä¸ï¼Œå®žå‚为a与båQŒä½†æ˜¯åœ¨è°ƒç”¨æ—Óž¼Œv1与v2接å—的是a与b的副本,所以实际上a与b的值没有å˜åŒ–ã€?/span>
  2åQ‰æŒ‡é’ˆåÅžå?/span>
  函数的åÅžå‚å¯ä»¥æ˜¯æŒ‡é’ˆåQŒæ¤æ—¶å°†å¤åˆ¶å®žå‚指针åQŒå…¶å®žè¿™¾c»è·Ÿ1åQ‰åŽŸç†ç±»ä¼û|¼Œå‡½æ•°å†…åÆˆæ— æ³•æ”¹å˜å®žå‚的指针倹{€‚åªæ˜¯å‡½æ•°å¯ä»¥é€šè¿‡å¤åˆ¶åˆ°çš„åœ°å€æ”¹å˜å®žå‚指针所指å‘的倹{€?/span>
  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;
  }
  上颽E‹åºä¸å®šä¹‰çš„swapçš„åÅžå‚äØ“æŒ‡é’ˆ¾cÕdž‹åQŒmainä¸è°ƒç”¨swapåQŒå®žé™…上swapòq¶ä¸èƒ½æ”¹å˜p1与p2çš„å€û|¼Œåªæ˜¯æ”¹å˜äº†å®ƒä»¬æ‰€æŒ‡å‘的倹{€?/span>
  3åQ‰const å½¢å‚
  对于普通的éžå¼•用类型用const修饰实际上是没有æ„ä¹‰çš„ï¼Œå› äØ“æœ¬æ¥å‡½æ•°ž®×ƒ¸ä¼šæ”¹å˜å®žå‚的倹{€‚åƒä¸‹é¢çš„定义,实际ä¸ç¼–译器会忽略const的定义,而将其视为intåž‹ã€?/span>
  void fcn(const int i);
  2åQŒå¼•用åÅžå?/span>
  1åQ‰åœ¨ä¸Šé¢çš„程åºä¸æˆ‘们看到åQŒå¦‚果想交æ¢ä¸¤ä¸ªå˜é‡çš„å€û|¼Œé€šè¿‡è°ƒç”¨æ™®é€šçš„éžå¼•用类型åÅžå‚的函数åQŒåƈä¸èƒ½å®žçŽ°ã€‚ç”¨å®ƒä»¬çš„æŒ‡é’ˆå¯ä»¥ï¼ŒåŒæ—¶æˆ‘们也å¯ä»¥ç”¨å¼•用ã€?/span>
  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çš„å¦ä¸€ä¸ªåå—ã€?/span>
  2åQ‰åœ¨æœ‰çš„æ—¶å€™æˆ‘们需è¦å‘å‡½æ•°ä¼ é€’å¤§åž‹å¯¹è±¡ï¼Œéœ€è¦ä‹É用引用åÅžå‚,如果直接使用å¤åˆ¶å®žå‚çš„åÅžå¼å¯ä»¥ï¼Œä½†æ˜¯å®ƒçš„æ•ˆçŽ‡å¤ªä½Žäº†ï¼Œç”šè‡³æœ‰äº›å¯¹è±¡æ˜¯æ— æ³•å¤åˆ¶çš„。但是ä‹É用引用åÅžå‚æ—¶åQŒæˆ‘们ä¸å¸Œæœ›å‡½æ•°æ”¹å˜äº†å®žå‚ä¼ å…¥çš„å€û|¼Œæˆ‘们ž®±å¯ä»¥ä‹É用constæ¥é™å®šåÅžå‚。下é¢ç¨‹åºç”¨æ¥åˆ¤æ–哪个嗽W¦ä¸²æ›´é•¿åQŒæ˜Žæ˜¾æˆ‘们ä¸å¸Œæœ›å‡½æ•°ä¼šæ”¹å˜å—½W¦ä¸²çš„内容,我们ž®±å¯ä»¥ç”¨const引用型的形å‚ã€?/span>
  bool isLonger(const string &s1, const string &s2)
  {
  return s1.size() > s2.size();
  }
  所以,如果使用引用形å‚的惟一的目的是é¿å…å¤åˆ¶å®žå‚æ—Óž¼Œåˆ™åº”ž®†åÅžå‚å®šä¹‰äØ“const引用ã€?/span>
  3åQ‰åœ¨ä½¿ç”¨å¼•用形å‚函数æ—Óž¼Œæœ‰ä¸¤ç‚¹å€¼å¾—注æ„åQ?/span>
  ä¸è¦ç”¨consté™å®šçš„å®žå‚æˆ–å—é¢å€¼æ¥è°ƒç”¨éžconst引用形å‚å‡½æ•°ã€‚å› ä¸ø™¿™æ ·å‡½æ•°å†…åQŒå¯ä»¥æ”¹å˜å®žå‚çš„å€û|¼Œ˜q™ä¸åˆæ³•ã€?/span>
  éžconst引用形å‚åªèƒ½ä¸Žå®Œå…¨åŒ¾cÕdž‹çš„éžconst对象兌™”ã€?/span>
  4åQ‰ä¼ é€’æŒ‡å‘æŒ‡é’ˆçš„引用
  如下有下é¢çš„½E‹åºåQ?/span>
  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åQŒè€Œp2指å‘了aã€?/span>
  3åQŒå…¶ä»–类型的形å‚
  1åQ‰vector和其他类型的形å‚åQšä¸€èˆ¬åœ¨˜q™ç§¾cÕdž‹ä½œäØ“å½¢å‚æ—Óž¼Œä¸ÞZº†é¿å…å¤åˆ¶åº”该考虑形å‚声明为引用类型。C++½E‹åºå‘˜å€‘Ö‘äºŽä¼ é€’å®¹å™¨ä¸éœ€è¦å¤„ç†çš„å…ƒç´ çš„è„P代器æ¥ä¼ 递容器ã€?/span>
  2åQ‰æ•°¾l„åÅžå‚:ç”׃ºŽæ•°ç»„ä¸èƒ½å¤åˆ¶åQŒæ‰€ä»¥ä¸èƒ½ç›´æŽ¥ç¼–写数¾l„类型的形å‚函数åQŒä¸€èˆ¬é€šè¿‡ä¼ é€’æŒ‡å‘æ•°¾l„çš„å…ƒç´ çš„æŒ‡é’ˆæ¥å¤„ç†æ•°ç»„。值得注æ„çš„æ˜¯åœ¨é€šè¿‡å¼•ç”¨ä¼ é€’æ•°¾l„æ—¶åQŒåœ¨è°ƒç”¨å‡½æ•°æ—¶åÅžå‚与实å‚的类型è¦åŒšw…ã€?/span>
  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;
  }
  二ã€å‡½æ•°çš„˜q”回å€?/span>
  1åQ‰æ²¡æœ‰è¿”回å€?/span>
  很多函数òq¶æ²¡æœ‰è¿”回å€û|¼Œž®¤å…¶æ˜¯çŽ°åœ¨C++é£Žæ ¼åQŒä¹ 惯于把需è¦çš„¾l“æžœä½œäØ“å¼•ç”¨å½¢å‚。这¾cÕdž‹å‡½æ•°ä¸€èˆ¬æ²¡æœ‰returnè¯å¥åQŒæœ‰æ—¶å€™æœ‰return是ä‹É函数ä¸é€”䏿–执行ã€?/span>
  2åQ‰è¿”回éžå¼•用¾cÕdž‹
  ˜q™ç§æƒ…况在函数调用处åQŒç¨‹åºä¼šç”¨ä¸€ä¸ªäÍæ—¶å˜é‡å¤åˆ¶å‡½æ•°çš„˜q”回倹{€?/span>
  3åQ‰è¿”回引ç”?/span>
  当函数返回引用类型时åQŒåƈ没有å¤åˆ¶˜q”回倹{€‚相å,˜q”回的是对象本èínã€?/span>
  在返回引用这¿U情况下åQŒæ³¨æ„ä¸è¦è¿”回局部å˜é‡çš„引用åQŒå› 为局部å˜é‡åœ¨å‡½æ•°ä½“内定义åQŒå½“函数执行完厞®±é”€æ¯äº†åQŒæ‰€è°“的引用也就没有æ„义了。åŒç†ï¼Œä¸è¦˜q”回指å‘局部å˜é‡çš„æŒ‡é’ˆã€?/span>
  三ã€é‡è½½å‡½æ•?/span>
  出现在相åŒä½œç”¨åŸŸä¸çš„两个函数åQŒå¦‚果具有相åŒçš„åå—而åÅžå‚ä¸åŒï¼Œåˆ™ç§°ä¸ºé‡è½½å‡½æ•°ã€?/span>
  1åQ‰æ³¨æ„区分函数é‡è½½ä¸Žé‡å¤å£°æ˜Ž
  有些看è“væ¥ä¸åŒçš„å½¢å‚åQŒæœ¬è´¨æ˜¯ç›¸åŒçš„。下é¢ä»£ç ä¸çš„都是é‡å¤å£°æ˜Žçš„例å
  typedef double newDouble;
  int func(double i);
  int func(newDouble i); // 没有新类�/span>
  int func1(int, int = 1); //åªæ˜¯æä¾›é»˜è®¤å‚æ•°
  int func1(int ,int);
  int func2(int);
  int func2(const int); //对于普通éžå¼•用形å‚用cosnt修饰是没有æ„义的
  2åQ‰é‡è½½ä¸Žä½œç”¨åŸ?/span>
  局部声明的函数åQŒå°†å±è”½æ‰€æœ‰å…¨å±€ä½œç”¨çš„åŒå函数。下é¢ä¾‹å显½Cºï¼Œå³ä‹Éå…¨å±€ä½œç”¨çš„å‡½æ•°æ›´åŠ åŒ¹é…调用的实傾cÕdž‹åQŒä½†æ˜¯ä»ç„¶è°ƒç”¨çš„æ˜¯å±€éƒ¨çš„函数ã€?/span>
  void print(int);
  int main()
  {
  void print(double);
  print(42);
  return 0;
  }
  上颽E‹åºä¸ï¼Œž®†è°ƒç”¨void print(double)函数åQŒè™½ç„?2是intåž‹ã€?/span>
  3åQ‰é‡è½½ç¡®å®šçš„三个æ¥éª¤
  如果定义了众多的函数é‡è²åQŒå°†å˜åœ¨å‡½æ•°è°ƒç”¨åˆ°åº•与哪个é‡è½½å‡½æ•°ç›¸åŒšw…的问题。我们通过下é¢çš„ç¤ºä¾‹ä»£ç æ¥è¯´æ˜Žé—®é¢˜åQ?/span>
  void f(); // 1
  void f(int);// 2
  void f(double);// 3
  void f(int, int);// 4
  void f(double, double);// 5
  ½W¬ä¸€æ¥ï¼š¼‹®å®šå€™é€‰å‡½æ•?/span>
  å‡å¦‚我们调用f(4.2)åQŒé‚£ä¹ˆå…ˆæ‰‘Öˆ°åŒå函数åQŒåƈ且在作用域内å¯è§åQŒä¸Šé¢ä¾‹åä¸5个函数都满èƒöã€?/span>
  ½W¬äºŒæ¥ï¼šé€‰æ‹©å¯è¡Œçš„函æ•?/span>
  必须满èƒö2个æ¡ä»Óž¼šä¸€æ˜¯å‡½æ•°åÅžå‚与该调用实å‚个数相åŒï¼›½W¬äºŒåQŒæ¯ä¸ªå®žå‚çš„¾cÕdž‹å¿…须与对应的¾cÕdž‹åŒšw…åQŒæˆ–者å¯ä»¥è¢«éšå¼è½¬æ¢ä¸ºå¯¹åº”的形傾cÕdž‹ã€‚这里我们å†è°ƒç”¨f(4.2)æ—Óž¼ŒæŽ’除äº?ã€?ã€?å·å‡½æ•ŽÍ¼Œåªå‰©ä¸?ä¸?。其ä¸?å·å‡½æ•°å¯ä»¥é€šè¿‡¾cÕdž‹è½¬æ¢æ¥æ»¡‘Ÿë€?/span>
  ½W¬ä¸‰æ¥ï¼šå¯ÀL‰¾æœ€ä½›_Œ¹é…?/span>
  在绘q‡ç¬¬äºŒæ¥¼‹®å®šåŽï¼Œå‰©ä¸‹2ä¸?函数åQŒé‚£ä¹?需è¦è¿›è¡Œç±»åž‹è{æ¢ï¼Œæ˜„¡„¶3是最佛_Œ¹é…了ã€?/span>
  但是如果˜q™æ ·è°ƒç”¨f(42,4.2)。这时候就会出çŽîCºŒä¹‰æ€§ï¼Œ¾~–译器将æç¤ºã€?/span>
  ˜q˜æœ‰ä¸€¿Uè¦æ³¨æ„çš„å°±æ˜¯æœ‰é»˜è®¤å‚æ•°çš„函敎ͼŒæ¯”如我们定义6å·å‡½æ•îCØ“void f(double,int =1);那么在调用f(4.2)时就会有二义性ã€?/span>
  å¯åŸºäºŽå‡½æ•°çš„å¼•ç”¨å½¢å‚æ˜¯æŒ‡å‘const对象˜q˜æ˜¯æŒ‡å‘éžconst对象实现函数é‡è²ã€?/span>