C++函數及其應用


C++函數及其應用

一.為什么要用函數

  函數是編程很重要的一部分,他能給程序帶來很多益處,也方便我們程序員編寫代碼。

  1. 我們知道,c和c++中使用函數,能簡化代碼量,對各個部分進行封裝,使得問題變得簡單和直觀,提高了程序的易讀性。

  2. 還可以提升可維護性,把一些計算或操作編成通用的函數,以供隨時調用,從而避免了代碼的重復冗長。

  3. 但是運用函數,就需要傳遞參數,開辟緩存、堆棧等,相比較而言,會耗一些多余的效率。

例:比較三個數的大小

#include <iostream> 
using namespace std;  
void func(int a,int b,int c)
{  
int middle,max,small;
if(a>b){
	max=a;
	middle =b;
       }
else{
	max=b;
	middle =a;
    }

if(c>max){
	cout << c << " " << max << " "<< middle;
    }
else if(c<middle){
cout << max << " " << middle << " " <<c;
    }
else{
cout << max << " " << c << " " <<middle;
    }
}

int main(){
int a,b,c;
cout << "請輸入a,b,c的大小\n";
cin >> a >> b >> c;

func(a,b,c);//進行排序 

return 0;
}

  我們可以看出用一個func函數對三個數進行比較大小后,主函數就變得簡單清晰,程序可讀性變強。

二.函數重載

  在C++中,如果需要定義幾個功能相似,而參數類型不同的函數,那么這樣的幾個函數可以使用相同的函數名,這就是“函數重載”。
兩個重載函數必須在下列一個或兩個方面有所區別,僅僅返回值類型不同是不行的。
1、函數的參數個數不同;

2、函數的參數類型不同或者參數類型順序不同。

例如,求和函數,對應不同的參數類型,可以定義如下幾個重載函數:

#include<iostream>
using namespace std;

int sum(int a=0,int b=0){
return a+b;
}
double sum(double a=0,double b=0){
return a+b;
}
float sum(float a=0,float b=0,float c=0){
return a+b+c;
}

int main(){

int x=sum(5,9);
float y=sum(2.7,5.87);
float z=sum(float(x),y,5);

cout << x << " " << y << " " << z; 
return 0; 
}  

三.什么是值傳遞

  調用時,將實參的值傳遞對應的形參,即為值傳遞。函數中對任何形參值得修改都不會改變實參變量的值。
例如經典的交換x,y的值:

#include<iostream>
using namespace std;

void swap(int x,int y){

int temp;

temp=x;
x=y;
y=temp;

cout << "swap中a和b " << x << " " << y << endl; 

}

int main(){

int a,b;

cin >> a >> b;

swap(a,b);

cout << "main中a和b " << a << " " << b << endl; 

return 0;
}

  我們分析一下整個程序:在主函數中,實參a和b有自己的存儲空間,並且有自己的初始值。當調用函數Swap時,內存給函數的參數x和y分配存儲空間,並將a和b的值復制過來,函數執行過程中,將x和y的值進行交換,當函數執行結束之后,x和y所占用的存儲空間將被釋放,這種傳遞的方式,並不會對實參a和b的值產生影響,所以看到的a和b的值沒喲改變。

四.什么是傳引用

  引用變量是變量的另一個別名,它沒有自己的存儲數據的內存位置,它訪問的是另一個變量的內存位置。對引用變量作出的任何更改,實際上都是對它所引用的變量內存位置中存儲數據的更改。
我們用傳值的程序,把void swap(int a,int b){...}改為void swap(int &a,int &b){...}。可以看出,在main函數中,ab的值發生了改變。

#include<iostream>
using namespace std;

void swap(int &x,int &y){

int temp;

temp=x;
x=y;
y=temp;

cout << "swap中a和b " << x << " " << y << endl; 

}

int main(){

int a,b;

cin >> a >> b;

swap(a,b);

cout << "main中a和b " << a << " " << b << endl; 

return 0;
}

五.如何編寫遞歸函數

  說起遞歸,不得不說他很想小時候聽過的故事:從前有座山,山里有座廟,廟里有個和尚,和尚在講故事,從前有座山,山里有座廟,廟里有個和尚,和尚在講故事,從前有座山...
網上流傳的這個表情包,他也很好的詮釋了什么叫遞歸。遞歸的原理就是通過棧機制來把遞歸過程中的函數,以及它的符號入棧和出棧,並在出棧過程中對這些符號和函數返回值等進行運算。

  我們再來看看不好理解的漢羅塔問題:該問題是在一塊銅板裝置上,有三根桿(編號A、B、C),在A桿自下而上、由大到小按順序放置n個金盤。游戲的目標:把A桿上的金盤全部移到C桿上,並仍保持原有順序疊好。

  研究這個問題我們就要利用遞歸思想,要把n個盤子從A->C,我們就要先把n-1個盤子從A->C->B,再把A最后一個盤子從A->C,緊接着再把n-1個盤子從B->A->C上。
再具體一點,就是我們要把前n-2個盤子移動到B上,n-3個盤子移動到C上,以此類推,最終推出第一個盤子應該放在B或者C上。由於遞歸是倒序輸出,我們在前面已經記錄過倒數第二個盤子應放在哪里,再把前兩個盤子疊加在一起,在記錄中找出倒數第三個盤子放在哪里,以此類推,一直到n-1個盤子把他們疊在一起就完成了第一步(我們就要先把n-1個盤子從A->C->B),第一部move(n-1,x,z,y)遞歸函數調用徹底結束。
這時中間語句直接輸出第n個盤子從A->C,完成第二部。
完成后到達第三個move函數, move(n-1,y,x,z),這個函數的作用和第一個函數的作用相似,只是改變了起始針,中間針和目的針。原理和第一個遞歸函數相同。由於我們知道第一個遞歸函數和第二個遞歸函數是相似的,步驟也是相同的,可以得出漢諾塔的步數一定是個奇數(加上中間直接移動最后一個盤子的一步)。
具體代碼:

//棧之遞歸漢諾塔問題
#include<iostream>

using namespace std; 

void move(int n,char x,char y,char z){

if(n==1)
cout << x <<"->" << z << endl;  //把x放到z上

else{
	
	move(n-1,x,z,y);
	cout << x <<"->" << z << endl;  
	move(n-1,y,x,z);
	
 } 	
}

int main(){

move(3,'x','y','z');

return 0;

}  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM