從問題到程序課件_第1頁
從問題到程序課件_第2頁
從問題到程序課件_第3頁
從問題到程序課件_第4頁
從問題到程序課件_第5頁
已閱讀5頁,還剩103頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、從問題到程序第七章,指針程序執(zhí)行中數(shù)據(jù)存于內(nèi)存。在可用期間數(shù)據(jù)有確定存儲位置,占據(jù)一些存儲單元。內(nèi)存單元的編號:地址。機(jī)器語言通過地址訪問數(shù)據(jù)。高級語言用變量等作為存儲單元/地址的抽象。建立變量就是安排存儲。賦值時(shí)存入,用值時(shí)從中提取外部變量/靜態(tài)變量有全局存在期,程序執(zhí)行前安排存儲位置,保持到程序結(jié)束。自動變量在函數(shù)調(diào)用時(shí)安排存儲,至函數(shù)結(jié)束。再調(diào)用時(shí)重新安排存儲。7.1 地址與指針變量存在期就是它占據(jù)所安排存儲的期間。任何變量在存在期間總有確定存儲位置,有固定地址。寄存器變量可能放在寄存器,無地址。本章不考慮寄存器變量。變量存在時(shí)有地址,地址用二進(jìn)制編碼,因此可能成為程序處理的數(shù)據(jù)。問題:

2、地址作為數(shù)據(jù)有什么用?若程序可以處理對象地址,就可通過地址處理相關(guān)對象。對象(如變量)地址也被作為數(shù)據(jù),地址值/指針值。以地址為值的變量稱為指針變量/指針(pointer)。指針是一種訪問其他對象的手段,利用這種機(jī)制能更靈活方便地實(shí)施對各種對象的操作。指針的主要操作指針賦值:將程序?qū)ο蟮牡刂反嫒胫羔樧兞俊ig接訪問:通過指針訪問被指對象。指針還能保存其他對象的地址。下面討論以變量為例。指針p保存著變量x地址,也說指針p指向x。圖示:在C中使用指針常能寫出更簡潔有效的程序。有些問題必須用指針處理。指針在大型復(fù)雜軟件中使用廣泛。指針使用的水平是評價(jià)人的C程序設(shè)計(jì)能力的重要方面。C指針靈活/功能強(qiáng)。掌

3、握有難度,易用錯(cuò),應(yīng)特別注意。應(yīng)特別注意使用指針的常見錯(cuò)誤,注意!指針是變量,可賦值,其指向可以改變?,F(xiàn)在p指向x,以后可能指向y。通過p訪問被指對象的語句目前訪問x,后來就訪問y。這種新的靈活性很有用。7.2 指針變量的定義和使用指針有類型,只能保存特定類型的變量的地址指向int的指針p只能指向int變量。p所指也看作int,從p間接訪問當(dāng)作int。常說int指針p1等。定義指針需指明指向類型。定義指向int的指針變量:int *p, *q;指針變量可以與其他變量一起定義:int *p, n, a10, *q, *p1, m;指針是變量,可賦值取值,有定義域與存在期。應(yīng)賦給類型正確的指針值,

4、取出的值是特定類型的指針值。用(int*)表示整型指針的類型,其他類似。指針操作取地址運(yùn)算符& 和間接訪問操作 *。都是一元運(yùn)算符取地址運(yùn)算& 寫在變量描述(如變量名)前取變量地址,是對應(yīng)類型的指針值,可賦給類型合適的指針。例:p = &n; q = p; p1 = &a1;多個(gè)指針可能同時(shí)指向同一變量。變量相等是值相等,兩個(gè)指針變量相等說明它們指向程序里同一東西。間接運(yùn)算間接運(yùn)算得到被指針?biāo)傅淖兞?,這種表達(dá)式可以像普通變量一樣使用。設(shè)p指向n。間接賦值:*p = 17;這里寫*p相當(dāng)于直接寫n。另一個(gè)賦值:m = *p + *q * n; /* 訪問n三次 */+ *p; /* 使變量n的

5、值加1,變成18 */(*p)+; /* 使變量n的值再加1,變成19。*/*p += *q + n; /* 變量n被賦以新值57 */q = &a0;/* 指針q指向了數(shù)組a的元素 */指針作為函數(shù)參數(shù)指針作為函數(shù)參數(shù)有特殊意義,利用這種參數(shù)可寫出能修改調(diào)用時(shí)環(huán)境的函數(shù)。函數(shù)調(diào)用處的環(huán)境指在調(diào)用函數(shù)的位置能訪問的變量全體。前面函數(shù)的特點(diǎn):可使用調(diào)用處環(huán)境中變量的值(通過參數(shù)),但不能修改這些變量(數(shù)組參數(shù)除外)。在函數(shù)f里調(diào)用g,可將f的局部變量作為實(shí)參。但用g改變f局部變量的唯一方法是將g的返回值賦給f的局部變量。這種方法局限性太強(qiáng),例如無法在一個(gè)函數(shù)調(diào)用中修改兩個(gè)局部變量的值。利用指針可

6、以改變這種情況。例:定義函數(shù)swap,希望用它交換兩個(gè)變量的值。因?yàn)橐淖儍蓚€(gè)變量,無法通過返回值解決。下面定義不行:void swap0 (int x, int y) int t = x; x = y; y = t;int f() int a = 5, b = 10; swap0(a, b); /*不行*/函數(shù)內(nèi)修改形參,不會改變調(diào)用時(shí)的實(shí)參。分析:要(在一函數(shù)里)通過調(diào)用函數(shù)g修改調(diào)用處的變量(如局部變量),必須在g里掌握這個(gè)變量。用指針可以解決問題。把m的地址(也是值)通過指針參數(shù)p傳給g,函數(shù)內(nèi)對p間接訪問就能操作m,包括對m賦值(改變m)。例,通過函數(shù)調(diào)用把變量值設(shè)置為3:void

7、set3(int * np) *np = 3;使用實(shí)例:int main() int n, m; set3(&n); /* 設(shè)置n和m */ set3(&m); printf(%d, %dn, n, m); return 0;請回憶scanf的情況。通過參數(shù)改變調(diào)用環(huán)境的方案包括三方面:函數(shù)定義中用指針參數(shù);函數(shù)內(nèi)用間接操作實(shí)際變量;調(diào)用時(shí)以被操作變量的地址作為實(shí)參。函數(shù)swap可定義為:void swap(int *p, int *q) int t = *p; *p = *q; *q = t;交換變量m和n的值,調(diào)用形式是: swap(&m, &n);swap的參數(shù)類型是(int *),實(shí)參

