![程序設(shè)計(jì)基礎(chǔ):ch13 若干深入問(wèn)題_第1頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2021-12/10/282c8d06-5753-4c62-a2f8-f98f73d1913d/282c8d06-5753-4c62-a2f8-f98f73d1913d1.gif)
![程序設(shè)計(jì)基礎(chǔ):ch13 若干深入問(wèn)題_第2頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2021-12/10/282c8d06-5753-4c62-a2f8-f98f73d1913d/282c8d06-5753-4c62-a2f8-f98f73d1913d2.gif)
![程序設(shè)計(jì)基礎(chǔ):ch13 若干深入問(wèn)題_第3頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2021-12/10/282c8d06-5753-4c62-a2f8-f98f73d1913d/282c8d06-5753-4c62-a2f8-f98f73d1913d3.gif)
![程序設(shè)計(jì)基礎(chǔ):ch13 若干深入問(wèn)題_第4頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2021-12/10/282c8d06-5753-4c62-a2f8-f98f73d1913d/282c8d06-5753-4c62-a2f8-f98f73d1913d4.gif)
![程序設(shè)計(jì)基礎(chǔ):ch13 若干深入問(wèn)題_第5頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2021-12/10/282c8d06-5753-4c62-a2f8-f98f73d1913d/282c8d06-5753-4c62-a2f8-f98f73d1913d5.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、n 函數(shù)函數(shù) 函數(shù)指針函數(shù)指針 函數(shù)作參數(shù)函數(shù)作參數(shù) 間接遞歸間接遞歸 函數(shù)副作用函數(shù)副作用n 運(yùn)算運(yùn)算 賦值賦值 順序表達(dá)式順序表達(dá)式 條件表達(dá)式條件表達(dá)式 位運(yùn)算位運(yùn)算作業(yè)作業(yè): 13.6 13.7 n語(yǔ)句語(yǔ)句 break continue for的延伸的延伸 goto和標(biāo)號(hào)和標(biāo)號(hào)n數(shù)據(jù)組織數(shù)據(jù)組織 多維數(shù)組與指針多維數(shù)組與指針 位段位段 共用體共用體n存儲(chǔ)類別存儲(chǔ)類別n編譯預(yù)處理編譯預(yù)處理在本例題中,在本例題中,l 函數(shù)函數(shù)sort有三個(gè)參數(shù),有三個(gè)參數(shù),a是被排序的數(shù)組,是被排序的數(shù)組,n是數(shù)組長(zhǎng)度,是數(shù)組長(zhǎng)度,flag是遞增或遞減標(biāo)記;是遞增或遞減標(biāo)記;l 函數(shù)函數(shù)swap交換兩個(gè)變
2、量的值;交換兩個(gè)變量的值;l 函數(shù)函數(shù)ascending判斷是否判斷是否ab ;l 函數(shù)函數(shù)descending判斷是否判斷是否ab 。 當(dāng)調(diào)用當(dāng)調(diào)用sort 時(shí),時(shí),sort 根據(jù)根據(jù) flag 的值是否的值是否“ascending”,決定按遞增,決定按遞增或遞減排序,把函數(shù)名或遞減排序,把函數(shù)名 ascending 或或 descending 賦值給函數(shù)指針變量賦值給函數(shù)指針變量 ad 。通過(guò)調(diào)用通過(guò)調(diào)用 ad 所指向的函數(shù),所指向的函數(shù),判斷是否需要交換數(shù)組兩個(gè)判斷是否需要交換數(shù)組兩個(gè)相鄰成分。當(dāng)需要交換時(shí),相鄰成分。當(dāng)需要交換時(shí),調(diào)用函數(shù)調(diào)用函數(shù) swap。經(jīng)過(guò)多次。經(jīng)過(guò)多次掃描,最終
3、達(dá)到排序目的。掃描,最終達(dá)到排序目的。 函數(shù)函數(shù) sort 使用了指向使用了指向函數(shù)的指針調(diào)用函數(shù)函數(shù)的指針調(diào)用函數(shù) ascending 或或 descending 。運(yùn)行結(jié)果演示運(yùn)行結(jié)果演示例如例如 int (*f) ( float d , char c );聲明指向聲明指向“返回返回int類型值的函數(shù)類型值的函數(shù)”的函數(shù)指針變量的函數(shù)指針變量 f ,f 所指向所指向的函數(shù)有兩個(gè)形式參數(shù)的函數(shù)有兩個(gè)形式參數(shù):l 第一個(gè)參數(shù)是第一個(gè)參數(shù)是float類型,類型,l 第二個(gè)參數(shù)是第二個(gè)參數(shù)是char類型。類型。 函數(shù)指針聲明中用括號(hào)把星號(hào)函數(shù)指針聲明中用括號(hào)把星號(hào)“*”和和“標(biāo)識(shí)符標(biāo)識(shí)符”括起來(lái)是
4、括起來(lái)是必須的,比如上述的必須的,比如上述的“(*f)”,原因是由優(yōu)先級(jí)造成的。引,原因是由優(yōu)先級(jí)造成的。引進(jìn)函數(shù)指針概念不是憑空臆造的,它的作用在于進(jìn)函數(shù)指針概念不是憑空臆造的,它的作用在于l使用函數(shù)指針調(diào)用函數(shù)使用函數(shù)指針調(diào)用函數(shù)l實(shí)現(xiàn)其它程序設(shè)計(jì)語(yǔ)言中函數(shù)參數(shù)的功能實(shí)現(xiàn)其它程序設(shè)計(jì)語(yǔ)言中函數(shù)參數(shù)的功能可以把函數(shù)名賦值給一個(gè)函數(shù)指針變量,然后通過(guò)函數(shù)指針變可以把函數(shù)名賦值給一個(gè)函數(shù)指針變量,然后通過(guò)函數(shù)指針變量調(diào)用函數(shù)。形式是:量調(diào)用函數(shù)。形式是:函數(shù)指針變量函數(shù)指針變量 = 函數(shù)名;函數(shù)名;要求函數(shù)指針的特性與函數(shù)名的特性一致,這種一致性體現(xiàn)在要求函數(shù)指針的特性與函數(shù)名的特性一致,這種一
5、致性體現(xiàn)在l它們的返回類型相同;它們的返回類型相同;l它們的參數(shù)個(gè)數(shù)相同;它們的參數(shù)個(gè)數(shù)相同;l對(duì)應(yīng)位置上,每個(gè)形式參數(shù)的類型相同。對(duì)應(yīng)位置上,每個(gè)形式參數(shù)的類型相同。使用函數(shù)指針要注意:使用函數(shù)指針要注意:l 給函數(shù)指針賦值時(shí),右端只是一個(gè)函數(shù)名,不許帶參數(shù)表。給函數(shù)指針賦值時(shí),右端只是一個(gè)函數(shù)名,不許帶參數(shù)表。 ad = ascending 是正確的,而是正確的,而 ad = ascending(int,int) 是錯(cuò)誤的。是錯(cuò)誤的。l 不能對(duì)函數(shù)指針變量進(jìn)行任何運(yùn)算。不能對(duì)函數(shù)指針變量進(jìn)行任何運(yùn)算?!癮d+n”、“ad+”、“ad-” 等是等是錯(cuò)誤的。錯(cuò)誤的。l 利用函數(shù)指針調(diào)用函數(shù)時(shí),
6、把利用函數(shù)指針調(diào)用函數(shù)時(shí),把 “*” 和函數(shù)名用括號(hào)括起來(lái),成和函數(shù)名用括號(hào)括起來(lái),成 (*函數(shù)名)(函數(shù)名)( ) 形式,是必須的。因?yàn)樾问?,是必須的。因?yàn)椤埃ǎǎ钡膬?yōu)先級(jí)高于的優(yōu)先級(jí)高于“*”。在例。在例13-3中,調(diào)用函中,調(diào)用函數(shù)指針數(shù)指針 ad 所指函數(shù)的形式是所指函數(shù)的形式是 (*ad)(ac,ac+1) 不能寫(xiě)成不能寫(xiě)成 *ad (ac,ac+1)dxexdxxsixdxxx + +- -20311210 33x2 six x f x dxab( ) 我們希望我們希望 integrate 能計(jì)算任意函數(shù)能計(jì)算任意函數(shù) f ,在任意區(qū)間,在任意區(qū)間 a,b 上的定積分。上的定積
7、分。而具體計(jì)算那個(gè)函數(shù)的積分由調(diào)用而具體計(jì)算那個(gè)函數(shù)的積分由調(diào)用 integrate 時(shí)確定。顯然時(shí)確定。顯然 f 作為作為integrate 的一個(gè)參數(shù)比較合適。調(diào)用的一個(gè)參數(shù)比較合適。調(diào)用 inegrate 的函數(shù)調(diào)用可以寫(xiě)成:的函數(shù)調(diào)用可以寫(xiě)成: integrate(g,a,b)其中其中 g 為被積分函數(shù)。這就要求函數(shù)為被積分函數(shù)。這就要求函數(shù) integrate 帶有函數(shù)參數(shù),帶有函數(shù)參數(shù),integrate 的的函數(shù)定義說(shuō)明符可以寫(xiě)成:函數(shù)定義說(shuō)明符可以寫(xiě)成: float integrate( float (*f)(float) ,float a, float b ) 函數(shù)作參數(shù)時(shí),
8、在形式參數(shù)表中應(yīng)列出作參數(shù)函數(shù)的函數(shù)原型。目的是函數(shù)作參數(shù)時(shí),在形式參數(shù)表中應(yīng)列出作參數(shù)函數(shù)的函數(shù)原型。目的是為了說(shuō)明該形式參數(shù)函數(shù)的特性。為了說(shuō)明該形式參數(shù)函數(shù)的特性。 Yf aYf ahYf ahYf bn0122= = =+ += =+ += =( ),(),(),( )LLSf x dxhYYYYYYabnn= = + + + + + + + - -( )() /)012312LLxex+ +323x x sin 其中,實(shí)在參數(shù)其中,實(shí)在參數(shù) 0、1 ; -1.0、1.0 ; 0.0、2.0分別表示積分區(qū)間分別表示積分區(qū)間 0、1 ,-1.0、1.0 ,0.0、2.0100為把積分區(qū)間
9、等分成為把積分區(qū)間等分成100份;份; cube、sin2、r 分別為被積函數(shù)的函數(shù)標(biāo)識(shí)符。分別為被積函數(shù)的函數(shù)標(biāo)識(shí)符。被積函數(shù)被積函數(shù) cube,sin2,r 都是一元函數(shù),都是一元函數(shù),其參數(shù)是其參數(shù)是 float 型的,結(jié)果類型也是型的,結(jié)果類型也是 float 的。的。被積函數(shù)被積函數(shù) cube,sin2,r 的函數(shù)定義說(shuō)明的函數(shù)定義說(shuō)明符與符與 integrate 形式參數(shù)表中的函數(shù)參數(shù)說(shuō)明形式參數(shù)表中的函數(shù)參數(shù)說(shuō)明 float (*f)(float)是一致的。是一致的。運(yùn)行結(jié)果演示運(yùn)行結(jié)果演示 函數(shù)函數(shù) bubsort 有三個(gè)形式參數(shù),有三個(gè)形式參數(shù), s 是欲排序的整數(shù)數(shù)組,是欲
10、排序的整數(shù)數(shù)組, Size 是是 s 數(shù)組的尺寸數(shù)組的尺寸, P 是一個(gè)是一個(gè)bool型函數(shù),調(diào)用型函數(shù),調(diào)用 bubsor t時(shí)以時(shí)以 ascending 函數(shù)或者以函數(shù)或者以 descending函數(shù)作實(shí)在參數(shù)對(duì)應(yīng)它,具體指明是按遞增排序還是按遞減排序。函數(shù)作實(shí)在參數(shù)對(duì)應(yīng)它,具體指明是按遞增排序還是按遞減排序。運(yùn)行結(jié)果演示運(yùn)行結(jié)果演示程序運(yùn)行結(jié)果為:程序運(yùn)行結(jié)果為:The sum of sin for 0.1 to 1.0 is 5.01388The sum of cos for 0.5 to 3.0 is -2.44645 函數(shù)函數(shù) sum( ) 的第一個(gè)參數(shù)為函數(shù)指針,該指針指向的是帶
11、有一個(gè)的第一個(gè)參數(shù)為函數(shù)指針,該指針指向的是帶有一個(gè)double型參數(shù)并返回型參數(shù)并返回double類型數(shù)據(jù)的函數(shù)。而在頭文件類型數(shù)據(jù)的函數(shù)。而在頭文件 math.h 中定義中定義的函數(shù)的函數(shù) sin( ) 與與 cos( ) 正是這樣的函數(shù)。正是這樣的函數(shù)。 主程序中,分別以主程序中,分別以 sin( ) 與與 cos( ) 作實(shí)在參數(shù)對(duì)應(yīng)作實(shí)在參數(shù)對(duì)應(yīng) sum 函數(shù)的函數(shù)指針函數(shù)的函數(shù)指針參數(shù)參數(shù) func。達(dá)到函數(shù)。達(dá)到函數(shù) sum 分別求分別求 sin 和和 cos 之和。之和。運(yùn)行結(jié)果演示運(yùn)行結(jié)果演示13.1.3 計(jì)算算術(shù)表達(dá)式的值計(jì)算算術(shù)表達(dá)式的值間接遞歸間接遞歸n前邊講的遞歸程序
12、,都是在函數(shù)前邊講的遞歸程序,都是在函數(shù)本身的函數(shù)體內(nèi)調(diào)用自己。本身的函數(shù)體內(nèi)調(diào)用自己。n而遞歸的動(dòng)態(tài)含義是在調(diào)用函數(shù)而遞歸的動(dòng)態(tài)含義是在調(diào)用函數(shù)進(jìn)入函數(shù)后,沒(méi)有退出之前,又進(jìn)入函數(shù)后,沒(méi)有退出之前,又再一次調(diào)用本函數(shù)。再一次調(diào)用本函數(shù)。n可能存在如圖所示情況,這顯然可能存在如圖所示情況,這顯然也是進(jìn)入也是進(jìn)入P后,沒(méi)退出后,沒(méi)退出P之前又再之前又再一次調(diào)用一次調(diào)用P ,這種情況稱,這種情況稱“間接間接遞歸遞歸”。n相應(yīng)前邊講的相應(yīng)前邊講的“在在P中直接調(diào)用中直接調(diào)用P”稱稱“直接遞歸直接遞歸”。 調(diào)用函數(shù)調(diào)用函數(shù) 調(diào)用調(diào)用 1 1 調(diào)用調(diào)用 2 . . n-1 調(diào)用調(diào)用 n n 調(diào)用調(diào)用 【
13、例【例13.5】編程序,從終端讀入表達(dá)式,計(jì)算表達(dá)式的值。表達(dá)】編程序,從終端讀入表達(dá)式,計(jì)算表達(dá)式的值。表達(dá)式遵守先乘除后加減的運(yùn)算規(guī)則,并且允許有括號(hào)。它的構(gòu)成規(guī)則是:式遵守先乘除后加減的運(yùn)算規(guī)則,并且允許有括號(hào)。它的構(gòu)成規(guī)則是: 表達(dá)式是表達(dá)式是“加法項(xiàng)加法項(xiàng)”;或者;或者“由一個(gè)加法項(xiàng)加上一個(gè)表達(dá)式由一個(gè)加法項(xiàng)加上一個(gè)表達(dá)式”構(gòu)構(gòu)成;或者成;或者“由一個(gè)加法項(xiàng)減去一個(gè)表達(dá)式由一個(gè)加法項(xiàng)減去一個(gè)表達(dá)式”構(gòu)成。構(gòu)成。 加法項(xiàng)是加法項(xiàng)是“乘法因子乘法因子”;或者;或者“由一個(gè)乘法因子乘以一個(gè)加法項(xiàng)由一個(gè)乘法因子乘以一個(gè)加法項(xiàng)”構(gòu)成;或者構(gòu)成;或者“由一個(gè)乘法因子除以一個(gè)加法項(xiàng)由一個(gè)乘法因子除
14、以一個(gè)加法項(xiàng)”構(gòu)成。構(gòu)成。 乘法因子是一個(gè)乘法因子是一個(gè)“數(shù)字?jǐn)?shù)字”;或者是;或者是 “由一對(duì)括號(hào)括起來(lái)的表達(dá)式由一對(duì)括號(hào)括起來(lái)的表達(dá)式”構(gòu)成。構(gòu)成。 若用若用E、T、F分別表示表達(dá)式、加法項(xiàng)、乘法因子,則可以形式分別表示表達(dá)式、加法項(xiàng)、乘法因子,則可以形式化的表示表達(dá)式的構(gòu)成如下:化的表示表達(dá)式的構(gòu)成如下: E : T+E 或者或者 T-E 或者或者 T T : F*T 或者或者 F/T 或者或者 F F : 數(shù)字?jǐn)?shù)字 或者或者 (E) 解:把每個(gè)語(yǔ)法單位的處理編成一個(gè)函數(shù),全局量解:把每個(gè)語(yǔ)法單位的處理編成一個(gè)函數(shù),全局量w放當(dāng)放當(dāng)前讀入字符,得:前讀入字符,得:e(*ve) 返回返回t(
15、&v1)w=w1=we(&v2)*ve=v1w1=+*ve=v1+v2*ve=v1-v2 t(*vt) 返回返回f(&u1)w = * /w1=wt(&u2)w1=*vt=u1*u2*vt=u1/u2*vt=u1 f(*vf) 返回返回w=(*vf=we(vf)開(kāi)始開(kāi)始 結(jié)束結(jié)束印印 ve(&v)主函數(shù)在開(kāi)始應(yīng)該首先讀入一個(gè)字符;主函數(shù)在開(kāi)始應(yīng)該首先讀入一個(gè)字符;E 的處理函數(shù),也應(yīng)該加上讀入字符部分;的處理函數(shù),也應(yīng)該加上讀入字符部分;與與 E 一樣,相應(yīng)一樣,相應(yīng) T 的處理函數(shù),也應(yīng)該加上讀入字符部分。的處理函數(shù),也應(yīng)該加上讀入字符部分。最后,最后
16、,F(xiàn) 的處理:的處理: 在處理帶括號(hào)的在處理帶括號(hào)的 E 之前,應(yīng)該讀入之前,應(yīng)該讀入 E 的第一個(gè)字符;的第一個(gè)字符; 在處理完在處理完 E 之后,已經(jīng)讀入右括號(hào),但是還應(yīng)該把后繼符讀入之后,已經(jīng)讀入右括號(hào),但是還應(yīng)該把后繼符讀入 在處理數(shù)字時(shí),處理完數(shù)字后,還應(yīng)該讀入后繼符號(hào)。在處理數(shù)字時(shí),處理完數(shù)字后,還應(yīng)該讀入后繼符號(hào)。讀讀(w)開(kāi)始開(kāi)始結(jié)束結(jié)束印印 ve(&v)e(*ve) 返回返回t(&v1)w=w1=we(&v2)*ve=v1w1=+*ve=v1+v2*ve=v1-v2讀讀(w) t(*vt) 返回返回f(&u1)w = * /w1=wt(&
17、;u2)w1=*vt=u1*u2*vt=u1/u2*vt=u1讀讀(w) f(*vf) 返回返回w=(*vf=we(vf)讀讀(w)讀讀(w)讀讀(w)讀讀(w) 開(kāi)始開(kāi)始 結(jié)束結(jié)束印印 ve(&v)e(*ve) 返回返回w1=we(&v2)*ve=v1-v2*ve=v1w=w1=+*ve=v1+v2t(&v1)讀讀(w)t(*vt)返回返回w = * /w1=w讀讀(w)t(&u2)*vt=u1w1=*vt=u1*u2*vt=u1/u2f(&u1)f(*vf) 返回返回w=(*vf=w讀讀(w)讀讀(w)e(vf)讀讀(w)char w ; /* 2
18、*/ float v ; /* 3 */ void t( float *vt ); /* 4 */ void f( float *vf ); /* 5 */ void e( float *ve ) /* 6 */ float v2 , v1 ; /* 7 */ char w1 ; /* 8 */ t(&v1); /* 9 */ if ( w=+) | ( w=-) ) /* 10 */ w1=w ; /* 11 */ scanf( “%c”,&w); /* 12 */ e(&v2); /* 13 */ if (w1=+) /* 14 */ *ve=v1+v2 ; /*
19、15 */ else /* 16 */ *ve=v1-v2 ; /* 17 */ /* 18 */ else *ve=v1 ; /* 19 */ /* 20 */ void t( float *vt ) /* 21 */ float u1,u2 ; /* 22 */ char w1 ; /* 23 */ f(&u1); /* 24 */ if ( (w=*)|(w=/) ) /* 25 */ w1=w; /* 26 */ scanf( “%c”,&w); /* 27 */ t(&u2); /* 28 */ if (w1=*) /* 29 */ *vt=u1*u2; /*
20、 30 */ else /* 31 */ *vt=u1/u2 ; /* 32 */ /* 33 */ else *vt=u1 /* 34 */ /* 35 */ void f( float *vf ) /* 36 */ if ( w=( ) /* 37 */ scanf( “%c”,&w); /* 38 */ e(vf); /* 39 */ scanf( “%c”,&w); /* 40 */ else /* 41 */ *vf=(int)w -(int)0; /* 42 */ scanf( “%c”,&w); /* 43 */ /* 44 */ /* 45 */ int
21、 main(void) /* 46 */ scanf( “%c”,&w); /* 47 */ e(&v); /* 48 */ printf(“n = %f n”, v ) ; /* 49 */ /* 50 */運(yùn)行結(jié)果演示運(yùn)行結(jié)果演示13.1.4 函數(shù)副作用函數(shù)副作用 所謂函數(shù)副作用是指,當(dāng)調(diào)用函數(shù)時(shí),被調(diào)用函數(shù)除了返回函數(shù)值之外,所謂函數(shù)副作用是指,當(dāng)調(diào)用函數(shù)時(shí),被調(diào)用函數(shù)除了返回函數(shù)值之外,還對(duì)主調(diào)用函數(shù)產(chǎn)生附加的影響。例如,調(diào)用函數(shù)時(shí)在被調(diào)用函數(shù)內(nèi)部還對(duì)主調(diào)用函數(shù)產(chǎn)生附加的影響。例如,調(diào)用函數(shù)時(shí)在被調(diào)用函數(shù)內(nèi)部l修改全局量的值;修改全局量的值;l修改主調(diào)用函數(shù)中聲明的變量
22、的值(一般通過(guò)指針參數(shù)實(shí)現(xiàn))。修改主調(diào)用函數(shù)中聲明的變量的值(一般通過(guò)指針參數(shù)實(shí)現(xiàn))。函數(shù)副作用會(huì)給程序設(shè)計(jì)帶來(lái)不必要的麻煩,給程序帶來(lái)十分難以查找的錯(cuò)誤,函數(shù)副作用會(huì)給程序設(shè)計(jì)帶來(lái)不必要的麻煩,給程序帶來(lái)十分難以查找的錯(cuò)誤,并且降低程序的可讀性。并且降低程序的可讀性。 第三章介紹表達(dá)式值的計(jì)算時(shí)曾經(jīng)舉過(guò)一個(gè)例子,由于雙目運(yùn)算的兩個(gè)運(yùn)第三章介紹表達(dá)式值的計(jì)算時(shí)曾經(jīng)舉過(guò)一個(gè)例子,由于雙目運(yùn)算的兩個(gè)運(yùn)算分量的計(jì)算次序不同,而帶來(lái)運(yùn)算結(jié)果不同,就是由函數(shù)副作用引起的。算分量的計(jì)算次序不同,而帶來(lái)運(yùn)算結(jié)果不同,就是由函數(shù)副作用引起的。 對(duì)函數(shù)副作用的看法與對(duì)對(duì)函數(shù)副作用的看法與對(duì)GOTO語(yǔ)句的看法一樣
23、,在程序設(shè)計(jì)語(yǔ)言界一直語(yǔ)句的看法一樣,在程序設(shè)計(jì)語(yǔ)言界一直有分歧,有人主張保留,有人主張取消。我們認(rèn)為,可以保留函數(shù)副作用,但有分歧,有人主張保留,有人主張取消。我們認(rèn)為,可以保留函數(shù)副作用,但是應(yīng)該限制程序員盡量不要使用函數(shù)副作用。由于函數(shù)副作用的影響:是應(yīng)該限制程序員盡量不要使用函數(shù)副作用。由于函數(shù)副作用的影響:l會(huì)使雙目運(yùn)算的結(jié)果依賴于兩個(gè)運(yùn)算分量的計(jì)算次序;會(huì)使雙目運(yùn)算的結(jié)果依賴于兩個(gè)運(yùn)算分量的計(jì)算次序;l還可能使某些在數(shù)學(xué)上明顯成立的事實(shí),在程序中就不一定成立。還可能使某些在數(shù)學(xué)上明顯成立的事實(shí),在程序中就不一定成立。 例如,在數(shù)學(xué)上乘法符合交換律,例如,在數(shù)學(xué)上乘法符合交換律, a
24、*f(x) 與與 f(x)*a顯然相等。但是在程序中,若函數(shù)顯然相等。但是在程序中,若函數(shù)f改變?nèi)至扛淖內(nèi)至縜的值,則上述交換律就不的值,則上述交換律就不成立。成立。 設(shè)有函數(shù):設(shè)有函數(shù): float f(float u) a = a*2; return 2*u 假定,計(jì)算時(shí)開(kāi)始假定,計(jì)算時(shí)開(kāi)始 a=3 , x=5 ; 3a :5x :當(dāng)雙目運(yùn)算符的運(yùn)算對(duì)象從左向右計(jì)算時(shí),計(jì)算:當(dāng)雙目運(yùn)算符的運(yùn)算對(duì)象從左向右計(jì)算時(shí),計(jì)算: a * f(x)第一步,求運(yùn)算分量第一步,求運(yùn)算分量 a 的值,為的值,為 3 ;第二步,求運(yùn)算分量第二步,求運(yùn)算分量 f(x) 的值,調(diào)用函數(shù)的值,調(diào)用函數(shù) f,u
25、取取 x 值為值為 5 ,進(jìn)入,進(jìn)入 f 執(zhí)行執(zhí)行 a=a*2 a 得得 6,再執(zhí)行,再執(zhí)行 return 2*u 得函數(shù)值為得函數(shù)值為10,返回;,返回;第三步,計(jì)算表達(dá)式值為第三步,計(jì)算表達(dá)式值為 3*10 得得 30 。第一運(yùn)算分量第一運(yùn)算分量 第二運(yùn)算分量第二運(yùn)算分量* *35u :610而在同樣條件下計(jì)算:而在同樣條件下計(jì)算: f(x) * a106第一步,求運(yùn)算分量第一步,求運(yùn)算分量 f(x) 的值,調(diào)用函數(shù)的值,調(diào)用函數(shù) f,u 取取 x 值為值為 5,進(jìn)入,進(jìn)入f執(zhí)行執(zhí)行 a=a * 2 a 得得 6 ,再執(zhí)行,再執(zhí)行 return 2 * u 得函數(shù)值為得函數(shù)值為 10 ,返
26、回;,返回;第二步,求運(yùn)算分量第二步,求運(yùn)算分量a的值,為的值,為6 ;第三步,計(jì)算表達(dá)式值為第三步,計(jì)算表達(dá)式值為10*6得得60 。 計(jì)算結(jié)果顯然不一樣,使乘法交換率不成立。這就是因?yàn)橛?jì)算結(jié)果顯然不一樣,使乘法交換率不成立。這就是因?yàn)楦弊饔玫挠绊懺斐傻?,因?yàn)樵诤瘮?shù)副作用的影響造成的,因?yàn)樵诤瘮?shù) f 內(nèi)改變了全局量?jī)?nèi)改變了全局量 a 的值。的值。希望讀者在編程序時(shí),盡量不要使用帶副作用的函數(shù)希望讀者在編程序時(shí),盡量不要使用帶副作用的函數(shù)13.2 運(yùn)算運(yùn)算 C語(yǔ)言的運(yùn)算符非常豐富,第三章表語(yǔ)言的運(yùn)算符非常豐富,第三章表3.1列列出了所有出了所有C運(yùn)算符,包括運(yùn)算符的記號(hào)、運(yùn)算、運(yùn)算符,包括運(yùn)算
27、符的記號(hào)、運(yùn)算、類別、優(yōu)先級(jí)、結(jié)合關(guān)系等。常用的運(yùn)算符及其類別、優(yōu)先級(jí)、結(jié)合關(guān)系等。常用的運(yùn)算符及其意義我們已經(jīng)在前面相關(guān)章節(jié)介紹過(guò),本節(jié)介紹意義我們已經(jīng)在前面相關(guān)章節(jié)介紹過(guò),本節(jié)介紹那些那些C獨(dú)有的特色。獨(dú)有的特色。13.2.1 賦值運(yùn)算賦值運(yùn)算 “=”可以和一些雙目運(yùn)算符結(jié)合,形成新的附加運(yùn)算意義的賦值可以和一些雙目運(yùn)算符結(jié)合,形成新的附加運(yùn)算意義的賦值運(yùn)算符,稱為復(fù)合賦值運(yùn)算符。運(yùn)算符,稱為復(fù)合賦值運(yùn)算符。 復(fù)合賦值運(yùn)算符包括:復(fù)合賦值運(yùn)算符包括: += = *= /= %= = &= = |= 使用這些賦值運(yùn)算符的格式是:使用這些賦值運(yùn)算符的格式是: 操作數(shù)操作數(shù)1 賦值運(yùn)算符
28、賦值運(yùn)算符 操作數(shù)操作數(shù)2復(fù)合賦值運(yùn)算復(fù)合賦值運(yùn)算 a op= b與簡(jiǎn)單賦值運(yùn)算與簡(jiǎn)單賦值運(yùn)算 a = a op b 等價(jià)。等價(jià)。 例如,設(shè)例如,設(shè) x=3 則則 x += x*5 ; 相當(dāng)于相當(dāng)于 x = x+(x*5) ; 結(jié)果結(jié)果 x 中為整數(shù)中為整數(shù) 18 。13.2.2 順序表達(dá)式順序表達(dá)式 用逗號(hào)運(yùn)算符用逗號(hào)運(yùn)算符 , 分隔開(kāi)的若干個(gè)表達(dá)式稱為分隔開(kāi)的若干個(gè)表達(dá)式稱為逗號(hào)表達(dá)式逗號(hào)表達(dá)式,又稱為,又稱為順序表達(dá)式順序表達(dá)式。逗號(hào)表達(dá)式按行文。逗號(hào)表達(dá)式按行文順序從左向右計(jì)算各個(gè)子表達(dá)式的值。順序從左向右計(jì)算各個(gè)子表達(dá)式的值。l 表達(dá)式的結(jié)果類型是最右端表達(dá)式的類型,表達(dá)式的結(jié)果類型
29、是最右端表達(dá)式的類型,l 表達(dá)式的結(jié)果值是最右端表達(dá)式的值。表達(dá)式的結(jié)果值是最右端表達(dá)式的值。例如例如 : j = ( x=0.5 , y=10 ,15+x ,y=(int)x+y*2 ) 將順序的:將順序的:1.先計(jì)算先計(jì)算 “x=0.5” 給給 x 賦值賦值 0.5 ,得,得 float 類型的類型的 0.5;2.再計(jì)算再計(jì)算 “y=10” 給給 y 賦值賦值 10 ,得,得 int 類型的類型的 10 ;3.再計(jì)算再計(jì)算 “15+x” ,得,得 float 類型的類型的 15.5 ;4.再計(jì)算再計(jì)算 “y=(int)x+y*2” 給給 y 賦值賦值 20 ,得,得 int 類型的類型的
30、20 ;最終括號(hào)內(nèi)表達(dá)式的結(jié)果值是最終括號(hào)內(nèi)表達(dá)式的結(jié)果值是 20 ,結(jié)果類型是整數(shù)類型,結(jié)果類型是整數(shù)類型,j 被賦值被賦值 20 。13.2.3 條件表達(dá)式條件表達(dá)式 C條件表達(dá)式格式是:條件表達(dá)式格式是: 操作數(shù)操作數(shù)1 ? 操作數(shù)操作數(shù)2 : 操作數(shù)操作數(shù)3 該表達(dá)式含有兩個(gè)運(yùn)算符該表達(dá)式含有兩個(gè)運(yùn)算符 “ ?” 和和 “ :” 、三個(gè)操作數(shù)。條件表達(dá)、三個(gè)操作數(shù)。條件表達(dá)式是三元表達(dá)式,運(yùn)算符式是三元表達(dá)式,運(yùn)算符 “ ?” 和和 “ :” 合并使用稱為三元運(yùn)算符。合并使用稱為三元運(yùn)算符。 條件表達(dá)式的計(jì)算步驟是:條件表達(dá)式的計(jì)算步驟是:1. 計(jì)算計(jì)算“操作數(shù)操作數(shù)1 ”;2. 若若
31、“操作數(shù)操作數(shù)1”的值為的值為true,則計(jì)算,則計(jì)算“操作數(shù)操作數(shù)2” ,表達(dá)式的值為,表達(dá)式的值為“操作數(shù)操作數(shù)2”的值;的值;3. 否則否則“操作數(shù)操作數(shù)1”的值為的值為false ,計(jì)算計(jì)算“操作數(shù)操作數(shù)3” ,表達(dá)式的值為表達(dá)式的值為“操操作數(shù)作數(shù)3”的值。的值。 條件表達(dá)式是條件表達(dá)式是右結(jié)合右結(jié)合的,優(yōu)先級(jí)別高于賦值運(yùn)算符,低于二元操作符。的,優(yōu)先級(jí)別高于賦值運(yùn)算符,低于二元操作符。 表達(dá)式語(yǔ)句表達(dá)式語(yǔ)句 x = a ? b : c ;相當(dāng)于如下條件語(yǔ)句:相當(dāng)于如下條件語(yǔ)句: if ( a != 0 ) x = b; else x = c;由于右結(jié)合的特性,表達(dá)式由于右結(jié)合的特性
32、,表達(dá)式 u=ab?x:cd?y:z相當(dāng)于相當(dāng)于 u=ab?x:(cd?y:z)用條件語(yǔ)句表示如下:用條件語(yǔ)句表示如下: if (ab) u=x; else if (cd) u=y; else u=z;13.2.4 位運(yùn)算位運(yùn)算 C可以直接針對(duì)二進(jìn)制位進(jìn)行操作,這使得用它描述系統(tǒng)程序十可以直接針對(duì)二進(jìn)制位進(jìn)行操作,這使得用它描述系統(tǒng)程序十分方便。位運(yùn)算的所有操作數(shù)必須為整數(shù)類型,下表列出分方便。位運(yùn)算的所有操作數(shù)必須為整數(shù)類型,下表列出 C 的位運(yùn)算的位運(yùn)算符,下邊分別介紹它們定義的運(yùn)算。符,下邊分別介紹它們定義的運(yùn)算。記號(hào)記號(hào)運(yùn)算符運(yùn)算符類別類別結(jié)合關(guān)系結(jié)合關(guān)系優(yōu)先級(jí)優(yōu)先級(jí)按位取反按位取反一
33、元一元從右到左從右到左15左移、右移左移、右移二元二元從左到右從左到右11&按位與按位與8按位異或按位異或7|按位或按位或6按位取反按位取反: 按位取反運(yùn)算的格式是:按位取反運(yùn)算的格式是: 操作數(shù)操作數(shù) 該運(yùn)算該運(yùn)算“”對(duì)操作數(shù)結(jié)果值的二進(jìn)制表示的每一位取反碼。對(duì)操作數(shù)結(jié)果值的二進(jìn)制表示的每一位取反碼?!纠纠?3.6】如果】如果 X 是一個(gè)是一個(gè) int 類型的整數(shù),十六進(jìn)制表示為類型的整數(shù),十六進(jìn)制表示為 0XF0F0它的二進(jìn)制表示為它的二進(jìn)制表示為 111100001111000X 結(jié)果的二進(jìn)制表示為結(jié)果的二進(jìn)制表示為 0000111100001111十六進(jìn)制的表示為十六進(jìn)制的表
34、示為 OX0F0F位移運(yùn)算位移運(yùn)算: 位移運(yùn)算的格式是:位移運(yùn)算的格式是: 操作數(shù)操作數(shù)1 位移運(yùn)算符位移運(yùn)算符 操作數(shù)操作數(shù)2 l C有兩個(gè)位移運(yùn)算符有兩個(gè)位移運(yùn)算符 “” 。其中。其中 為右移;為右移; 操作數(shù)操作數(shù)1 是要進(jìn)行位移整數(shù);是要進(jìn)行位移整數(shù); 操作數(shù)操作數(shù)2 指定移動(dòng)的位數(shù)。指定移動(dòng)的位數(shù)。l 位移運(yùn)算的操作是:位移運(yùn)算的操作是: 按運(yùn)算符的要求把按運(yùn)算符的要求把 “操作數(shù)操作數(shù)1” 移動(dòng)移動(dòng) “操作數(shù)操作數(shù)2” 指定的位數(shù)。指定的位數(shù)。在進(jìn)行移位運(yùn)算過(guò)程中,移到邊界之外的多余位放棄扔掉;另一側(cè)在進(jìn)行移位運(yùn)算過(guò)程中,移到邊界之外的多余位放棄扔掉;另一側(cè)產(chǎn)生的缺位以產(chǎn)生的缺位以
35、“0”補(bǔ)足。補(bǔ)足。X5的結(jié)果的結(jié)果:0110100111100000(X2:0001101001111000(x2X:0001101101001111X5:0110100111100000X 5 【例【例13.7】設(shè)變量】設(shè)變量 x 值為值為 0 x1B4F ,計(jì)算表達(dá)式,計(jì)算表達(dá)式“x 2”的值。的值。 解:首先解:首先 x 左移左移 5 位,所得結(jié)果為位,所得結(jié)果為 0 x69E0,如上圖所示。然后再對(duì)所,如上圖所示。然后再對(duì)所得結(jié)果向右移得結(jié)果向右移 2 位,結(jié)果為位,結(jié)果為 0 x1A78 ,如下圖所示。,如下圖所示。舍掉舍掉補(bǔ)補(bǔ)0舍掉舍掉補(bǔ)補(bǔ)0按位邏輯運(yùn)算按位邏輯運(yùn)算:按位邏輯運(yùn)算是
36、雙目運(yùn)算,它的格式是:按位邏輯運(yùn)算是雙目運(yùn)算,它的格式是: 操作數(shù)操作數(shù)1 運(yùn)算符運(yùn)算符 操作數(shù)操作數(shù)2 具體操作是:具體操作是:l 首先將兩個(gè)操作數(shù)都轉(zhuǎn)換成二進(jìn)制數(shù);首先將兩個(gè)操作數(shù)都轉(zhuǎn)換成二進(jìn)制數(shù);l 然后根據(jù)運(yùn)算符的要求以二進(jìn)制位為單位,按位對(duì)其進(jìn)行然后根據(jù)運(yùn)算符的要求以二進(jìn)制位為單位,按位對(duì)其進(jìn)行 位與位與 、位異或、位異或 、 位或位或 運(yùn)算。運(yùn)算。 位邏輯運(yùn)算符以及它定義的操作位邏輯運(yùn)算符以及它定義的操作Xyx & y(按位與)(按位與)x y(按位異或)(按位異或)x | y(按位或)(按位或)00000010111001111101 【例【例13.8】設(shè)整數(shù)】設(shè)整數(shù)x值
37、為值為0 x1B4F,y值為值為0 x1A78,它們,它們按位邏輯運(yùn)算結(jié)果如圖按位邏輯運(yùn)算結(jié)果如圖.x:00011011010011110 x1B4F x:00011010011110000X1A78 x&y00011010010010000X1A48 xy00000001001101110X0137 x|y00011011011111110X1B7F x與與y的按位運(yùn)算的按位運(yùn)算13.3 語(yǔ)句語(yǔ)句 本節(jié)介紹三個(gè)語(yǔ)句本節(jié)介紹三個(gè)語(yǔ)句break 、continue 和和 for ,以及以及goto語(yǔ)句和標(biāo)號(hào)語(yǔ)句和標(biāo)號(hào) 。 break 和和 continue 語(yǔ)句是受限制的語(yǔ)句是受限制的
38、goto 語(yǔ)句,用來(lái)語(yǔ)句,用來(lái)改變循環(huán)或分支語(yǔ)句的控制流程。在達(dá)到相同目的的情況改變循環(huán)或分支語(yǔ)句的控制流程。在達(dá)到相同目的的情況下,使用下,使用 break和和 continue 語(yǔ)句比起語(yǔ)句比起 goto 語(yǔ)句具有更好語(yǔ)句具有更好的風(fēng)格和結(jié)構(gòu)。但與全部用標(biāo)準(zhǔn)控制流程寫(xiě)出的程序相比,的風(fēng)格和結(jié)構(gòu)。但與全部用標(biāo)準(zhǔn)控制流程寫(xiě)出的程序相比,break 和和 continue 語(yǔ)句的結(jié)構(gòu)要差。語(yǔ)句的結(jié)構(gòu)要差。 for循環(huán)語(yǔ)句讀者已經(jīng)很熟悉,本節(jié)延伸它。循環(huán)語(yǔ)句讀者已經(jīng)很熟悉,本節(jié)延伸它。13.3.1 break 執(zhí)行執(zhí)行break 語(yǔ)句使包含它的最內(nèi)語(yǔ)句使包含它的最內(nèi)層層while、do、for、s
39、witch語(yǔ)句終止語(yǔ)句終止執(zhí)行,立即轉(zhuǎn)移到所終止語(yǔ)句之外的執(zhí)行,立即轉(zhuǎn)移到所終止語(yǔ)句之外的程序點(diǎn)。在沒(méi)有循環(huán)或程序點(diǎn)。在沒(méi)有循環(huán)或switch語(yǔ)句的語(yǔ)句的場(chǎng)合使用場(chǎng)合使用break是錯(cuò)誤的。是錯(cuò)誤的?!纠纠?3.9】迭代中使用】迭代中使用breakint x = 0;while (x 10) printf(Looping ); x;if (x = 5) break; else 其他代碼其他代碼后續(xù)代碼后續(xù)代碼int x=0 ;后續(xù)代碼后續(xù)代碼x10Fprintf(Looping );x + ;x=5其他代碼其他代碼T 在該程序片段中,循環(huán)將在在該程序片段中,循環(huán)將在x=5時(shí)停止,時(shí)停止,去執(zhí)
40、行后續(xù)代碼,盡管循環(huán)控制當(dāng)去執(zhí)行后續(xù)代碼,盡管循環(huán)控制當(dāng) x10 時(shí)都執(zhí)行循環(huán)體。用流程圖來(lái)表示該程序時(shí)都執(zhí)行循環(huán)體。用流程圖來(lái)表示該程序片段如上圖。片段如上圖。運(yùn)行結(jié)果演示運(yùn)行結(jié)果演示switch (x) case 1: printf(“ 1 ”); case 2: printf(“ 2 ”); case 3: printf(“ 3 ”); default: printf(“no_meaning”);switch (x) case 1: printf(“ 1 ”); break; case 2: printf(“ 2 ”); break; case 3: printf(“ 3 ”); bre
41、ak; default: printf(“no_meaning”); switch 語(yǔ)句中使用語(yǔ)句中使用 break 之一之一 switch 語(yǔ)句中使用語(yǔ)句中使用 break 之二之二 注意注意break在在switch語(yǔ)句中的作用。如下兩段代碼執(zhí)行的結(jié)果是不語(yǔ)句中的作用。如下兩段代碼執(zhí)行的結(jié)果是不一樣的,請(qǐng)認(rèn)真體會(huì)。一樣的,請(qǐng)認(rèn)真體會(huì)。1) 在左端程序中,當(dāng)在左端程序中,當(dāng)x=2時(shí),打印結(jié)果為時(shí),打印結(jié)果為: 2 3 no_meaning 因?yàn)橐驗(yàn)?switch 語(yǔ)句將控制轉(zhuǎn)移到語(yǔ)句將控制轉(zhuǎn)移到 case 2 處打印處打印 2 之后,接著執(zhí)行之后,接著執(zhí)行 printf(“ 3 ”) 和和
42、printf(“ no_meaning ”)。2) 如果需要在每次調(diào)用如果需要在每次調(diào)用 printf 之后都終止之后都終止 switch 體,則要象右端一樣體,則要象右端一樣 使用使用 break 語(yǔ)句。在右端程序片段中,當(dāng)語(yǔ)句。在右端程序片段中,當(dāng) x=2 時(shí),執(zhí)行結(jié)果只打印時(shí),執(zhí)行結(jié)果只打印 出一個(gè)數(shù)字出一個(gè)數(shù)字2。13.3.2 continue continue語(yǔ)句終止它所在的最內(nèi)層語(yǔ)句終止它所在的最內(nèi)層 while 、do 、for 語(yǔ)句循環(huán)體的執(zhí)行,跳過(guò)循環(huán)體余下的代碼,立即轉(zhuǎn)移到循語(yǔ)句循環(huán)體的執(zhí)行,跳過(guò)循環(huán)體余下的代碼,立即轉(zhuǎn)移到循環(huán)體末尾,受其影響的循環(huán)語(yǔ)句從環(huán)體末尾,受其影響
43、的循環(huán)語(yǔ)句從“重新求值循環(huán)測(cè)試點(diǎn)重新求值循環(huán)測(cè)試點(diǎn)”開(kāi)始執(zhí)行(對(duì)開(kāi)始執(zhí)行(對(duì)for語(yǔ)句為語(yǔ)句為“表達(dá)式表達(dá)式3”)。)。 在沒(méi)有循環(huán)迭代語(yǔ)句的場(chǎng)合使用在沒(méi)有循環(huán)迭代語(yǔ)句的場(chǎng)合使用continue語(yǔ)句是錯(cuò)誤的。語(yǔ)句是錯(cuò)誤的?!纠纠?3.10】continue語(yǔ)句示例語(yǔ)句示例for ( x = 0 ; x 5 ; x)if( x = 2) continue; else printf(Looping %dn,x); 該程序不可能打印該程序不可能打印”Looping 2 ” ,程程序執(zhí)行流程如右圖序執(zhí)行流程如右圖.程序執(zhí)行結(jié)果程序執(zhí)行結(jié)果:Looping 0Looping 1Looping 3Loo
44、ping 4int x=0 ;x5Fprintf(Looping %dn,x);x + ;x=2Tcontinue對(duì)循環(huán)的影響對(duì)循環(huán)的影響T運(yùn)行結(jié)果演示運(yùn)行結(jié)果演示13.3.3 for的延伸的延伸 for 語(yǔ)句包括語(yǔ)句包括 for 關(guān)鍵字和括在括號(hào)中的用分號(hào)分開(kāi)的關(guān)鍵字和括在括號(hào)中的用分號(hào)分開(kāi)的 3 個(gè)表達(dá)式,個(gè)表達(dá)式,然后是語(yǔ)句。通常然后是語(yǔ)句。通常:l 第一個(gè)表達(dá)式初始化循環(huán)控制變量第一個(gè)表達(dá)式初始化循環(huán)控制變量;l 第二個(gè)表達(dá)式測(cè)試循環(huán)是否終止第二個(gè)表達(dá)式測(cè)試循環(huán)是否終止;l 第三個(gè)表達(dá)式更新循環(huán)控制變量第三個(gè)表達(dá)式更新循環(huán)控制變量; 如果使用逗號(hào)表達(dá)式,就可以書(shū)寫(xiě)帶有多個(gè)控制變量的如果
45、使用逗號(hào)表達(dá)式,就可以書(shū)寫(xiě)帶有多個(gè)控制變量的for語(yǔ)句語(yǔ)句 【例【例13.11】編函數(shù),判斷兩個(gè)字符串】編函數(shù),判斷兩個(gè)字符串str1和和str2是否相等,相等則是否相等,相等則返回真,否則返回假。返回真,否則返回假。bool str_equal ( const char * str1 , const char *str2 ) char *t1, *t2; for ( t1 = str1 , t2 = str2 ; *t1 & *t2 ; t1+ ,t2+ ) if ( *t1 != *t2 ) return false; return *t1 = *t2;開(kāi)始開(kāi)始X0=初值初值X1
46、= f(X0)X0X1結(jié)束結(jié)束x0=x1TF x0=0.9; x0=0.9; / /* * 1 1 * */ / r1:x1=f(x0); /r1:x1=f(x0); /* * 2 2 * */ / if ( abs(x1-x0)1e-5 )/ if ( abs(x1-x0)1e-5 )/* * 3 3 * */ / gotogoto r2 ; / r2 ; /* * 4 4 * */ / x0=x1; x0=x1; / /* * 5 5 * */ / goto goto r1; r1; / /* * 6 6 * */ / r2: ; r2: ; / /* * 7 7 * */ / 當(dāng)?shù)诋?dāng)?shù)?
47、 3行的條件為行的條件為truetrue時(shí),執(zhí)行第時(shí),執(zhí)行第4 4行的行的gotogoto語(yǔ)句,則轉(zhuǎn)到標(biāo)號(hào)語(yǔ)句,則轉(zhuǎn)到標(biāo)號(hào)r2r2標(biāo)出的第標(biāo)出的第7 7行去執(zhí)行,從而結(jié)束迭代過(guò)程。行去執(zhí)行,從而結(jié)束迭代過(guò)程。 當(dāng)程序執(zhí)行到第當(dāng)程序執(zhí)行到第6 6行的行的gotogoto語(yǔ)句后,則無(wú)條件強(qiáng)制控制轉(zhuǎn)到標(biāo)號(hào)語(yǔ)句后,則無(wú)條件強(qiáng)制控制轉(zhuǎn)到標(biāo)號(hào)r1r1標(biāo)出的標(biāo)出的第第2 2行去執(zhí)行,繼續(xù)進(jìn)行迭代。行去執(zhí)行,繼續(xù)進(jìn)行迭代。運(yùn)行結(jié)果演示運(yùn)行結(jié)果演示13.4 數(shù)據(jù)組織數(shù)據(jù)組織 前述章節(jié)已經(jīng)介紹了各種描述數(shù)據(jù)的手段,本節(jié)介紹較前述章節(jié)已經(jīng)介紹了各種描述數(shù)據(jù)的手段,本節(jié)介紹較深入的數(shù)據(jù)描述手段,包括:多維數(shù)組與指針間
48、的關(guān)系、位深入的數(shù)據(jù)描述手段,包括:多維數(shù)組與指針間的關(guān)系、位段、共用體。段、共用體。13.4.1 13.4.1 多維數(shù)組與指針多維數(shù)組與指針二維數(shù)組元素的地址二維數(shù)組元素的地址二維數(shù)組二維數(shù)組 amn 可以看作是由可以看作是由 m 個(gè)一維數(shù)組個(gè)一維數(shù)組 a0、a1、 、am-2、am-1構(gòu)成。每個(gè)一維數(shù)組有構(gòu)成。每個(gè)一維數(shù)組有 n 個(gè)元素,即每個(gè)個(gè)元素,即每個(gè)ai都是都是由由 n 個(gè)變量個(gè)變量ai0、ai1、 、ain-1組成的數(shù)組。組成的數(shù)組。n如圖所示,按數(shù)組與指針的關(guān)系:如圖所示,按數(shù)組與指針的關(guān)系: 從一維角度看,從一維角度看,a表示一維數(shù)組的首地址,該一維數(shù)組的數(shù)組表示一維數(shù)組的首
49、地址,該一維數(shù)組的數(shù)組元素仍然是數(shù)組;元素仍然是數(shù)組; 每個(gè)每個(gè)ai也都表示一維數(shù)組的首地址,該一維數(shù)組是也都表示一維數(shù)組的首地址,該一維數(shù)組是a數(shù)組的數(shù)組的第第i行,它的各個(gè)元素是行,它的各個(gè)元素是int類型。類型。指針常量指針常量指針常量指針常量這些是數(shù)組這些是數(shù)組a的成分,全部是變量的成分,全部是變量aa0a00a01a0n-1a1a10a11a1 n-1am-2am-20 am-21 am-2 n-1am-1am-10 am-11 am-1 n-1實(shí)際上,不存在實(shí)際上,不存在 a、a0、a1、 、am-1 的存儲(chǔ)空間,的存儲(chǔ)空間,C 系統(tǒng)不給它們分配內(nèi)存,只分配系統(tǒng)不給它們分配內(nèi)存,只
50、分配 m*n 個(gè)變量的內(nèi)存空間。下個(gè)變量的內(nèi)存空間。下圖是一個(gè)示意圖,給出的圖是一個(gè)示意圖,給出的a、a0、a1、 、am-1只是一只是一個(gè)示意,讀者不要誤會(huì)。事實(shí)上個(gè)示意,讀者不要誤會(huì)。事實(shí)上a、a0、a1、a2、 、am-1都是指針常量。都是指針常量。進(jìn)一步,進(jìn)一步,ai是是a數(shù)組第數(shù)組第i個(gè)元素。個(gè)元素。l 如果如果a是一維數(shù)組,則是一維數(shù)組,則ai是一個(gè)變量并且可以有值,是一個(gè)變量并且可以有值,C系統(tǒng)系統(tǒng)會(huì)給它分配相應(yīng)的存儲(chǔ)空間,它實(shí)實(shí)在在占用計(jì)算機(jī)內(nèi)存會(huì)給它分配相應(yīng)的存儲(chǔ)空間,它實(shí)實(shí)在在占用計(jì)算機(jī)內(nèi)存l 如果如果a是二維數(shù)組,則是二維數(shù)組,則ai代表一維數(shù)組,它是一個(gè)指針常代表一維數(shù)
51、組,它是一個(gè)指針常量,量,C系統(tǒng)不給它分配存儲(chǔ)區(qū),它不占用內(nèi)存空間,僅僅是系統(tǒng)不給它分配存儲(chǔ)區(qū),它不占用內(nèi)存空間,僅僅是一個(gè)地址。一個(gè)地址。 am-1 n-1 (int)am-10 (int)am-1 (int*)am-2 n-1 (int)am-20 (int)am-2 (int*)a1 n-1 (int)a10 (int)a1(int*)a0n-1 (int)a00(int)a0(int*)a(int*)指針常量指針常量指針常量指針常量形式形式意義意義a二維數(shù)組名,指向一維數(shù)組二維數(shù)組名,指向一維數(shù)組a0,即第,即第0行首地址。行首地址。相當(dāng)于:相當(dāng)于:&(a0)也可以說(shuō)是數(shù)組也可
52、以說(shuō)是數(shù)組a的首地址,指向的首地址,指向a00。相當(dāng)于:相當(dāng)于:&(a00)a+i第第i行首地址,即行首地址,即ai地址。相當(dāng)于:地址。相當(dāng)于:&(ai)。*a第第0行第行第0列元素首地址,即列元素首地址,即a00地址。地址。相當(dāng)于:相當(dāng)于:a0、*(a+0) 、&( a00)*a+i第第0行第行第i列元素首地址,即列元素首地址,即a0i地址。地址。相當(dāng)于:相當(dāng)于:a0+i、&( a0i)*(a+i)第第i行第行第0列元素地址,即列元素地址,即ai0地址。地址。相當(dāng)于:相當(dāng)于:ai 、&( ai0)*(a+i)+j第第i行第行第j列元素地址,即列元素地址
53、,即aij地址。地址。相當(dāng)于:相當(dāng)于:ai+j、&( aij)*(*(a+i)+j)第第i行第行第j列元素值,即列元素值,即aij值。值。相當(dāng)于:相當(dāng)于:*(ai+j)、aij在該表的各種表示形式中,只有在該表的各種表示形式中,只有&(aij) 、ai+j 、*(a+i)+j 是實(shí)際計(jì)算機(jī)內(nèi)存的物是實(shí)際計(jì)算機(jī)內(nèi)存的物理地址理地址aij 、*(ai+j) 、*(*(a+i)+j) 是它們各自的值,占是它們各自的值,占用計(jì)算機(jī)內(nèi)存;用計(jì)算機(jī)內(nèi)存; 其它形式都是表示地址的指針常量,沒(méi)有被分配其它形式都是表示地址的指針常量,沒(méi)有被分配具體內(nèi)存空間。例如,并不存在具體內(nèi)存空間。例如,并不
54、存在 ai 這樣一個(gè)實(shí)際的這樣一個(gè)實(shí)際的變量,它只是一個(gè)指針常量,運(yùn)算變量,它只是一個(gè)指針常量,運(yùn)算“&(ai)”只是一只是一種地址計(jì)算方式而已,并不是求內(nèi)存實(shí)際存在的變量種地址計(jì)算方式而已,并不是求內(nèi)存實(shí)際存在的變量ai的內(nèi)存地址。的內(nèi)存地址。2. 指向二維數(shù)組元素的指針變量指向二維數(shù)組元素的指針變量n用指針變量表示二維數(shù)組的元素用指針變量表示二維數(shù)組的元素可以直接使用數(shù)組成分類型的指針變量訪可以直接使用數(shù)組成分類型的指針變量訪問(wèn)數(shù)組的成分問(wèn)數(shù)組的成分C數(shù)組的存儲(chǔ)分配方式數(shù)組的存儲(chǔ)分配方式在在C中,按中,按“行優(yōu)先行優(yōu)先”原則分配數(shù)組元素的存儲(chǔ)空原則分配數(shù)組元素的存儲(chǔ)空間。也就是說(shuō),
55、對(duì)數(shù)組間。也就是說(shuō),對(duì)數(shù)組a來(lái)說(shuō),它的各個(gè)成分被分來(lái)說(shuō),它的各個(gè)成分被分配的內(nèi)存空間的順序是:配的內(nèi)存空間的順序是:首先分配第首先分配第0行元素;行元素;然后分配第然后分配第1行元素;行元素; ;最后再分配第最后再分配第n-1行元素,如此等等。行元素,如此等等。每行元素按下標(biāo)值從小到大進(jìn)行。每行元素按下標(biāo)值從小到大進(jìn)行。a成分成分地址地址內(nèi)存內(nèi)存a23A016a22A014a21A012a20A010a13A00Ea12A00Ca11A00Aa10A008a03A006a02A004a01A002a00A000n int a34;n假設(shè)從首地址假設(shè)從首地址A000開(kāi)開(kāi)始分配內(nèi)存空間始分配內(nèi)存空
56、間n每個(gè)元素占每個(gè)元素占2個(gè)字節(jié)個(gè)字節(jié)n數(shù)組數(shù)組a的存儲(chǔ)分配圖的存儲(chǔ)分配圖使用成分類型指針訪問(wèn)兩維數(shù)組元素使用成分類型指針訪問(wèn)兩維數(shù)組元素設(shè)有聲明:設(shè)有聲明:int *aptr, amn ,x ;則可以直接用則可以直接用aptr訪問(wèn)訪問(wèn)a的成分。使用方法是:的成分。使用方法是:n首先使首先使aptr指向指向a的某個(gè)成分的某個(gè)成分aij,n然后以該成分的地址為基點(diǎn),計(jì)算所要訪問(wèn)的數(shù)組成分然后以該成分的地址為基點(diǎn),計(jì)算所要訪問(wèn)的數(shù)組成分的相對(duì)地址,并進(jìn)行訪問(wèn)。最常用的地址基點(diǎn)是的相對(duì)地址,并進(jìn)行訪問(wèn)。最常用的地址基點(diǎn)是a數(shù)組數(shù)組的第一個(gè)成分的第一個(gè)成分a00,例如,例如aptr = &(a
57、00) 由于由于a0指向指向a00,所以這個(gè)運(yùn)算還可以寫(xiě)成,所以這個(gè)運(yùn)算還可以寫(xiě)成aptr = a0 n在上述賦值運(yùn)算的前提下,在上述賦值運(yùn)算的前提下,a的成分的成分auv的地址為的地址為 aptr+u*n+vn若想把若想把a(bǔ)uv的值送入變量的值送入變量x中,可以使用賦值運(yùn)算:中,可以使用賦值運(yùn)算:x = *(aptr+u*n+v) 這個(gè)運(yùn)算等價(jià)于這個(gè)運(yùn)算等價(jià)于 x = auvn若想把某表達(dá)式若想把某表達(dá)式e的值送入數(shù)組的值送入數(shù)組a的成分的成分auv中,可中,可以使用賦值運(yùn)算:以使用賦值運(yùn)算:*(aptr+u*n+v) = e 這個(gè)運(yùn)算等價(jià)于這個(gè)運(yùn)算等價(jià)于auv = ea成分成分地址地址內(nèi)存
58、內(nèi)存a23A016a22A014a21A012a20A010a13A00Ea12A00Ca11A00Aa10A008a03A006a02A004a01A002a00A000n地址計(jì)算公式地址計(jì)算公式“aptr+u*n+v” 基點(diǎn)基點(diǎn) + 行數(shù)行數(shù) * 每行元素個(gè)數(shù)每行元素個(gè)數(shù) + 剩余行的零頭元素個(gè)數(shù)剩余行的零頭元素個(gè)數(shù)n例如,例如,a21的地址是:的地址是: aptr+2*4+1a成分成分地址地址內(nèi)存內(nèi)存a23A016a22A014a21A012a20A010a13A00Ea12A00Ca11A00Aa10A008a03A006a02A004a01A002a00A000若再考慮每個(gè)元素占用的
59、內(nèi)存尺若再考慮每個(gè)元素占用的內(nèi)存尺寸,寸,2*4+1 還要乘以還要乘以 int 類型一類型一個(gè)變量占用內(nèi)存空間數(shù)個(gè)變量占用內(nèi)存空間數(shù) 2 ,最后,最后 a21 對(duì)應(yīng)的具體內(nèi)存地址是:對(duì)應(yīng)的具體內(nèi)存地址是:A000 + (2*4+1)*2為為A012 。當(dāng)然,在用戶程序中只要寫(xiě)地址當(dāng)然,在用戶程序中只要寫(xiě)地址計(jì)算公式計(jì)算公式“aptr+u*n+v”即可即可.沒(méi)有必要也不允許沒(méi)有必要也不允許考慮每個(gè)元素考慮每個(gè)元素占用的存儲(chǔ)空間尺寸。占用的存儲(chǔ)空間尺寸。沒(méi)有必要,也不允許,更不可能沒(méi)有必要,也不允許,更不可能寫(xiě)出具體的地址計(jì)算計(jì)算算式寫(xiě)出具體的地址計(jì)算計(jì)算算式“A000 + (2*4+1)*2”。
60、 例例13.13 編函數(shù),求編函數(shù),求m*n個(gè)元素的給定個(gè)元素的給定float型數(shù)組各個(gè)型數(shù)組各個(gè)元素之乘積。元素之乘積。float arrmul(int m , int n , float *arr) int u, v; float mul; mul = 1; for( u=0; um; u+) for( v=0; vn; v+)mul = mul * (*(arr+u*n+v); return mul ;設(shè)有聲明設(shè)有聲明float a1015;則可以用如下任何一種則可以用如下任何一種形式調(diào)用該函數(shù):形式調(diào)用該函數(shù):arrmul(10,15,&(a00)arrmul(10,15,a0)arrmul(10,15,*a)在本例中,形式參數(shù)是一個(gè)指向在本例中,形式參數(shù)是一個(gè)指向float類型的指針變量,實(shí)在參數(shù)把類型的指針變量,實(shí)在參數(shù)把a(bǔ)數(shù)組第一個(gè)元素?cái)?shù)組第一個(gè)元素a00的指針(地址)送入形式參數(shù)的指針(地址)送入形式參數(shù)arr之中。之中。&(a00)、a0、*a都是都是a00的地址
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025瓷磚買賣合同
- Unit 3 Family Matters Understanding ideas Like Father,Like Son 說(shuō)課稿 -2024-2025學(xué)年高中英語(yǔ)外研版(2019)必修第一冊(cè)
- 2024-2025學(xué)年高中語(yǔ)文 第三課 第4節(jié) 咬文嚼字-消滅錯(cuò)別字說(shuō)課稿2 新人教版選修《語(yǔ)言文字應(yīng)用》
- 21 古詩(shī)三首 第一課時(shí) 說(shuō)課稿-2024-2025學(xué)年統(tǒng)編版語(yǔ)文四年級(jí)上冊(cè)
- 2025購(gòu)銷合同范本
- 企業(yè)派駐合同范例
- 2023八年級(jí)英語(yǔ)下冊(cè) Module 2 Experiences Unit 2 They have seen the Pyramids第三課時(shí)說(shuō)課稿 (新版)外研版
- 體驗(yàn)設(shè)備合同范例
- 醫(yī)院綜合能源合同范本
- 農(nóng)村租地養(yǎng)殖合同范例
- TCCEAS001-2022建設(shè)項(xiàng)目工程總承包計(jì)價(jià)規(guī)范
- 2024.8.1十七個(gè)崗位安全操作規(guī)程手冊(cè)(值得借鑒)
- 中學(xué)生手機(jī)使用管理協(xié)議書(shū)
- 給排水科學(xué)與工程基礎(chǔ)知識(shí)單選題100道及答案解析
- 2024年土地變更調(diào)查培訓(xùn)
- 2024年全國(guó)外貿(mào)單證員鑒定理論試題庫(kù)(含答案)
- 新版中國(guó)食物成分表
- 運(yùn)輸車輛掛靠協(xié)議書(shū)(15篇)
- 完整版:美制螺紋尺寸對(duì)照表(牙數(shù)、牙高、螺距、小徑、中徑外徑、鉆孔)
- 醫(yī)院醫(yī)療質(zhì)量管理制度完整版
- 粵劇課程設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論