1. 程式人生 > 其它 >二、面向過程的程式設計風格

二、面向過程的程式設計風格

技術標籤:Essential C++學習總結c++

  • 將函式獨立出來的好處有:

1)以一連串函式呼叫操作取代重複編寫相同的程式程式碼,使程式易讀
2)可以在不同的程式中使用這些函式;
3)可以更容易地把工作分配給協作開發團隊。

  • 每個函式必須定義返回型別函式名引數列表函式體四個部分。
  • 函式必須先被宣告才能被呼叫(使用)。
  • 函式的宣告讓編譯器得以檢查後續出現的使用方式是否正確(引數是否足夠、引數型別是否正確等)
  • 函式宣告不必提供函式體,但必須指明返回型別、函式名和引數列表,即所謂的函式原型(function prototype)。
  • 函式的定義包括函式原型函式體
  • 成對的/**/是多行註釋。
  • 當用戶輸入一個不合理的值時,可以終止整個程式(稍顯極端)或丟擲異常(見第七章)。
  • 標準庫的exit()函式用來終止程式。必須傳一個值作為程式結束時的狀態值。
#include <cstdlib>
//...
//以狀態-1結束程式
if(pos <= 0)
	exit(-1);
  • 函式只能返回一個值。題目“fibon_elem()是否計算出指定元素”關係到其返回值為truefalse,而返回該元素的實際值可通過加入第二個引數完成,如:
//修正函式原型
bool fibon_elem(int pos, int &elem);
  • 每個值型別都只能表示其值域(domain)中的最小至最大值間的某個值,超出即發生溢位(overflow)。

想知道某個型別的最小/最大值,可查詢標準庫中的numeric_limits class

#include <limits>
int max_int = numeric_limits<int>::max();
double min_dbl = numeric_limits<double>::min(); 
  • 函式的宣告可以不寫出引數的名稱,引數名稱只有在函式內使用引數時才是必要的。
  • 如果函式的返回型別不為void,必須在每個可能的退出點上將值返回。如果函式的最後一條語句不是return,那麼最後一條語句之後便是該函式的隱式退出點,隱式退出點不返回任何數值則編譯出錯。
  • return;語句不返回任何數值,只在返回值為void時才被使用,可以提前結束函式的執行。
  • 兩種引數傳遞方式:傳址(by reference)和傳值(by value)。
  • 當我們呼叫一個函式時,會在記憶體中建立起一塊特殊區域,稱為程式堆疊(program stack),提供了每個函式引數的儲存空間,也提供了函式所定義的每個物件的記憶體空間(這些物件也叫區域性物件local object)。一旦函式完成,這塊記憶體就會被釋放,也就是從程式堆疊中被pop出來。
  • 將物件傳入函式,預設情形下它的值會被複制一份,成為引數的區域性定義。這種方式稱為傳值
  • 讓引數和傳入的實際物件產生關聯,即傳址,最簡單的方法便是將引數宣告為一個引用(reference):
void swap(int &val1, int & val2)
{
	int temp = val1;
	val1 = val2;
	val2 = temp;
}
  • reference扮演著外界與物件之間一個間接手柄的角色。只要在型別名稱和reference名稱之間插入&符號,便是聲明瞭一個reference。
int ival = 1024; //物件,型別為int
int *pi = &ival; //指標pointer,指向一個int物件
int &rval = ival; //引用reference,代表一個int物件
  • int jval = 4096; rval = jval;是將jval賦值給rval所代表的物件ival。我們不能令rval轉而代表jval,因為C++不允許改變reference所代表的物件。
  • pi = &rval;是將ival(即rval所代表的物件)的地址賦值給pi,並未令pi指向rval
  • 面對reference的所有操作都和面對reference所代表的物件所進行的操作一模一樣。
  • 使用傳址方式將物件作為函式引數傳入時,物件本身並不會複製出另一份——複製的是物件的地址。對該物件的任何操作都相當於對傳入的物件進行間接操作。
  • 將引數宣告為reference的理由有:
  • 可以直接對傳入的物件進行修改;
  • 降低複製大量物件的額外負擔(直接傳入vector的地址比複製其中的所有元素更快)。
  • 如下程式碼所示,我們聲明瞭一個reference to const vector,因為函式之中並不會更改vector的內容。加上const可以讓閱讀程式的人瞭解,我們以傳址的方式傳遞vector是為了避免複製操作,而不是為了要在函式中對它進行修改
void display( const vector<int> &vec )
{
	for( int ix = 0; ix < vec.size(); ++ix)
		cout << vec[ix] << ' ';
	cout << endl;
}
  • 也可以用pointer傳遞vector,與reference相同,都是傳遞物件的地址而不是整個物件的副本,唯一差別在於用法不同:
void display( const vector<int> *vec )
{
	if( !vec )
	{
		cout << "display():the vector pointer is 0\n";
		return;
	}
	for( int ix = 0; ix < vec->size(); ++ix) //vec->size()
		cout << (*vec)[ix] << ' '; //(*vec)[ix]
	cout << endl;
}
  • pointer可能(也可能不)指向某個實際物件,當我們提領pointer時,一定要先確定其值並非0;而reference必定會代表某個物件,所以不需做此檢查。
  • 傳址機制主要用於傳遞class物件,除非需要在函式內改變引數值,否則傳遞內建型別時一般不使用傳址方式。