第七天(函式 C 程式設計模組)

2021-05-28 16:25:33 字數 4249 閱讀 6674

2011-10-07(functions: c++'s programming modules)

1、函式的返回值可以是宣告的返回值型別或者可轉換成該型別的型別。返回值型別不能是陣列,其他的的都可以,包括指標、含有陣列成員的結構體、物件。

2、

returntype funcname(parameterlist);

c++中必須提供函式原型。有兩類函式宣告原型的時候要注意:無引數和不指定引數,分別這樣宣告:

void funcname();            //括號裡無引數代表void

void funcname(...);         //不指定引數

3、如果傳給函式的是陣列,且唯讀,應該用

const

修飾,這樣在這個函式中,陣列就會被看成常量而不能修改,如:

void display(const int , int); //prototype

void display(const int a, int size)

4、const和指標。

i、一級指標情況。

const

修飾的物件有兩種:修飾變數和修飾指標。前者,很明顯,變數本身不能改;後者,修飾的方式有兩種,所獲效果亦有兩種。

①可以將非

const

變數賦給

const

指標,有兩種形式:

int a = 10;

const int* p1 = &a; //form i

int* const p2 = &a; //form ii

form i,對於p1來說,a跟自己一樣是

const

的,不能通過p1來修改a的值,可以改變其指向:

*p1 = 20;           //invalid

a = 20; //valid

int newa = 100;

p1 = &newa //valid

form ii,可以通過*p2來修改a的值,但不能改變p2的指向:

*p1 = 20;           //valid

int newa = 100;

p1 = &newa //invalid

當然還可以同時使用兩種形式,效果疊加:

const int* const p; 

②不能將const變數賦給非const指標:

const int a = 10;

int* p = &a; //invalid

如果上述**可寫,意味著可以通過*p來改變a的值,那將a修飾為

const

將無意義。

ii、二級指標情況。乙個非

const

指標不能賦給乙個

const

二級指標,這與變數和一級指標關係不同:

int* p;

const int** p = &p //invalid

為什麼呢?假設上述**編譯可通過,如果我們接下來這樣處理:

const int a = 5;      //a constant variable

*pp = &a; //valid, both *pp and &a is constant. meanwhile, p = &a

*p = 10; //valid, p is not const, but you change a's value,which is forbidden

最終結果是將

const

變數a的值改變。

總結i、ii,如果資料本身不是指標,則可以將

const

資料或非

const

資料(的位址)賦給

const

指標,對於非指標,只能將非

const

資料賦給它。

5、函式與結構體。傳遞與返回結構體,在c++中又三種方法:按值傳遞、傳遞位址和按引用傳遞。這裡按引用傳遞暫不表。按值傳遞,就是把結構體看成乙個基本資料型別,不同的是它可以用「.」來引用結構體成員。按值傳遞有個缺點,當結構體很大的時候,將其複製並賦給函式將費去很多時間,所以很多時候都是按位址傳遞的。比如現在宣告乙個loc結構體,裡面包含成員x,y。再編寫函式sum以兩個loc為形參,而後返回loc,成員值是形參x,y各自的和。兩種實現形式:

#include using namespace std;

struct loc

;loc sum(loc, loc);

int main()

; loc l2 = ;

loc l3 = sum(l1, l2);

cout << "l3.x = " << l3.x << endl;

cout << "l3.y = " << l3.y << endl;

return 0;

}loc sum(loc l1, loc l2)

; return l3;

}

#include using namespace std;

struct loc

;loc* sum(loc*, loc*);

int main()

; loc l2 = ;

loc* l3 = new loc;

l3 = sum(&l1, &l2);

cout << "l3.x = " << l3->x << endl;

cout << "l3.y = " << l3->y << endl;

delete l3;

return 0;

}loc* sum(loc* l1, loc* l2)

6、函式指標。函式也有位址,可以將函式a作為另乙個函式b的形參,而後使用它。當然這樣和在b中直接使用a有什麼區別,我現在說不上。但教材提到:如果未提到函式指標,則對c或者c++的函式討論將是不完整的。顯示是對這個方法的一種肯定,有其實用價值。回到正題,在以函式指標為引數,傳給另乙個函式,需要了解三件事:

i、獲取函式的位址。很簡單,函式名就是其位址。比如函式func(),func就是它的位址。

ii、宣告函式指標。

returntype func(parameterlist);

如果將函式名func換為*pf,即returntype (*pf) (parameterlist),因為*pf是函式,則pf是指向函式的指標。

iii、使用函式指標來呼叫函式。比如某函式接收了乙個名為pf的函式指標,在這個函式內使用它,可以採用兩種形式(假設pf的返回值和唯一的引數是

int):

int a = pf(5);         //form i

int b = (*pf) (6);     //form ii

這是兩種矛盾的形式。不過在c++均可。

理論過後,舉個例子:

#include using namespace std;

void f1(int); //tow basic functions

void f2(int);

//main function to use tow basic functions

void mainf(int, void(*pf) (int));

int main()

void f1(int a)

void f2(int a)

void mainf(int x, void(*pf) (int))

輸出: 

you use f1 as parameter, and f1's parameter value: 10

you use f2 as parameter, and f2's parameter value: 50

函式mainf的原型表明它可以接受任何以

void

為返回值(即:無返回值),

int為引數列表的函式的位址,這可能比直接呼叫函式通用。

C 學習第七天

c 中的params引數 引數陣列 1 params引數是陣列。呼叫方式可以陣列方式,也可以單個元素方式。static void test string name,params int scores console.writeline 你好,你的scores is name,sb test 劉德華 ...

C語言第七天

今天學習了結構體這個高大上的東西,在與函式結合的時候,我徹底懵了.做作業的時候我老忘記結構體是一種我自己定義的資料型別 老想著用int之類的型別.這樣就容易懵了,下次我一定要注意這些問題.結構體是一種自定義的資料型別 用struct關鍵字宣告乙個結構體 struct point 定義乙個結構體變數 ...

C 基礎第七天

1 ref引數 ref引數側重於將乙個變數以引數的形式帶到乙個方法中進行改變,改變完成後,再講改變後的值帶出來。在使用ref引數的時候需要注意 ref引數在方法外必須為其賦值。2 方法的過載 方法的過載指的是方法的名稱相同,但是引數不同。引數不同 1 如果引數的個數相同,那麼引數的型別就不能相同。2...