8、必須是合法的整型變量的地址。設(shè)有變量定義:int a10, k;調(diào)用swap的實(shí)例:swap(&a0,&a5); swap(&a1,&k);介紹標(biāo)準(zhǔn)庫函數(shù)scanf時(shí),強(qiáng)調(diào)在接受輸入的變量前必須寫&,就是將變量的地址傳給scanf。scanf采用與swap一樣的技術(shù),通過間接訪問為指定變量賦值,把輸入的值賦給指定變量。例:改造上章輸入整數(shù)值并檢查值范圍的函數(shù),引進(jìn)指針參數(shù),使之能更好處理輸入錯(cuò)誤。前面實(shí)現(xiàn)里用特殊整數(shù)值指明輸入出錯(cuò),有很大缺點(diǎn)(可能不存在合適的值)。指針參數(shù)提供了另一種方法: 函數(shù)增加一個(gè)指針參數(shù),通過它送回讀入值。用函數(shù)返回值傳遞函數(shù)執(zhí)行的狀態(tài)信息。返回1表示輸入成功,0表示

9、輸入未能正常完成。 新函數(shù)定義: int getnumber(char prompt, int imin, int imax, int repeat, int *np) int i; for (i = 0; repeat=0 | irepeat; +i) printf(%s, prompt); if (scanf(%d, np)!=1 | *npimax) printf(Correct range %d, %d.n, imin, imax); while (getchar() != n) ; else return 1; return 0;前面的調(diào)用現(xiàn)在可以重寫為:getnumber(Choo

10、se a range 0, n. Input n: , 2, 32767, 5, &m);getnumber(Your guess: , 0, m-1, 5, &guess);更合適的調(diào)用形式:if (getnumber(Your guess: , 0, m-1, 5, &guess) = 0) /* 處理輸入出錯(cuò)的程序片段 */這類函數(shù)的形參為指針,實(shí)參必須是合法變量地址。 這里可以看到標(biāo)準(zhǔn)庫函數(shù)scanf的樣子。通過返回值表示函數(shù)的工作情況,是一種常用技術(shù)。 與指針有關(guān)的一些問題空指針值:一個(gè)特殊指針值,表示指針變量閑置(未指向任何變量)。唯一對任何指針類型都合法的值空指針值用0表示,標(biāo)準(zhǔn)

11、庫專門定義了符號常量 NULLp = NULL; 和p = 0; 相同前一寫法易看到是指針,用時(shí)必須包含標(biāo)準(zhǔn)頭文件。指針初始化指針變量定義時(shí)可用合法指針值初始化:int n, *p = &n, *q = NULL;若沒有初始化,外部指針和局部靜態(tài)指針自動初始化為用空;局部自動指針不自動初始化。指針使用中的常見錯(cuò)誤使用指針的最常見錯(cuò)誤是非法間接訪問:在指針未指向合法變量的情況下做間接。如:int f (.) int *p, n = 3; *p = 2; .p沒有初始化,沒有指向合法變量?!皯铱罩羔槨敝钢挡皇牵ó?dāng)時(shí))合法的變量地址的指針變量,也常被稱為“野指針”。間接訪問懸空指針是嚴(yán)重錯(cuò)誤,后果可

12、能很嚴(yán)重。常見錯(cuò)誤寫法(設(shè)p是懸空int指針,n是int變量):swap(p, &n); scanf(., p); scanf(., n);編譯程序不能發(fā)現(xiàn)scanf的錯(cuò)誤。有些系統(tǒng)可能對第一個(gè)例子(假設(shè)p未初始化)給出警告。間接訪問空指針也同樣無理,是非法的。通用指針 類型(void*),可以指向任何變量。聲明:int n, *p;double x, *q; void *gp1,*gp2;任何指針值可以賦給通用指針(不必轉(zhuǎn)換)。例: gp1 = &n; / gp1指向n(值是n的地址) gp2 = &x; / gp2指向x若通用指針gpt指向g,g類型是指針pt的指向類型,將gpt賦給pt(

13、要寫強(qiáng)制轉(zhuǎn)換)通過pt保證正確訪問g。gp1 = &n;p = (int*)gp1; /*合法,p是(int*) */q = (double*)gp1;/*不合法,q是(double*) */其他使用方式?jīng)]有任何保證。編譯程序不能識別強(qiáng)制轉(zhuǎn)換錯(cuò)誤。指針類型轉(zhuǎn)換并不改變指針值將整型變量n的地址賦給通用指針gpt,gpt存的就是n的地址。賦回整型指針不會有問題。將該地址賦給double指針,就造成了混亂。指針類型代表一種觀點(diǎn)。被整型指針?biāo)傅淖兞靠偪闯墒钦偷淖兞?;被雙精度指針指向。指針轉(zhuǎn)換是觀點(diǎn)轉(zhuǎn)換。從整型指針轉(zhuǎn)換到通用指針就是丟掉類型信息。保證恢復(fù)到原有類型(轉(zhuǎn)回整型指針),被指對象還可用。通

14、用指針不能做間接運(yùn)算被普通指針指向的變量的類型明確,間接后可以作為該類型的變量使用通用指針可以指向任何變量,通過通用指針間接訪問的意義無法確定。通用指針沒提供被指對象的類型信息,所以不能通過它們直接使用被指對象通用指針最無用,唯一用途就是提供指針值標(biāo)準(zhǔn)庫的某些函數(shù)使用了通用指針(后面會看到)7.3 指針與數(shù)組C指針與數(shù)組關(guān)系密切,以指針為媒介可以完成各種數(shù)組操作。常能使程序更加簡潔有效。用指針做數(shù)組操作同樣要特別注意越界錯(cuò)誤。指針和數(shù)組的關(guān)系是C語言特有的,除了由C派生出的語言(如C+),一般語言中沒有這種關(guān)系。指向數(shù)組元素的指針類型合適的指針可以指向數(shù)組元素。假定有定義:int *p1, *

