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...