3 1 c 的程式設計模組函式

2021-10-04 01:56:35 字數 3983 閱讀 8800

c++的函式要完成如下工作:提供函式定義;提供函式原型;呼叫函式。

函式原型描述函式到編譯器的介面,即原型將返回值引數型別,引數型別以及數量告訴編譯器,效率高,無需在函式檔案中查詢。函式原型不要求提供變數名,當不指定引數列表時,使用省略號,它能控制引數的型別轉換。c++對返回值型別有一定的限制,不能是陣列,可以是其他任何型別。

double cube(double x);   // 函式原型

int main()

double cube(double x) // 函式頭及函式體

按值傳遞意味著將數值引數傳遞給函式,函式將其賦給乙個新的變數。如上述**,cube()使用的是side的副本,而不是原來的資料。用於接受傳遞值的變數被稱為形參(argument),傳遞給函式的值被稱為實參(parameter)。

處理陣列的c++函式,需要傳遞陣列中的資料種類,陣列的起始位置和陣列元素的個數。arr實際上並不是乙個陣列,而是乙個指標,編寫函式時,可以將arr看作陣列,所以1)處的函式頭也是正確的,當且僅當用於函式頭和函式原型中,二者的含義才是相同的。當陣列作為引數時,函式將使用原來的陣列,這並不違背按值傳遞的方法,只不過傳遞的是乙個位址而已——arr(第乙個元素的位址)。將陣列位址作為引數,可以節省複製整個陣列所需的時間和記憶體,但使用原始資料增加了破壞資料的風險,用const限定符解決,如2)處

int arr_sum(int arr, int n)

int arr_sum(int * arr, int n) // 1)處

int arr_sum(const int * arr, int n) // 2)處 無法修改arr陣列

int arr_sum(const int *begin, const int *end) // 3)處

int sum = arr_sum(num, num+arsize); // 4)處,arsize為num陣列的大小

注意:必須顯示傳遞陣列的長度,不要妄想在arr_sum函式中使用sizeof arr來得到陣列的長度。關於陣列、動態陣列和指標算術的知識可參照  

處理陣列的c++函式還有一種情況,指定元素區間,通過傳遞兩個指標來完成,乙個指標標識陣列的開頭,另乙個指標標識元素的尾部,如3)處函式頭。4)處為函式呼叫,num+arsize指向最後乙個元素後面的乙個位置。

有兩種不同的方式用於指標,第一種方法是讓指標指向乙個常量物件,這樣可以防止使用該指標來修改所指向的值,如1)處。pt指向乙個const int,不能用pt來修改20。pt的宣告並不意味著它指向的值實際上是乙個常量,只是對pt而言,這個值是個常量,所以可以用age變數修改20。1)處**是將常規變數的位址賦給指向const的指標,還有將const變數的位址賦值給指向const指標,如2)處;const變數的位址賦給常規指標,如3)處,但這種不可行,c++禁止這樣做。當然,非const指標賦給const指標也是可以的,如4)處。總之不能將const的東西賦給非const的東西,如5)處。另外,const只涉及一級間接關係,不用於二級間接關係。

第一種方法的好處:避免無意間膝蓋資料而導致程式設計錯誤,使用const的形參使得函式能夠處理const和非const實參,否則只能接受非const資料。

int age = 20;

const int *pt = &age; // 1)

const int age = 20;

const int *pt = &age; // 2)

const int age = 20;

int *pt = &age; // 3) 報錯

int age = 30;

int *pt = &age;

const int *pd = pt; // 4)

int sum(int arr, int n); // 函式原型

const int months[3] = ;

int j = sum(months, 3); // 函式呼叫,報錯 5)

//正確做法

int sum(const int arr, int n); // 函式原型

int months[3] = ; // 或const int months[3] = ;

int j = sum(months, 3); // 函式呼叫,報錯 5)

第二種方法是將指標本身宣告為常量,這樣可以防止改變指標指向的位置。這種格式使得finger只能指向sloth,但允許finger來修改sloth的值。

int sloth  =3;

int * const finger = &sloth;

cout << *finger <4 函式和二維陣列

把二維陣列名作為引數時,函式原型有1)和2)處寫法。要注意int (*ar)[4]與int *ar[4]的區別:由於*先和ar結合,所以前者是乙個由4個int組成的陣列的指標;後者由於ar先於結合,所以是乙個由4個指向int的指標組成的陣列。

int data[3][4] = , , };

int total = sum(data, 3);

// 函式原型

int sum(int (*ar)[4], int size); // 1)

int sum(int ar[4], int size); // 2)

表示字串的三種方式:char陣列;用引號括起來的字串常量;被設定為字串的位址的char指標。但三種選擇的型別都是char*,所以函式原型應將其表示字串的形參宣告為char*型別,實際傳遞的是字串第乙個字元的位址。同理,返回值可以是字串的位址,也是char*型別。

有3種方法:第一種方法是:按值傳遞和返回結構 。它像普通變數那樣按值傳遞,函式將使用原始結構的副本。缺點結構非常大,則複製結構會增加記憶體要求。第二種方法是按指標傳遞,即傳遞結構的位址。呼叫函式時,將結構的位址——&結構名,傳遞給它;將形參宣告名為指向結構的指標,即結構名*型別;形參是指標,因此應用間接成員運算子->。第三種方法是按引用傳遞,實參為結構變數,形參使用引用變數

獲取函式的位址:如果func()是乙個函式,則func就是該函式的位址,要將函式作為引數進行傳遞,必須傳遞函式名。

宣告函式指標:要指定指標指向的函式型別,即宣告應指定函式的返回值和引數列表。通常要宣告指向特定型別的函式指標,可以首先編寫這種函式原型,然後用(*pf)替換函式名,則pf就是這類的函式指標。

使用指標來呼叫函式:第一種版本如1)處**,第二種版本如2)處**。儘管邏輯上是相互衝突的,但c++都認可這兩種方式。

double pam(int);     // 函式原型

double (*pf)(int); // 函式指標宣告

pf = pam;

double x = (*pf)(5); // 1)

double y = pf(5); // 2)

使用函式指標示例

double betsy(int);

double pan(int);

void estimate(int lines, double (*pf)(int));

using namespace std;

int main()

double betsy(int a)

double pan(int a)

void estimate(int lines, double (*pf)(int))

(31)C 命名空間

假設這樣一種情況,當乙個班上有兩個名叫 zara 的學生時,為了明確區分它們,我們在使用名字之外,不得不使用一些額外的資訊,比如他們的家庭住址,或者他們父母的名字等等。同樣的情況也出現在 c 應用程式中。例如,您可能會寫乙個名為 xyz 的函式,在另乙個可用的庫中也存在乙個相同的函式 xyz 這樣,...

C 高階3 1 C 特性 反射 屬性

unity3d從入門到高階 文章目錄及設定這個專欄的初衷 首先,我們肯定attribute是乙個類,下面是msdn文件對它的描述 公共語言執行時允許你新增類似關鍵字的描述宣告,叫做attributes,它對程式中的元素進行標註,如型別 字段 方法和屬性等。attributes和microsoft n...

C程式語言 3 1

練習3 1 在上面有關折半查詢的例子中,while迴圈語句內共執行了兩次測試,其實只要一次就足夠 代價是將更多的測試在迴圈外執行 重寫該函式,使得在迴圈內部只執行以此測試。比較兩種版本函式的執行時間。我一開始是沒想出來的,所以去網上看了看,發現網上有些 無法執行但思路是對的,所以重新改了改發出來。i...