15、p2, *p3, *p4;int a10 = 1,2,3,4,5,6,7,8,9,10; 可以寫:p1 = &a0; p2 = p1;p3 = &a5; p4 = &a10; p4沒指向a的元素,是指向a最后元素向后一個(gè)位置。C語言保證這個(gè)地址存在,但寫 *p4 是錯(cuò)誤的。 寫數(shù)組名得到數(shù)組首元素地址,元素類型的指針值?!皃1 = &a0;”可簡寫為: p1 = a;指針運(yùn)算當(dāng)指針p指向數(shù)組元素時(shí)說p指到了數(shù)組里。這時(shí)由p可以訪問被p指的元素,還可訪問數(shù)組的其他元素。例:p1指向a首元素,值合法(a0的地址),p1+1也合法(a1的地址)。p1+2、p1+3、也合法,分別為a其他元素的地址。由

16、它們可間接訪問a各元素。例:*(p1 + 2) = 3;/* 給a2賦值 */p2 = p1 + 5; /* 使p2指向a5 */也可由指向非首元素的指針出發(fā)訪問數(shù)組其他元素: *(p2 + 2) = 5; /* 給a7賦值 */可用減法訪問所指位置之前的元素: *(p2 - 2) = 4; /* 給a3賦值 */通過指針訪問數(shù)組元素時(shí)必須保證不越界。運(yùn)算取得的指針值(即使不間接訪問)必須在數(shù)組范圍內(nèi)(可過末元素一位置),否則無定義。這類運(yùn)算稱為“指針運(yùn)算”。其他常用指針運(yùn)算:用指針運(yùn)算得到的值做指針更新: p2 = p2 - 2; /* 這使p2改指向a3 */用增/減量操作做指針更新(指針

17、應(yīng)指在數(shù)組里): p3 = p2; +p3; -p2; p3 += 2;如果兩指針指在同一個(gè)數(shù)組里,可以求差,得到它們間的數(shù)組元素個(gè)數(shù)(帶符號整數(shù))。 n = p3 p2; /* 也可以求 p2 p3 */指在同一個(gè)數(shù)組里的指針可以比較大?。篿f (p3 p2) .當(dāng)p3所指的元素在p2所指的元素之后時(shí)條件成立(值為1),否則不成立(值為0)。兩個(gè)指針不指在同一數(shù)組里時(shí),比較大小沒有意義。兩個(gè)同類型指針可用 = 和 != 比較相等或不等;任何指針都能與通用指針比較相等或不等,任何指針可與空指針值(0或NULL)比較相等或不等。兩指針指向同一數(shù)據(jù)元素,或同為空值時(shí)它們相等。數(shù)組寫法與指針寫法如果

18、一個(gè)指針指在一個(gè)數(shù)組里,通過指針訪問數(shù)組元素的操作也可用下標(biāo)形式寫。設(shè)p1指向數(shù)組a0,p3指向a5??蓪懀?p13 = 5; p32 = 8;p13一類寫法稱為數(shù)組寫法,*(p+3)一類寫法稱為指針寫法。兩類寫法有等價(jià)效力,可以自由選用。對數(shù)組名求值得到指向數(shù)組首元素的指針值數(shù)組名可以“看作”常量指針,可參與一些指針運(yùn)算,與其他指針比大小,比較相等與不相等。通過數(shù)組名的元素訪問也可以采用指針寫法。a3可寫為*(a+3)。注意:數(shù)組名不是指針變量,特別是不能賦值,不能更改。若a為數(shù)組,下面操作都是錯(cuò)誤的:a+;a += 3;a = p;有些運(yùn)算雖不賦值但也可能沒意義。如 a3 不可能得到合法指

19、針值,因其結(jié)果超出數(shù)組界限指針運(yùn)算原理當(dāng)一個(gè)指針指向某數(shù)組里的元素時(shí),為什么能算出下一元素位置?(這是指針運(yùn)算的基礎(chǔ))指針有指向類型,p指向數(shù)組a時(shí),由于p的指向類型與a的元素類型一致,數(shù)據(jù)對象的大小可以確定。p+1的值可根據(jù)p的值和數(shù)組元素大小算出。由一個(gè)數(shù)組元素位置可以算出下一元素位置,或幾個(gè)元素之后的元素位置。指針運(yùn)算的基礎(chǔ)。通用指針即使指到數(shù)組里,因沒有確定指向類型,因此不能做一般指針計(jì)算,只能做指針比較?;谥羔樀臄?shù)組程序設(shè)計(jì)指針運(yùn)算是處理數(shù)組元素的另一方式,有時(shí)很方便。設(shè)有int數(shù)組a和指針p1,p2,下面代碼都打印a的元素: for (p1 = a, p2 = a+10; p1

20、p2; +p1) printf(%dn, *p1);for (p1 = a; p1 a+10; +p1) printf(%dn, *p1);for (p1 = p2 = a; p1 - p2 10; +p1) printf(%dn, *p1);for (p1 = a; p1 - a 10; +p1) printf(%dn, *p1);數(shù)組參數(shù)的意義C規(guī)定,數(shù)組參數(shù)就是相應(yīng)的指針參數(shù):int f(int n, int d) . .和int f(int n, int *d) . . 意義相同。數(shù)組參數(shù)的作用就是這樣實(shí)現(xiàn)的。對應(yīng)d的實(shí)參是被處理數(shù)組的名字,求值得到指針值,符合形參需要,使d指向該數(shù)組

21、的“首元素”。前面函數(shù)體里參數(shù)用數(shù)組寫法(對指針可這樣寫)。通過指針形參d訪問的相應(yīng)實(shí)參數(shù)組里的各元素。(數(shù)組參數(shù)就是利用指針實(shí)現(xiàn)的!)這也使采用數(shù)組參數(shù)的函數(shù)能修改實(shí)參數(shù)組。函數(shù)里也可用指針方式做元素訪問。int intsum (int n, int a) int i, m = 0; for (i = 0; i n; +i) m += *(a+i); return m;函數(shù)里不能用sizeof確定數(shù)組實(shí)參大?。汉瘮?shù)的數(shù)組形參實(shí)際是指針,求sizeof算出的是指針的大小。所有指針大小都一樣,它們保存的都是地址值,各種類型的地址值采用同樣表示方式。另一方面,sizeof的計(jì)算是在編譯中完成的。實(shí)

22、參是動態(tài)運(yùn)行中確定的東西。使用數(shù)組的一段元素以數(shù)組為參數(shù)的函數(shù)可處理一段元素。求元素和:double sum(int n, double a);設(shè)有雙精度數(shù)組b,40個(gè)元素已有值:用sum可求b所有元素之和/前一段元素之和:x = sum(40, b);y = sum(20, b);sum不知道b的大小,它由參數(shù)得到數(shù)組首元素地址,從這里開始求連續(xù)40或20個(gè)元素的和。也可用sum求b中下標(biāo)12到24的一段元素之和。z = sum(13, b+12);指針與數(shù)組操作函數(shù)實(shí)例例1,用指針方式實(shí)現(xiàn)字符串長度函數(shù)。一種方式:int strLength (const char *s) int n =

