函數(二) 函數的重載 函數的變數 參照與函數 2012.12 綠園
函數(二) 函數的重載 函數的變數 參照與函數
函數的重載 C++辨別某一函數是否與另一函數相同,是藉由比對函數的特徵資料,包括函數的名稱和其所用的引數列。底下為三個不同的函數: // (1) 找出兩整數的最大值 int max(int a, int b); // (2) 找出兩浮點數的最大值 float max(float a, float b); // (3) 找出三整數的最大值 int max(int a, int b, int c);
函數(二) 函數的重載 函數的變數 參照與函數
函數變數的種類 依變數宣告的位置所在可分為 依變數在記憶體中的儲存方式來分 區域變數(Local) 外部變數(Exernal) 動態(auto)—利用堆疊來存放 靜態(static)—有一固定之存放位置 暫存器(register)—存放在cpu中的暫存器,速度快。
區域變數(Local) 又稱「自動變數」(auto),只在變數所在之函數中可使用。 auto int i; char ch; static:配置有固定的記憶體空間來存放,資料不會因函數執行完而消失。此方式所建立之變數稱為「定義」。 static int i; static char ch;
區域變數 執行結果: #include <iostream> #include <cstdlib> using namespace std; void func(void); int main(void) { int a=100; cout <<"before the func, a= " <<a <<endl; func(); cout <<"after the func, a=" <<a <<endl; system("PAUSE"); return 0; } void func(void) { int a=300; cout <<"in the func, a=" <<a <<endl; return; 區域變數 執行結果: before the func, a=100 in the func, a=300 after the func, a=100
靜態區域變數 執行結果: #include <iostream> #include <cstdlib> using namespace std; void func(void); int main(void) { func(); func(); system("PAUSE"); return 0; } void func(void) { static int a=10; cout <<"in the func, a=" <<a <<endl; a+=20; return; 執行結果: in the func, a=10 in the func, a=30 in the func, a=50
外部變數(External、Global) 可作為函數與函數之間傳遞或共同使用的通道,使用範圍由變數的定義處開始向下到程式結束。 extern:外部變數 可作為函數與函數之間傳遞或共同使用的通道 可跨檔案使用 管理若不當,容易產生混亂 static extern:靜態外部變數 只可在一檔案中使用 一般會定義在程式一開始的地方,讓所有函數皆可用
外部變數的宣告(extern) int main (void) { extern int i; //經由宣告後才可使用外部變數i … … star(); } func() //無法使用外部變數i { … … } int i; //定義外部變數i star() //外部變數i的活動範圍 { i++;
靜態外部變數的宣告(static) int main (void) { star(); … … } static int i; //定義靜態外部變數i func() //以下為外部變數i的活動範圍 { … … } star() { i++;
外部變數 執行結果: #include <iostream> #include <cstdlib> using namespace std; void func(void); int main(void) { extern int a; cout <<"before the func, a=" <<a <<endl; func(); cout <<"after the func, a=" <<a <<endl; system("PAUSE"); return 0; } int a=100; void func(void) { a=300; cout <<"in the func, a=" <<a <<endl; return; 外部變數 執行結果: before the func, a=100 in the func, a=300 after the func, a=300
引數傳遞 執行結果: #include <iostream> #include <cstdlib> using namespace std; void add10(int, int); int main(void) { int a=3, b=5; cout << "before the add10:\n"; cout <<" a=" <<a <<" b=" <<b <<endl; add10(a,b); cout << "after the add10:\n"; system("PAUSE"); return 0; } void add10(int a, int b) { a=a+10; b=b+10; return; 執行結果: before the add10: a=3 b=5 after the add10:
暫存器變數(register) 利用CPU的暫存器來存放資料,處理速度比較快。 暫存器變數的活動範圍只有在所屬的左、右大括號中所包圍起來的區段。 int main(void) { register int i; … … star(); } star() main()函數中i的活動範圍 star()函數中i的活動範圍
函數(二) 函數的重載 函數的變數 參照與函數
參照與函數(一) 在函數間傳遞的引數,一般都是以「傳值呼叫」的方式,編譯器會將欲傳入函數的引數值另行複製一份,供呼叫的函數使用,因此不管如何改變這個傳進函數中的引數值,都不會更動到原先變數的值。
引數傳遞 執行結果: #include <iostream> #include <cstdlib> using namespace std; void add10(int, int); int main(void) { int a=3, b=5; cout << “before the add10:\n”; cout <<“ a=” <<a <<“ b=” <<b <<endl; add10(a,b); cout << “after the add10:\n”; system(“PAUSE”); return 0; } void add10(int a, int b) a=a+10; b=b+10; return; 執行結果: before the add10: a=3 b=5 after the add10:
參照與函數(二) 「參照」(reference)就像是變數的暱稱或別名,可以代替某個變數。在程式中可使用變數的參照名稱來直接存取變數。 參照的宣告方式如下: int a; int &ref = a; 或 int& ref = a;
參照使用 執行結果: #include <iostream> #include <cstdlib> using namespace std; int main() { int num=5; int &ref=num; cout << "Before process ..." << endl; cout << " num = " << num << endl; cout << " ref = " << ref << endl; ref=ref+10; cout << "After process ..." << endl; system("pause"); return 0; } 執行結果: Before process… num = 5 ref = 5 After process… num = 15 ref = 15
參照傳遞 執行結果: #include <iostream> #include <cstdlib> using namespace std; void add10(int &, int &); int main(void) { int a=20, b=50; cout << " before the add10:\n"; cout << " a=" <<a <<" b=" <<b <<endl; add10(a,b); cout << "after the add10:\n"; cout <<" a=" <<a <<" b=" <<b <<endl; system("PAUSE"); return 0; } void add10(int &i, int &j) i=i+10; j=j+10; return; 執行結果: before the add10: a=20 b=50 after the add10: a=30 b=60
傳回參照 執行結果: #include <iostream> #include <cstdlib> using namespace std; int& max(int&, int&); int main(void) { int a=3, b=5; cout << " max = " << max(a,b) <<endl; max(a,b) = 100; cout << "a = " << a << endl; cout << "b = " << b << endl; system("PAUSE"); return 0; } int& max(int& i, int& j) if(i>j) return i; else return j; 執行結果: max = 5 a = 3 b = 100
兩數交換 執行結果: #include <iostream> #include <cstdlib> using namespace std; ____ swap(_______________); int main(void) { int a=3, b=5; cout << "before swap ... \n"; cout << " a=" <<a <<" b=" <<b <<endl; swap(a,b); cout << "after swap ... \n"; cout <<" a=" <<a <<" b=" <<b <<endl; system(“PAUSE”); return 0; } ____ swap(_______________) ....... 執行結果: before swap ... a=3 b=5 after swap ... a=5 b=3
隨堂練習(一) – 還是質數 設計一程式,包含一個副程式,能判斷傳入的整數是否為質數,而主程式能 (1) 找出 1~1000 中的質數,每十個列一排。 (2) 如果質數滿足 2p-1 時,稱為梅森尼質數 (Mersenne Prime)。 找出前八個梅森尼質數。
遞迴函數 -- 河內塔(一) 河內塔是根據一個傳說形成的一個問題:有三根桿子A,B,C。A桿上有N個(N>1)穿孔圓盤,盤子的尺寸由下到上依次變小,如下圖。 現在,想要把桿子 'A' 上的盤子移動到桿子 'C',而且盤子的移動規則是:每次只能移動一個圓盤; 大盤子不能疊在小盤子上面。 當然,任何盤子皆可以臨時置於B桿,也可將從A桿移出的圓盤重新移回A桿,但都必須遵循上述兩條規則。 現在,請你寫一個能夠描述盤子搬動過程的程式。
遞迴函數 -- 河內塔(二) 事實上,若有n個盤子,則移動完畢所需之次數為2^n - 1,所以當盤數為64時,則所需次數為:264 – 1 次。 演算法如下:(n個盤子,由A搬到C,可暫放B。) Hanoi(n, A, C, B) { if (n == 0) then return; else { Hanoi(n-1, A, B, C); Move disk n form A to C; Hanoi(n-1, B, C, A); } }