1. 程式人生 > 其它 >題解:ybt1207:求最大公約數問題

題解:ybt1207:求最大公約數問題

ybt1207:求最大公約數問題

  1207:求最大公約數問題

  時間限制: 1000 ms         記憶體限制: 65536 KB

  【題目描述】

  給定兩個正整數,求它們的最大公約數。

  【輸入】

  輸入一行,包含兩個正整數(<1,000,000,000)。

  【輸出】

  輸出一個正整數,即這兩個正整數的最大公約數。

  【輸入樣例】

  6 9

  【輸出樣例】

  3

  【來源】

    ybt1207

這道題的一般解法是在main()函式裡面用while迴圈來解決,程式碼一般是這樣的:

#include <iostream>
using namespace
std; 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()函式後面,前面需要先定義函式,如果不定義,會編譯錯誤!!!!