23、0; /*通過局部指針掃描串中字符*/ while (*s != 0) s+; n+; return n; 另一實(shí)現(xiàn):int strLength (const char *s) char *p = s; while (*p != 0) p+; return p - s;參數(shù)類型(char*),實(shí)參應(yīng)是字符串或存字符串的數(shù)組例2,用指針實(shí)現(xiàn)字符串復(fù)制函數(shù)。直接定義:void strCopy (char *s, const char *t) while (*s = *t) != 0) s+; t+; 賦值表達(dá)式有值,0就是0,函數(shù)可簡化:void strCopy (char *s, const c

24、har *t) while (*s = *t) s+; t+; 把指針更新操作也寫在循環(huán)測試條件里,程序是:void strCopy (char *s, const char *t) while (*s+ = *t+) ; / 空語句注意優(yōu)先級與結(jié)合性,增量運(yùn)算的作用與值等。例3,利用指針,輸出int數(shù)組里一段元素:void prt_seq(int *begin, int *end) for (; begin != end; +begin) printf(%dn, *begin); prt_seq(a, a+10);prt_seq(a+5, a+10);prt_seq(a, a+3);prt_

25、seq(a+2, a+6);prt_seq(a+4, a+4);prt_seq(a+10, a+10);最后兩個(gè)調(diào)用對應(yīng)空序列。序列為“半閉半開”。 還可寫出許多類似函數(shù)?!霸O(shè)置”函數(shù):void set_seq(int *b, int *e, int v) for (; b != e; +b) *b = v; 把序列中每個(gè)元素都用其平方根取代:void sqrt_seq (double *b, double *e) for (; b!=e; +b) *b = sqrt(*b); 求平均值:double avrg(double *b, double *e) double *p, x = 0.0;

26、 if (b = e) return 0.0; for (p = b; p != e; +p) x += *p; return x / (e - b);字符指針與字符數(shù)組常用字符指針指向字符數(shù)組元素。如指向常量字符串或存著字符串的字符數(shù)組,通常指向字符串開始。也可指到字符串中間,把指的東西當(dāng)字符串用。定義字符指針時(shí)可用字符串常量初始化,如:char *p = Programming;1)定義了指針p2)建立了一個(gè)字符串常量,內(nèi)容為Programming3)令p指向該字符串常量。圖(a)char a = Programming; 1)定義了一個(gè)12個(gè)字符元素的數(shù)組2)用Programming各字

27、符初始化a的元素,圖(b)1)指針p可重新賦值(數(shù)組不能賦值):p = Programming Language C;2)p和a類型不同,大小不同。a占12個(gè)字符的空間。3)a的元素可以重新賦值。如:a8=e; a9=r; a10=0;a的內(nèi)容現(xiàn)在變成“Programmer”按規(guī)定,字符串常量不得修改可定義字符指針變量并讓它指向已有字符數(shù)組。C程序常用這種方式使用和操作字符數(shù)組內(nèi)容。例如,輸入一行到數(shù)組里:enum NLINE = 256 ;char lineNLINE;int count; char *p;/*-*/p = line;while(plineNLINE-1 & (*p = ge

28、rchar()!=n) +p; *p = 0; /* 做成字符串 */*-*/for (count = 0, p = line; *p != 0; +p) if (*p = e) +count; /* 統(tǒng)計(jì)e的個(gè)數(shù) */7.4 指針數(shù)組復(fù)雜C程序里常用到指針的數(shù)組。例:需要一組字符串,常用字符指針數(shù)組索引它們。如軟件中錯(cuò)誤信息常用一組字符串表示。分散管理不便??啥x指針數(shù)組,指針分別指向輸出信息串常量。也可定義其他類型的指針數(shù)組,如指向整數(shù)或者其他類型的指針的數(shù)組,下面討論以字符指針為例。定義字符指針數(shù)組:char *pa10;優(yōu)先級也適用于定義。優(yōu)先級高,pa是數(shù)組,其元素是字符指針。定義字

29、符指針數(shù)組時(shí)用字符串常量提供初始值。例:char *days = Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday; 簡單實(shí)例:printf(Work days: );for(i=1; i6; +i) printf(%s , daysi);printf(nWeekend: );printf(%s %sn, days6,days0);字符指針數(shù)組實(shí)例:改寫第6章的C語言關(guān)鍵字統(tǒng)計(jì)程序,把原來的兩維字符數(shù)組keywords改為字符指針數(shù)組。只需定義下面數(shù)組,并用(關(guān)鍵字)字符串對各指針做初始化:char *keywords

30、 = auto, break, . . volatile, while;其他部分不需要改,程序可以正常工作。指針數(shù)組與兩維數(shù)組兩維字符數(shù)組與字符指針數(shù)組不同 。定義:char color16=RED,GREEN,BLUE;char *color=RED,GREEN,BLUE;命令行參數(shù)的處理啟動程序的基本方式是輸入命令,要求OS裝入程序代碼文件并執(zhí)行。命令行:描述命令的字符行。在圖形用戶界面系統(tǒng)(如Windows)里,命令行存在于圖標(biāo)/菜單的定義中。源文件abcd.c得到可執(zhí)行文件abcd.exe。鍵入命令:abcd該程序就會被裝入執(zhí)行。除命令名外,命令行常包括其他信息。DOS命令: copy

31、 a:file1.txt dir windowssystem /p附加信息也是字符序列,稱為命令行參數(shù)。前面的程序都沒有包含處理命令行的功能要寫能夠處理命令行參數(shù)的程序,需要用C語言的命令行參數(shù)機(jī)制。處理命令行參數(shù)很像處理函數(shù)參數(shù),寫程序時(shí)要考慮和處理程序啟動時(shí)實(shí)際命令行提供的信息。命令行被看作空格分隔的字段,各個(gè)命令行參數(shù)。命令名編號為0,其余依次編號。程序啟動時(shí)把各命令行參數(shù)做成字符串,程序里可按規(guī)定方式使用。設(shè)有程序 prog1;設(shè)啟動程序的命令行是:prog1 there are five arguments這時(shí)prog1是編為0的命令行參數(shù),there是編號1的命令行參數(shù),;共5個(gè)命

32、令行參數(shù)。通過main的參數(shù)可獲取命令行參數(shù)。main(void)表示不處理命令行參數(shù),main的另一形式帶兩個(gè)參數(shù):int main (int argc, char *argv);main開始執(zhí)行時(shí):argc是命令行參數(shù)的個(gè)數(shù)argv指向含argc+1個(gè)指針字符指針數(shù)組,前argc個(gè)指針指向各命令行參數(shù)串,最后有一個(gè)空指針圖為執(zhí)行下面命令時(shí) main 函數(shù)里的現(xiàn)場情況prog1 there are five argumentsmain參數(shù)常用argc、argv作為名字(實(shí)際上可以用其他名字)。參數(shù)類型確定。可由argc得到參數(shù)個(gè)數(shù),通過argv訪問它們。可以訪問啟動程序的命令名本身。在一些系

33、統(tǒng)里,0號參數(shù)還包括完整的目錄路徑。例:寫程序echo打印各命令行參數(shù)。寫程序時(shí)不知道調(diào)用時(shí)的命令行參數(shù)是什么,但可以打印它們:#include int main (int argc, char *argv) int i; for (i = 0; i argc; +i) printf(Args%d: %sn, i, argvi); return 0;書上有另一種定義方式,其中利用了最后的空指針用IDE開發(fā)程序時(shí),編輯/調(diào)試/執(zhí)行等工作都在環(huán)境里完成,執(zhí)行程序時(shí)如何提供命令行參數(shù)?集成開發(fā)環(huán)境都有專門機(jī)制為啟動命令行提供參數(shù)(如Turbo-C的Options/Arguments)??赊D(zhuǎn)到IDE之

34、外在命令行狀態(tài)下啟動程序。在圖形用戶界面系統(tǒng)里,有關(guān)命令行參數(shù)的討論同樣有效。建立程序項(xiàng)、命令菜單項(xiàng)等也要寫出實(shí)際命令行,包括提供必需的命令行參數(shù)。一些圖形界面系統(tǒng)里可把數(shù)據(jù)文件拖到程序文件上作為處理對象。此時(shí)將自動產(chǎn)生一個(gè)命令行。7.5 多維數(shù)組作為參數(shù)的通用函數(shù)函數(shù)的兩維或多維數(shù)組參數(shù)必須說明除第一維外各維的大小,這使函數(shù)失去了一般通用性。ANSI C 沒提供定義處理多維數(shù)組的通用函數(shù)的標(biāo)準(zhǔn)方法。可以通過技術(shù)解決。(C99 提供了標(biāo)準(zhǔn)方式)下面以兩維數(shù)組為例,多維數(shù)組可以類似處理??紤]:int fun1(int n, int mat10) . . matij . . 只能對第二維長10的數(shù)

