題解:ybt1207:求最大公約數問題
1207:求最大公約數問題
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
給定兩個正整數,求它們的最大公約數。
【輸入】
輸入一行,包含兩個正整數(<1,000,000,000)。
【輸出】
輸出一個正整數,即這兩個正整數的最大公約數。
【輸入樣例】
6 9
【輸出樣例】
3
【來源】
ybt1207
這道題的一般解法是在main()函式裡面用while迴圈來解決,程式碼一般是這樣的:
#include <iostream> using namespacestd; int main() { int m,n,c,r; cin>>m>>n; r=m%n; while(r!=0) { m=n; n=r; r=m%n; } cout<<n; return 0; }
但這種方法,唯一的缺點是:不能重複使用。如果在好幾處地方都要用到最大公約數,我們要在每一處都複製貼上嗎?那未免也太麻煩了,
十分降低程式的效率,所以我們要用一種全新的方式來編寫,那就是"函式"。
函式這種功能,我們先來介紹一下:
main就是一個函式,它是C++程式的主函式。一個C++程式可以由一個主函式和若干子函式組成。主函式是程式執行的開始點。由主函式呼叫子函式,子函式還可以再呼叫其它子函式。
呼叫其它函式的函式稱為主調函式。被其他函式呼叫的函式稱為被調函式。一個函式很可能既呼叫別的函式又被其它函式呼叫。
1.函式的定義
1.1函式定義的語法形式
型別說明符 函式名(含型別說明的形式引數表)
{
語句序列
}
1.2形式引數
型別識別符號1 形參名1,型別識別符號2 形參名2,···,型別識別符號n 形參名n
形參的作用是實現主調函式與被調函式之間的聯絡。通常將函式所處理的資料、影響函式功能的因素或者函式的處理結果作為形參。
如果一個函式的形參表為空,則表示它沒有任何形參。main函式可以沒有形參,也可以有形參,其形參也稱命令列引數,由作業系統在啟動程式時初始化。
函式在沒有被呼叫時是靜止的,此時的形參只是一個符號,它標誌著在形參出現的位置應該有一個什麼型別的資料。
函式在被呼叫時才執行,也就是在被呼叫時才由主調函式將實際引數賦予形參。
1.3函式的返回值和返回值型別
函式可以有一個返回值,函式的返回值是需要返回給主調函式的處理結果。型別說明符規定了函式返回值的型別,函式的返回值由return語句給出,格式如下:
return 表示式;
除了指定函式的返回值外,return語句還有一個作用,就是結束當前函式的執行。
一個函式也可以不講任何值返回給主調函式,這時它的型別識別符號為void,可以不寫return語句,但也可以寫一個不帶表示式的return語句,用於結束當前函式的呼叫,格式如下:
return;
2.1函式的呼叫形式
變數在使用之前需要首先宣告,類似的,函式在呼叫之前也需要宣告。函式的定義就屬於函式的宣告,因此,在定義了一個函式之後,可以直接呼叫這個函式。但如果希望在定義一個函式之前呼叫它,則需要在呼叫函式之前新增該函式的函式原型宣告。函式原型宣告的形式如下:
型別說明符 函式名(含型別說明的形參表);
與變數的宣告和定義類似,宣告一個函式只是將函式的有關資訊告訴編譯器,此時並不產生任何程式碼;定義一個函式是除了同樣要給出函式的有關資訊外,主要是要寫出函式的程式碼。
聲明瞭函式原型之後,便可以按如下形式呼叫子函式:
函式名(實參列表);
實參列表應該給出與函式原型形參個數相同、型別相符的實參,每個實參都是一個表示式。函式呼叫可以作為一條語句,這時函式可以沒有返回值。函式呼叫也可以出現在表示式中,這時就必須有一個明確的返回值。
2.2巢狀呼叫
函式允許巢狀呼叫。如果函式1呼叫了函式2,函式2再呼叫函式3,便形成了函式的巢狀呼叫
2.3遞迴呼叫
函式可以直接或間接地呼叫自身,稱為遞迴呼叫。
所謂直接呼叫自身,就是指在一個函式的函式體中出現了對自身的呼叫表示式。
遞迴演算法的實質是將原有的問題分解成新的問題,而解決新問題時又用到了原有問題的解法。按照這一原則分解下去,每次出現的新問題都是原有問題的簡化的子集,而最終分解出來的問題,是一個已知解的問題。這便是有限的遞迴呼叫。只有有限的遞迴呼叫才是有意義的,無限的遞迴呼叫永遠得不到解,沒有實際意義。
遞迴的過程有如下兩個階段。
第一階段:遞推。將原問題不斷分解為新的子問題,逐漸從未知向已知推進,最終達到已知的條件,即遞迴結束的條件,這時遞推階段結束。
第二階段:迴歸。從已知的條件出發,按照遞推的逆過程,逐一求值迴歸,最後達到遞推的開始處,結束迴歸階段,完成遞迴呼叫。
3.函式的引數傳遞
在函式未被呼叫時,函式的形參並不佔有實際的記憶體空間,也沒有實際的值。只有在函式被呼叫時才為形參分配儲存單元,並將實參與形參結合。每個實參都是一個表示式,其型別必須與形參相符。函式的引數傳遞指的就是形參與實參結合(簡稱形實結合)的過程,形實結合的方式有值傳遞和引用傳遞。
3.1值傳遞
值傳遞是指當發生函式呼叫時,給形參分配記憶體空間,並用實參來初始化形參(直接將實參的值傳遞給形參)。這一過程是引數值的單項傳遞過程,一旦形參獲得了值便與實參脫離關係,此後無論形參發生了怎樣的改變,都不會影響到實參。
2.引用傳遞
值傳遞時引數是單向傳遞。
引用是一種特殊型別的變數,可以被認為是另一個變數的別名,通過引用名與通過被引用的變數名訪問變數的效果是一樣的。
使用引用時必須注意以下問題:
·宣告一個引用時,必須同時對它進行初始化,使它指向一個已存在的物件。44
·一旦一個引用被初始化後,就不能改為指向其它物件。
也就是說,一個引用,從它誕生時,就必須確定是哪個變數的別名,而且始終只能作為作為這一個變數的別名,不能另作他用。
引用也可以作為形參,如果將引用作為形參,情況便稍有不同。這是因為,形參的初始化不在型別說明時進行,而是在執行主調函式中的呼叫表示式時,才為形參分配記憶體空間,同時用實參初始化形參。這樣引用型別的形參就通過形實結合,成為了實參的一個別名,對形參的任何操作也就會直接作用於實參。
用引用作為形參,在函式呼叫時發生的引數傳遞,稱為引用傳遞。
回到題目,使用函式和不使用函式的求最大公約數的方法是一樣的,只不過添加了實參和形參
#include <iostream> using namespace std; int gcd(int x,int y); int main() { int m,n; cin>>m>>n; cout<<gcd(m,n); return 0; } int gcd(int x,int y) { int r; r=x%y; while(r!=0) { x=y; y=r; r=x%y; } return y; }
再次提醒:如果把函式定義在main()函式後面,前面需要先定義函式,如果不定義,會編譯錯誤!!!!
。