35、組使用。不能處理其他數(shù)組mat的指向類型是int數(shù)組(兩維數(shù)組的元素是一維數(shù)組)。定義沒給出一維數(shù)組大小,指針定義不完全這樣,編譯程序雖然知道m(xù)at0的位置,但卻無法算出mat1等子數(shù)組位置以及matij位置。因此編譯工作無法完成。實(shí)際中確實(shí)需定義處理多維數(shù)組的通用函數(shù)。改寫為:int fun2(int n, int m, int mat) . . matij . . 這個(gè)定義錯(cuò)誤,無法通過編譯。為什么?解決方案:考慮數(shù)組 int a108;首元位置&a00。每行8元素,第1行開始位置是:&a00 + 8訪問第1行首元素用表達(dá)式:*(&a00 + 8)訪問第i行首元素用表達(dá)式:*(&a00 +

36、 i*8)訪問aij:*(&a00 + i*8 + j)可見,有了一些信息后,可以算出元素的位置處理兩維數(shù)組所需信息:1)基本元素類型;2)數(shù)組兩個(gè)維的長度;3)數(shù)組開始位置。通過參數(shù)可得到數(shù)組的首元素位置和各維長。輸出兩維整型數(shù)組的函數(shù),每行輸出在一行。void prtMatrix (int m, int n, int *mp) int i, j; for (i = 0; i m; +i) for (j = 0; j n; +j) printf(%d , *(mp + i * n + j); putchar(n); 打印數(shù)組a和另一2036的整型數(shù)組mat的調(diào)用形式:prtMatrix(10

37、, 8, &a00);prtMatrix(20, 36, &mat00);7.6 動態(tài)存儲管理變量(簡單變量/數(shù)組等)用于保存數(shù)據(jù),需安排存儲(稱為存儲分配)。高級語言編程不需要考慮存儲細(xì)節(jié),有關(guān)工作由編譯程序完成。編程效率高。在 C 語言里外部變量/局部靜態(tài)變量在編譯的時(shí)候確定存儲,開始執(zhí)行前分配存儲自動變量在執(zhí)行進(jìn)入定義函數(shù)時(shí)分配存儲共同性質(zhì):變量大小都是靜態(tài)確定的。例:函數(shù)中變量和參數(shù)決定了函數(shù)執(zhí)行時(shí)所需要存儲空間量, C 語言要求自動數(shù)組的大小用靜態(tài)表達(dá)式描述。這樣,函數(shù)需要的存儲量就可在編譯時(shí)確定。靜態(tài)處理存儲的優(yōu)點(diǎn)是方便,效率高,執(zhí)行中的工作簡單,速度快。但對編程方式加了限制,有些

38、問題不好解決。例:要處理學(xué)生成績,需要用數(shù)組存放。但編程時(shí)并不知道運(yùn)行時(shí)需要處理多少學(xué)生成績,每次處理的成績項(xiàng)數(shù)也可能不同。能否先通知數(shù)據(jù)項(xiàng)數(shù),再建數(shù)據(jù)表示?理想方式(現(xiàn)在行不通):int n;.scanf(%d, &n);double scoresn; /* 不行!*/. /* 讀入數(shù)據(jù),然后處理 */不能用變量說明scores大小(必須靜態(tài)確定)。至今討論的機(jī)制無法很好解決這類問題??赡芙鉀Q方案:1)分析問題,定義適當(dāng)大小的數(shù)組。若分析正確,一般都能處理。但數(shù)據(jù)很多時(shí)程序就不能用。2)定義盡可能大的數(shù)組以滿足任何需要。浪費(fèi)大量存儲資源。如有多個(gè)這種數(shù)組就更難辦。系統(tǒng)可能無法容納幾個(gè)大數(shù)組,

39、但實(shí)際上它們并不同時(shí)需要很大空間。解決的辦法是“動態(tài)存儲分配”。在程序運(yùn)行中做存儲分配工作。這里的問題:程序運(yùn)行中需要使用存儲,有時(shí)程序?qū)Υ鎯Φ男枨罅吭趯懗绦驎r(shí)不能確定。動態(tài)存儲分配與釋放根據(jù)運(yùn)行中的需要分配存儲,取得存儲塊使用,稱為動態(tài)存儲分配。在運(yùn)行中根據(jù)需要?jiǎng)討B(tài)進(jìn)行。程序里怎樣使用分配的存儲塊?程使用變量是通過名字。動態(tài)分配的存儲塊沒有名字,因此需要其他訪問途徑。借助于指針。用指針指向存儲塊,間接使用被指存儲。訪問動態(tài)分配存儲是指針的最重要用途。與此對應(yīng):動態(tài)釋放,不用的動態(tài)存儲塊應(yīng)交還。動態(tài)分配/釋放由動態(tài)存儲管理系統(tǒng)完成,這是程序運(yùn)行系統(tǒng)的子系統(tǒng),管理著稱作堆(英文heap)的存儲區(qū)

40、。大部分常規(guī)語言都有這種機(jī)制。C語言的動態(tài)存儲管理機(jī)制用標(biāo)準(zhǔn)庫函數(shù)實(shí)現(xiàn),/1)存儲分配函數(shù)malloc()。原型:void *malloc(size_t n); /*size_t是某整型*/分配一塊不小于n的存儲,返回其地址。無法滿足時(shí)返回空指針值。int n; double *data;. scanf(%d, &n);data=(double*)malloc(n*sizeof(double);if (data = NULL) . /* 分配未完成時(shí)的處理 */ .datai.*(data+j)./*正常處理*/malloc的返回值(void*)應(yīng)通過類型強(qiáng)制轉(zhuǎn)為特定指針類型后賦給指針變量。使

41、用注意事項(xiàng):分配存儲塊大小應(yīng)該用sizeof計(jì)算動態(tài)分配必須檢查成功與否動態(tài)分配的塊大小也是確定的。越界使用(尤其是越界賦值)是嚴(yán)重錯(cuò)誤,可能導(dǎo)致程序或系統(tǒng)垮臺2)帶計(jì)數(shù)和清0的存儲分配函數(shù)calloc。原型:void *calloc(size_t n, size_t size);size是元素大小,n是個(gè)數(shù)。分配一塊存儲,足夠存n個(gè)大小為size的元素,并把元素全部清0;無法分配時(shí)返回空指針值。前面的存儲分配問題也可用下面語句實(shí)現(xiàn):data = (double*)calloc(n, sizeof(double);主要差別:malloc對所分配的區(qū)域不做任何事情,calloc對整個(gè)區(qū)域自動清0

42、。3)動態(tài)存儲釋放函數(shù)free。原型:void free(void *p);free釋放p指的存儲塊。注意:該塊必須是通過動態(tài)存儲分配得到的p值為空時(shí)什么也不做執(zhí)行free(p)后p值未變,被指塊可能已變。不允許間接訪問已釋放存儲塊不要對并非指向動態(tài)分配塊的指針用本操作為保證動態(tài)存儲的有效使用,動態(tài)分配塊不再用時(shí)應(yīng)釋放。動態(tài)存儲塊的釋放只能通過調(diào)用free完成。程序例子:int fun (.) int *p; . p = (int *)malloc(.); . free(p); return .; /*退出函數(shù)前應(yīng)釋放函數(shù)內(nèi)分配且已無用的動態(tài)存儲*/fun退出時(shí)p存在期結(jié)束,若沒有訪問分配塊的

43、其他途徑,將不可能再用到函數(shù)里分配的存儲塊。動態(tài)存儲的流失。如程序長期執(zhí)行,存儲流失就可能成為嚴(yán)重問題。對實(shí)際系統(tǒng)可能是很嚴(yán)重的問題。4)分配調(diào)整函數(shù)realloc。函數(shù)原型是:void *realloc(void *p, size_t n);更改已有分配。p指原分配塊,n是新大小要求。返回大小至少為n的存儲塊指針。新塊與原塊一致:新塊小時(shí)保存原塊n范圍內(nèi)數(shù)據(jù);新塊大時(shí)原數(shù)據(jù)存在,新增部分不初始化。分配成功后原塊可能改變。無法滿足時(shí)返回空指針,原塊不變。常用寫法(防止分配失敗導(dǎo)致原存儲塊丟失) :q = (double*)realloc(p, m * sizeof(double);if (q

44、= NULL) /*未成功,p仍指原塊,特殊處理*/ else p = q; /* 令p指向新塊,正常處理 */ .例1:修改篩法程序,由命令行參數(shù)得到所需范圍。如無命令行參數(shù)則要求用戶輸入確定范圍的整數(shù)值。 先考慮整體設(shè)計(jì)。為了清晰,將篩法用函數(shù)實(shí)現(xiàn)。命令行參數(shù)(字符串)需要轉(zhuǎn)換到整數(shù),定義函數(shù):int s2int(const char *s); 函數(shù)實(shí)現(xiàn)(標(biāo)準(zhǔn)庫有類似函數(shù)atoi):int s2int(const char *s) int n; for (n = 0; isdigit(*s); +s) n = 10 * n + (*s - 0); return n;篩法計(jì)算包裝為函數(shù):vo

45、id sieve(int lim, int an) int i, j, upb = sqrt(lim+1); an0 = an1 = 0; / 建立初始向量 for (i = 2; i = lim; +i) ani = 1; for (i = 2; i = upb; +i) if (ani = 1) / i是素?cái)?shù) for (j = i*2; j = lim; j += i) anj = 0; / i的倍數(shù)不是素?cái)?shù)main的工作:1)獲取范圍(由命令行或用戶),2)分配空間及初始化,3)執(zhí)行篩法,4)打印輸出。enum LARG = 65535 ;int main(int argc, char

46、*argv) int i, j, n, *ns; if (argc = 2) n = s2int(argv1); else getnumber(Largest: ,2,LARG,5,&n); if (n LARG) printf(Largest must in 2, %d,LARG); return 1; ns = (int*)malloc(sizeof(int)*(n+1) if (ns = NULL) printf(No enough memory!n); return 2; sieve(n, ns); . /* 輸出略 */ free(ns); return 0;例2,改造成績直方圖程序

47、,使之能處理任意個(gè)數(shù)據(jù)。如何處理事先無法確定數(shù)目的數(shù)據(jù)集合。用數(shù)組限制了能處理的項(xiàng)數(shù),現(xiàn)在改用動態(tài)分配。讓getscores根據(jù)需要申請存儲塊,返回動態(tài)分配的塊和實(shí)際項(xiàng)數(shù)。函數(shù)原型:double* readscores(int* np); 由np送回項(xiàng)數(shù)無法分配存儲時(shí)返回NULL如果已讀了部分?jǐn)?shù)據(jù),但在擴(kuò)大存儲失敗,就給出信息并返回部分?jǐn)?shù)據(jù)主函數(shù):int main() int n; double *scores = readscores(&n); if(scores = NULL) return 1; . /* 其他不必修改 */由于原來的設(shè)計(jì)比較得當(dāng),現(xiàn)在只需做少許修改由此可見良好設(shè)計(jì)的重要

48、性readscores的定義:事先不知道數(shù)據(jù)項(xiàng)數(shù),可以先分配一塊,讀入中發(fā)現(xiàn)不夠用時(shí)擴(kuò)大。開始分配多大?采用什么擴(kuò)大策略?下面采用開始分配一塊,隨后不夠時(shí)加倍的策略。有關(guān)存儲分配和擴(kuò)大策略的討論見書。這個(gè)定義主要顯示分配調(diào)整技術(shù),沒有追求完善。讀入中遇到錯(cuò)誤數(shù)據(jù)就立即結(jié)束。數(shù)據(jù)檢查和處理問題前面已討論過,修改這個(gè)函數(shù),使之能合理處理輸入數(shù)據(jù)錯(cuò)誤,給出有用信息,或增加其他有用功能等都留作 練習(xí)。enum INUM = 40 ;double* readscores(int* np) unsigned size = INUM, n; double *q, x, *p; if(p=(double*)m

49、alloc(INUM*sizeof(double)=NULL) printf(No memory. Stopn); *np = 0; return NULL; for(n=0; scanf(%lf, &x) = 1; +n) if (n = size) /* 塊滿了,需要重新分配 */ size *= 2; q = (double*)realloc(p, size*sizeof(double); if (q = NULL) printf(Process only %d scores.n, n); break; p = q; pn = x; *np = n; return p;函數(shù)、指針和動態(tài)存

50、儲分配要用函數(shù)處理一組數(shù)據(jù),得到處理結(jié)果,最好的方式是直接為函數(shù)提供數(shù)組位置和元素個(gè)數(shù)(或結(jié)束位置)。前面經(jīng)常采用這種方式。這時(shí)函數(shù)不必知道處理的是數(shù)組變量還是動態(tài)存儲。例如,完全可以用如下方式調(diào)用篩法函數(shù):int ns1000;int main() . sieve(1000, ns); . return 0;這時(shí)存儲的問題在一個(gè)層次中管理(定義變量或動態(tài)分配)。責(zé)任清晰,易于把握,是最好的處理方案。 有時(shí)無法采用上述方法。例如前面直方圖程序,只能由readscores根據(jù)情況分配存儲,送出存儲塊地址。main用指針接收。這種做法完全正確動態(tài)分配的塊將一直存在到明確釋放為止(直到對它調(diào)用fre

51、e),與分配所在的函數(shù)無關(guān)。readscores返回存儲塊地址不僅傳回?cái)?shù)據(jù),也將管理這個(gè)塊的責(zé)任轉(zhuǎn)交給main??梢娗懊娴?main 結(jié)束前缺了free(scores)調(diào)用。應(yīng)該加上。前面的readscores返回塊地址,由參數(shù)傳回塊的大?。▽nt變量地址給int*)。另一種可能方式是讓readscores返回塊大小,無法分配存儲時(shí)返回0?,F(xiàn)在考慮這種設(shè)計(jì)的問題:調(diào)用方式:if (readscores(.)=0) /*處理錯(cuò)誤*/ 函數(shù)原型應(yīng)該是:int readscores(?); /* 參數(shù)類型?*/現(xiàn)在需要的是通過實(shí)參得到動態(tài)塊的地址,這是一個(gè)(double*)值已知,要想通過函數(shù)的參

52、數(shù)取得送出來的int值,參數(shù)就應(yīng)該為(int*)類型,實(shí)參用int變量地址要通過參數(shù)送出(double*)類型的值,實(shí)參就應(yīng)該傳遞(double*)變量的地址。因此,形參應(yīng)該是指向(double*)類型的指針,也就是(double*)類型正確的原型:int readscores(double* dpp);調(diào)用:if(readscores(&scores)=0)/*錯(cuò)誤處理*/這里討論了不同函數(shù)層次之間存儲分配、傳遞和使用的幾種技術(shù)。各有適用之處,可根據(jù)情況選擇。關(guān)于動態(tài)存儲分配計(jì)算機(jī)系統(tǒng)的內(nèi)存由OS(操作系統(tǒng))管理。啟動一個(gè)程序時(shí),OS為它分配內(nèi)存,存放它的代碼和數(shù)據(jù)。程序結(jié)束時(shí)OS收回該程序

53、所占用的所有內(nèi)存。C程序啟動時(shí)從OS得到的內(nèi)存,其中一大塊由自己的動態(tài)存儲管理系統(tǒng)管理。程序里調(diào)用malloc將在這塊里分配存儲,free將內(nèi)存塊退回動態(tài)存儲管理系統(tǒng)。這是C程序內(nèi)部的事情。至于C動態(tài)存儲管理系統(tǒng)如何與OS打交道的問題是看不見的(透明的)。一個(gè)C程序結(jié)束時(shí),OS收回原先分配給它的全部內(nèi)存。這是OS的存儲管理問題,與我們的程序無關(guān)。7.7 定義類型基本類型有類型名,可用于定義/說明變量,描述函數(shù)參數(shù)與返回值,做類型強(qiáng)制等。數(shù)組、指針等等可能使說明變得很復(fù)雜,使用不便。也不容易保證多個(gè)類型描述的一致性。如果能把復(fù)雜類型描述看作類型(用戶定義類型) 加以命名,可帶來很大方便,特別是在

54、實(shí)現(xiàn)復(fù)雜程序/軟件系統(tǒng)時(shí)。定義類型是重要語言機(jī)制,定義好的類型最好能像內(nèi)部類型一樣使用。C語言類型定義機(jī)制較弱,其主要作用是簡化描述。類型定義用關(guān)鍵字typedef,其后的描述形式與變量定義相似,使原變量位置的標(biāo)識符成為新類型名。typedef unsigned long int ULI;定義后的ULI可以像基本類型名一樣用:ULI x, y, *p;ULI fun1(double x, ULI n);p = (ULI*)malloc(n*sizeof(ULI);這種類型定義可簡化程序書寫,有一定實(shí)際價(jià)值。有時(shí)定義新類型可提高可讀性和清晰性。如:typedef double LENGTH;ty

55、pedef double AREA;定義不同類型名可能幫人看到不一致情況。注:C語言認(rèn)為定義的只是原類型的別名。LENGTH和AREA是double的別名。提高程序的可讀性。用預(yù)處理命令可產(chǎn)生類似效果。如:#define LENGTH double#define AREA double但兩種寫法處理過程不同,類型定義由編譯程序處理。有些類型不能通過宏的方式(例如數(shù)組類型)。定義數(shù)組類型數(shù)組類型定義形式符合前面解釋。例:typedef double VECT44;此后可以寫:VECT4 v1, v2;int intprod(VECT4 v, VECT4 u);55的雙精度數(shù)組類型:typedef

56、 double MAT55;MAT a1, a2, a3; /*定義55數(shù)組變量*/double det(MAT m); /*說明函數(shù)參數(shù)*/MAT *p = (MAT *)malloc(sizeof(MAT);定義指針類型 例如:typedef int * IP;typedef MAT * MATP;用宏定義代替它們,可能造成意想不到的結(jié)果。例如寫#define MIP int *而后希望定義兩個(gè)指針:MIP mp1, mp2;可發(fā)現(xiàn)mp2不是指針,而是一個(gè)int變量。只要把這個(gè)描述按規(guī)則展開,就不難發(fā)現(xiàn)其中的問題。宏是低級正文代換機(jī)制,應(yīng)盡量少用。這又是一例。需要定義類型名時(shí),應(yīng)該用typ

57、edef。復(fù)雜類型描述與解讀類型描述可能變得很復(fù)雜(C語言的缺點(diǎn))。應(yīng)盡量不寫復(fù)雜描述。用typedef分解,易理解/少出錯(cuò)。定義后可多次使用/節(jié)省時(shí)間/方便維護(hù)。讀程序時(shí)可能遇到復(fù)雜類型描述。應(yīng)了解類型描述的一般構(gòu)造及解讀方式。描述類型時(shí)也能更清楚,知道怎樣寫,什么地方需要加括號等。類型描述中可出現(xiàn):已定義類型名,被定義標(biāo)識符,構(gòu)造符號(三個(gè)(組)運(yùn)算符):*()指針數(shù)組函數(shù)可加圓括號改變結(jié)合關(guān)系。又增加了理解難度。解讀方式:符號意義不變,優(yōu)先級和結(jié)合關(guān)系按運(yùn)算符規(guī)定。和()結(jié)合性強(qiáng),*結(jié)合力弱;和()從左到右結(jié)合,*從右向左結(jié)合。首先辨認(rèn)被說明(定義)的標(biāo)識符,從它向外分析。這個(gè)標(biāo)識符常出

58、現(xiàn)在描述中間,被其他符號包圍。一些例子:1)int *f(int);被說明的是f,f是一個(gè)函數(shù)。2)int (*fp)(int);說明的是fp。fp是一個(gè)指針,指向.3)char *argv;argv是個(gè)指針,指向(char*)4)int (*dp)16;dp是指針,它指向有16個(gè)元素的整型數(shù)組。5)int *dp116;dp1是個(gè)16個(gè)元素的數(shù)組,其元素是整型指針。6)int (*(*g(int)4)(double);被說明的是函數(shù)g,有一整型參數(shù),返回指針,指針指向4個(gè)元素的數(shù)組,數(shù)組元素是指向函數(shù)的指針,被指函數(shù)有一個(gè)雙精度參數(shù)并返回整數(shù)值。類型描述就是用三種構(gòu)造符號及表示結(jié)合性的括號,

59、逐層構(gòu)造起來。很復(fù)雜的類型描述非常少見。有些構(gòu)造不合法:函數(shù)不能返回?cái)?shù)組,函數(shù)不能返回函數(shù),函數(shù)不能作數(shù)組元素等。利用typedef能更清晰地描述復(fù)雜類型。下面以例6)為例。實(shí)際分解應(yīng)該根據(jù)需要,看哪個(gè)(哪些)層次的類型有邏輯意義,有用處。原描述:int (*(*g(int)4)(double);先定義函數(shù)指針類型和函數(shù)指針數(shù)組類型:typedef int (*funp)(double);typedef funp fparray4;有這兩個(gè)類型,g的類型可以簡單地說明為:fparray *g(int);g是函數(shù),有一個(gè)int參數(shù),返回指向fparray的指針上面定義的兩個(gè)類型也可以用于定義變量

60、等。7.8 指向函數(shù)的指針例:設(shè)需要定義求數(shù)學(xué)函數(shù)的根。前面定義過一個(gè)函數(shù),但那只是玩具,只能當(dāng)作練習(xí)答案,實(shí)際中沒什么用。原因:求根函數(shù)規(guī)定了被求根數(shù)學(xué)函數(shù)的名字。規(guī)定函數(shù)名則使求根函數(shù)不能用于多個(gè)函數(shù),只能對一個(gè)特定的函數(shù)求根。程序可能需要求多個(gè)函數(shù)的根,應(yīng)只寫一個(gè)求根函數(shù)。提高函數(shù)通用性方法:引進(jìn)新參數(shù)。要使求根函數(shù)能處理不同的數(shù)學(xué)函數(shù),必須為它引進(jìn)與函數(shù)有關(guān)的參數(shù)。其他許多語言也支持函數(shù)的“函數(shù)參數(shù)”,但采用的方式可能與C語言不同。C采用函數(shù)指針是為簡化語言,同時(shí)又能提供最大靈活性,可以支持其他程序設(shè)計(jì)技術(shù)。C語言里的函數(shù)指針也有類型,一個(gè)函數(shù)指針只能指向某種特定類型(具有特定原型)的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論