C語言程序設(shè)計(jì)第八章指針_第1頁
C語言程序設(shè)計(jì)第八章指針_第2頁
C語言程序設(shè)計(jì)第八章指針_第3頁
C語言程序設(shè)計(jì)第八章指針_第4頁
C語言程序設(shè)計(jì)第八章指針_第5頁
已閱讀5頁,還剩101頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第八章 指針,8.1 概 述,C程序設(shè)計(jì)中使用指針可以: 使程序簡潔、緊湊、高效 有效表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu) 動(dòng)態(tài)分配內(nèi)存 方便使用字符串 有效使用數(shù)組 調(diào)用函數(shù)時(shí)可以得到多于1個(gè)的值 直接處理內(nèi)存地址,8.2 指針的概念,一、數(shù)據(jù)的存取,1、內(nèi)存地址,內(nèi)存的每個(gè)字節(jié)都有一個(gè)編號(hào),這個(gè)編號(hào)稱為“內(nèi)存地址”。,程序中的每個(gè)數(shù)據(jù)都對(duì)應(yīng)著內(nèi)存中的一個(gè)地址,從該地址開始的一個(gè)或多個(gè)字節(jié)用來存放該數(shù)據(jù)。,int i, j, k;,i,j,k,2、內(nèi)存單元的地址和內(nèi)存單元的內(nèi)容的區(qū)別:,若i=3, j=5;,從圖中可以看出它們的區(qū)別。,程序編譯后已經(jīng)沒有i、j、k這些變量名了,而是將變量名轉(zhuǎn)換為變量的地址,計(jì)

2、算機(jī)通過內(nèi)存地址對(duì)變量進(jìn)行存取。,二、直接訪問和間接訪問,1、直接訪問方式:,、i=3;,、j=i+2;,、printf(%d, i);,、scanf(%d, ,、k=i+j; 如何執(zhí)行?,按變量的地址存取變量的方式,2、間接訪問方式:,語言中可以定義整型變量、實(shí)型變量、字符型變量,各自存放相應(yīng)類型的數(shù)據(jù);另外還可以定義和使用一種特殊類型的變量,用來存放變量的地址。,假設(shè)已經(jīng)定義變量 ip 用來存放整型變量的地址,它被分配到內(nèi)存單元3000和3001。,ip,通過執(zhí)行語句:ip= 將整型變量i 的地址存放到變量ip中,即ip的值為變量i所對(duì)應(yīng)的內(nèi)存單元的起始地址2000。,2000,現(xiàn)在要存取

3、i的值可以這樣做:先找到存放i的地址的內(nèi)存單元地址(3000和3001),從中取出變量i的地址(2000),然后再對(duì)2000和2001單元進(jìn)行存取這就稱為間接訪問。,通過變量ip知道變量i的地址,從而找到變量i的內(nèi)存單元,因此說變量ip指向變量i,用箭頭表示這種“指向”關(guān)系。,變量ip的值為2000,即變量i的地址,這樣就在ip和 i 之間建立了一種聯(lián)系:,3、關(guān)于“指向”的含義:,4、為了表示將數(shù)值10送到變量i中,可以有兩種表示方法:,、將10送到變量i所標(biāo)志的單元中;,10,、將10送到變量ip所指向的單元中;,10,三、指針與指針變量,通過地址能找到所需的變量單元,可以說:地址“指向”

4、該變量單元。因此,把一個(gè)變量的地址稱為該變量的“指針”。,如果一個(gè)變量專門用來存放另一個(gè)變量的地址,則稱它為“指針變量”。指針變量的值(即指針變量中存放的值)是指針(地址)。,注意區(qū)分“指針”和“指針變量”這兩個(gè)概念。,指針與指針變量 指針:一個(gè)變量的地址 指針變量:專門存放變量地址的變量,2000,指針,指針變量,變量的內(nèi)容,變量的地址,、數(shù)據(jù)所占有的內(nèi)存單元個(gè)數(shù)是由其數(shù)據(jù)類型決定的;,、首地址:即第一個(gè)單元的地址;,、表示地址的數(shù)與整數(shù)的區(qū)別;,、變量i、j的地址可能相鄰,也可能不相鄰,是由系統(tǒng)分配的,我們不必關(guān)心。,、程序中定義的每個(gè)變量在編譯后都占有各自的內(nèi)存單元,系統(tǒng)是通過內(nèi)存地址對(duì)

5、變量進(jìn)行存取的;,四、說明,8.3 指針變量的定義和引用,指針運(yùn)算符:*,為了表示指針變量和它所指向的變量之間的聯(lián)系,用“*”表示指向的關(guān)系。,如:ip代表指針變量,*ip表示ip所指向的變量。即*ip也代表一個(gè)變量。,例:,、若:ip=,*ip=5;,結(jié)論:*ip與i等價(jià)。,、x=i+1;,x=*ip+1;,取地址運(yùn)算符:,、不能把一個(gè)指針變量的值賦值給一個(gè)整型變量:x=ip;, float *q ; static char *name;,存儲(chǔ)類型 數(shù)據(jù)類型 *指針變量名;,說明:, “*”只表示定義的變量為指針變量,但指針變量名中并不包含“*”;*是指針變量的標(biāo)志,不可丟掉;, 指針變量定

6、義時(shí),指定了它所指向的變量的數(shù)據(jù)類型;指針變量定義時(shí)必須指定其所指向的變量的數(shù)據(jù)類型,而且使用過程中只能指向同一種類型的變量。, 指針變量定義后,系統(tǒng)為變量分配一個(gè)存儲(chǔ)單元,用來存放地址;根據(jù)存儲(chǔ)單元的長度分為大存儲(chǔ)模式(長指針,4 Byte)和小存儲(chǔ)模式(短指針,2 Byte);, 指針變量定義后,若不賦值,其值是不確定的。,二、指針變量的賦值,1、賦值語句:,int i, j, *p1, *p2;,p1=,char ch, *cp1, *cp2;,cp1=,2、初始化:,int i, *p1=,int i, *p1; p1=,一般形式: 存儲(chǔ)類型 數(shù)據(jù)類型 *指針變量名=初始地址值;,賦給

7、指針變量, 不是賦給目標(biāo)變量,例 int i; int *p=,變量必須已說明過 類型應(yīng)一致,例 int i; int *p=,用已初始化指針變量作初值,例 main( ) int i; static int *p= . (),不能用auto變量的地址 去初始化static型指針,3、說明:,、指針變量定義后,若不賦值,其值是不確定的;,、可以給指針變量賦空值(NULL),使指針變量不指向任何變量;,ip=NULL;,#define NULL 0,、指針變量的值為空值(NULL)與未對(duì)指針變量賦值,意義不同;,、只能是同類型變量的地址進(jìn)行賦值;,int i, *ip; char ch, *cp

8、;,ip=,ip=,、可以將數(shù)組名或函數(shù)名賦給某些類型的指針變量;,int a10, *ip;,ip=,ip=a;,、不能將一個(gè)整型量(或任何其它非地址類型的數(shù)據(jù))賦給一個(gè)指針變量;,int *ip;,ip=3000;,8.3.2 指針變量的引用,int a, *p1, *p2; p1=,int a, *p1, *p2;,p1=,p2=p1;,3,printf(%d, *p1);,1、兩個(gè)運(yùn)算符: p=,int a, *p; *p=,3、指針變量可以進(jìn)行的操作:,int a, *p1, *p2;,、賦值:,p1=,p2=p1;,、輸出:,printf(%x, p1);,、取內(nèi)容:,*p1=5;

9、,a=5;,printf(%d, *p1);,例8.1,#include void main( ) int a1=11, a2=22; int *p1, *p2; p1= , int *p1, *p2, *p; p1= , int *p1, *p2; p1= , temp=x; x=y; y=temp; void main( ) int a, b; printf(nInput a, b: ); scanf(%d%d, ,注意:語言中的函數(shù)調(diào)用采用“傳值”方式,即單向傳遞方式。,即:主調(diào)函數(shù)可以將實(shí)參的值傳遞給被調(diào)函數(shù)的形參,但不能通過改變形參的值而改變實(shí)參的值。,Eg804.cpp,#incl

10、ude void swap(int *px, int *py) int temp; temp=*px; *px=*py; *py=temp; void main( ) int a, b, *p1, *p2; printf(nInput a, b: ); scanf(%d%d, , *temp=*px; *px=*py; *py=*temp; void main( ) int a, b, *p1, *p2; printf(nInput a, b: ); scanf(%d%d, ,*temp是指針變量temp所指向的變量,但temp中并無確定的地址值,其值不確定;*temp所指向的單元也不確定。因

11、此,對(duì)*temp賦值可能會(huì)破壞系統(tǒng)的正常工作狀況。,應(yīng)該將*px的值賦給一個(gè)整型變量,用整型變量作為臨時(shí)存儲(chǔ)空間實(shí)現(xiàn)*px和*py的交換。,#include void swap(int *px, int *py) int *p; p=px; px=py; py=p; void main( ) int a, b, *p1, *p2; printf(nInput a, b: ); scanf(%d%d, , /* 定義包含10個(gè)整型元素的數(shù)組a */ int *p; /* 定義指向整型變量的指針變量p */ 指向數(shù)組元素的指針變量,其類型應(yīng)與數(shù)組元素相同 為了讓指針p指向數(shù)組a,應(yīng)把數(shù)組a的地址賦

12、給指針變量p,賦值:,p=,、定義時(shí)可以進(jìn)行初始化:,int *p=,int *p; p=,int *p; *p=,int *p=a;,8.4.2 通過指針訪問一維數(shù)組,int a10; int *p; 如果: p = a; (或 p = ) 則,*p=5;,a0=5;,p=,*p=5;,a3=5;,又如果:,當(dāng)指針p指向數(shù)組a后,可用指針p訪問數(shù)組的各個(gè)元素。,通過指針訪問一維數(shù)組,C規(guī)定:若指針變量p已指向數(shù)組中的一個(gè)元素,則p1指向該數(shù)組中的下一個(gè)元素,如果指針p指向數(shù)組a(指向數(shù)組第一個(gè)元素a0),則:p+1指向下一個(gè)元素a1,注意不是將p值簡單加1。如果數(shù)組元素是整型,p+1表示p的

13、地址加2;如果數(shù)組元素是實(shí)型,p+1表示p的地址加4;如果數(shù)組元素是字符型,p+1表示p的地址加1,通過指針訪問一維數(shù)組,p+i指向元素ai??梢允褂?(p+i)訪問元素ai p+i也可以記作a+i。指向元素ai。 指向數(shù)組的指針變量也可以帶下標(biāo),如,pi與*(p+i)等價(jià),表示元素ai。,指針的運(yùn)算,指針變量的賦值運(yùn)算 p= (指針變量p2值p1) 不能把一個(gè)整數(shù)p,也不能把p的值整型變量,指針的運(yùn)算,指針的算術(shù)運(yùn)算 pi p id (i為整型數(shù),d為p指向的變量所占字節(jié)數(shù)) p+, p-, p+i, p-i, p+=i, p-=i等 若p1與p2指向同一數(shù)組,p1-p2=兩指針間元素個(gè)數(shù)(

14、p1-p2)/d p1+p2 無意義,指針的運(yùn)算,例 p指向float數(shù),則 p+1 p+1 4,例 p指向int型數(shù)組,且p= 則p+1 指向a1,例 int a10; int *p=,例 int a10; int *p1=,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a數(shù)組,p,p+1,a+1,p+i,a+i,p+9,a+9,1,指針的運(yùn)算,指針變量的關(guān)系運(yùn)算 若p1和p2指向同一數(shù)組,則 p1p2 表示p1指的元素在后 p1=p2 表示p1與p2指向同一元素 若p1與p2不指向同一數(shù)組,比較無意義 p=NULL或p!=NULL,數(shù)組元素表示方法, 變址運(yùn)算符 ai *(a

15、+i),ai pi *(p+i) *(a+i),通過指針訪問一維數(shù)組,例10.1輸出有10個(gè)元素的整型數(shù)組a中的全部元素 1、下標(biāo)法(常用,很直觀) main() int a10;int i; for(i=0;i10;i+) scanf(%d, ,例10.1輸出有10個(gè)元素的整型數(shù)組a中的全部元素 1、下標(biāo)法(常用,很直觀) main() int a10;int i; for(i=0;i10;i+) scanf(%d, ,下標(biāo),通過指針訪問一維數(shù)組,2、用數(shù)組名計(jì)算數(shù)組元素的地址。(效率與下標(biāo)法相同,不常用) main() int a10;int i; for(i=0;i10;i+) scan

16、f(%d, ,數(shù)組名,通過指針訪問一維數(shù)組,3.用指針訪問各元素。(常用,效率高) main() int a10;int *p, i; for(i=0;i10;i+) scanf(%d, ,指針移動(dòng),通過指針訪問一維數(shù)組,三種方法比較: 方法1、2費(fèi)時(shí),編譯系統(tǒng)先將ai轉(zhuǎn)換為*(a+i),即先計(jì)算元素地址; 方法3不用每次計(jì)算地址,執(zhí)行效率高; 下標(biāo)法直觀。,通過指針訪問一維數(shù)組,使用指針指向數(shù)組,應(yīng)注意以下問題: 1.若指針p指向數(shù)組a,雖然p+i與a+i、*(p+i)與*(a+i)意義相同,但仍應(yīng)注意p與a的區(qū)別(a代表數(shù)組的首地址,是不變的;p是一個(gè)指針變量,可以指向數(shù)組中的任何元素,實(shí)

17、現(xiàn)使自身的值改變) for(p=a; a(p+10); a+) printf(%d, *a) a代表數(shù)組的首地址,是不變的,a+不合法,通過指針訪問一維數(shù)組,2.指針變量可以指向數(shù)組中的任何元素,在程序運(yùn)行期間,要始終注意指針變量當(dāng)前所指向的是哪一個(gè)元素 main() int *p, i, a10; p = a; for(i=0;i10;i+) scanf(%d, p+); printf(n); for(i=0;i10; i+,p+) printf(%d, *p); ,p=a;,通過指針訪問一維數(shù)組,3.使用指針時(shí),應(yīng)特別注意避免指針訪問越界。在上例中,第二次for循環(huán),p已經(jīng)越過數(shù)組的范圍,

18、但編譯器不能發(fā)現(xiàn)該問題。避免指針訪問越界是程序員自己的責(zé)任。,通過指針訪問一維數(shù)組,4.指針使用的幾個(gè)細(xì)節(jié): 設(shè)指針p指向數(shù)組a(p=a),則: p+(或 p += 1),p指向下一個(gè)元素a1。如執(zhí)行*p,則取出a1的值 *p+,相當(dāng)于*(p+)。因?yàn)椋?和+同優(yōu)先級(jí),+是右結(jié)合運(yùn)算符(p375)。則先得到*p,再執(zhí)行p=p+1。 *(p+)與*(+p)的作用不同。 *(p+):先取*p,再使p加1。 *(+p):先使p加1,再取*p。,通過指針訪問一維數(shù)組, (*p)+表示,p指向的元素值加1。 如果p當(dāng)前指向數(shù)組a的第i個(gè)元素,則: *(p-)相當(dāng)于ai-,先取*p,再使p減1。 *(+p

19、)相當(dāng)于a+i,先使p加1,再取*p。 *(-p)相當(dāng)于a-i,先使p減1,再取*p。,例 int a=1,2,3,4,5,6,7,8,9,10,*p=a,i; 數(shù)組元素地址的正確表示:(A) int y,*p= ,輸出:5 6,例 注意指針變量的運(yùn)算,6,8.4.3 通過指針在函數(shù)間傳遞一維數(shù)組,2、數(shù)組名作為函數(shù)參數(shù):,void f(int x , int n);,f(a, 10);,數(shù)組名代表數(shù)組首地址。用數(shù)組名作實(shí)參,調(diào)用函數(shù)時(shí)是把數(shù)組首地址傳遞給形參,而不是把數(shù)組的值傳給形參。這樣,實(shí)參數(shù)組和形參數(shù)組共占同一段內(nèi)存區(qū)域。從而在函數(shù)調(diào)用后,實(shí)參數(shù)組的元素值可能會(huì)發(fā)生變化。,x,x0,x

20、1,x2,x3,x4,x5,x6,x7,x8,x9,實(shí)際上能夠接受并存放地址值的只能是指針變量,編譯系統(tǒng)都是將形參數(shù)組名作為指針變量來處理的。,void f(int *x, int n);,通過指針在函數(shù)間傳遞一維數(shù)組,變量名與數(shù)組名作函數(shù)參數(shù)時(shí)的比較:,變量名,變量的值,不能,數(shù)組名或指針變量,數(shù)組的起始地址,能,需要說明的是: 語言的函數(shù)調(diào)用都是采用“值傳遞”方式;當(dāng)用變量名作函數(shù)參數(shù)時(shí)傳遞的是變量的值;用數(shù)組名作函數(shù)參數(shù)時(shí),由于數(shù)組名代表的是數(shù)組首地址,因此傳遞的是數(shù)組首地址,所以要求形參為指針變量。,歸納起來,實(shí)參與形參的對(duì)應(yīng)關(guān)系有:,、形參和實(shí)參都用數(shù)組名:,f(int x , in

21、t n);,f(a, 10);,把實(shí)參數(shù)組首地址傳給形參作為形參數(shù)組首地址;,、實(shí)參用數(shù)組名,形參用指針變量:,f(int *x, int n);,f(a, 10);,把實(shí)參數(shù)組首地址傳給形參(指針變量),函數(shù)中用指針訪問實(shí)參數(shù)組,、形參和實(shí)參都用指針變量:,f(int *x, int n);,f(p, 10);,函數(shù)調(diào)用前應(yīng)先給實(shí)參指針變量賦值(如:p=a),、實(shí)參為指針變量,形參為數(shù)組名:,f(int x , int n);,f(p, 10);,實(shí)參通過指針變量為形參提供數(shù)組首地址;,void inv(int x, int n) int t,i,j,m=(n-1)/2; for(i=0;i

22、=m;i+) j=n-1-i; t=xi; xi=xj; xj=t; main() int i,a10=3,7,9,11,0,6,7,5,4,2; inv(a,10); printf(The array has been reverted:n); for(i=0;i10;i+) printf(%d,ai); printf(n); ,例 將數(shù)組a中的n個(gè)整數(shù)按相反順序存放,實(shí)參與形參均用數(shù)組,m=4,void inv(int *x, int n) int t,*p,*i,*j,m=(n-1)/2; i=x; j=x+n-1; p=x+m; for(;i=p;i+,j-) t=*i; *i=*j;

23、 *j=t; main() int i,a10=3,7,9,11,0,6,7,5,4,2; inv(a,10); printf(The array has been reverted:n); for(i=0;i10;i+) printf(%d,ai); printf(n); ,實(shí)參用數(shù)組,形參用指針變量,例 將數(shù)組a中的n個(gè)整數(shù)按相反順序存放,void inv(int *x, int n) int t,*i,*j,*p,m=(n-1)/2; i=x; j=x+n-1; p=x+m; for(;i=p;i+,j-) t=*i; *i=*j; *j=t; main() int i,a10,*p=a

24、; for(i=0;i10;i+,p+) scanf(%d,p); p=a; inv(p,10); printf(The array has been reverted:n); for(p=a;pa+10;p+) printf(%d,*p); ,實(shí)參與形參均用指針變量,例 將數(shù)組a中的n個(gè)整數(shù)按相反順序存放,void inv(int x, int n) int t,i,j,m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i; t=xi; xi=xj; xj=t; main() int i,a10,*p=a; for(i=0;i10;i+,p+) scanf(%d,p); p=

25、a; inv(p,10); printf(The array has been reverted:n); for(p=arr;parr+10;p+) printf(%d ,*p); ,實(shí)參用指針變量,形參用數(shù)組,例 將數(shù)組a中的n個(gè)整數(shù)按相反順序存放,8.5 指針與字符串,8.5.1 字符串表示形式 用字符數(shù)組實(shí)現(xiàn),例 main( ) char string=“I love China!”; printf(“%sn”,string); printf(“%sn”,string+7); ,用字符指針實(shí)現(xiàn),例 main( ) char *string=“I love China!”; printf(

26、“%sn”,string); string+=7; while(*string) putchar(string0); string+; ,字符指針初始化:把字符串首地址賦給string char *string; string=“I love China!”;,例:將字符串a(chǎn)復(fù)制到字符串b字符數(shù)組作參數(shù) main() char a = I am a boy.;char b20;int i; for(i=0; *(a+i) !=0; i+) *(b+i) = *(a+i); *(b+i) = 0; printf(string a is: %sn,a); printf(string b is:);

27、 for(i=0; bi !=0; i+) printf(%c,bi); printf(n); ,將字符串a(chǎn)復(fù)制到字符串b用指針處理 main() char a=Iam a boy., b20, *p1, *p2;int i; p1 = a; p2 = b; for(; *p1 != 0; p1+, p2+) *p2 = *p1; *p2 = 0; printf(string a is: %sn, a);printf(string b is:); for(i=0; bi !=0; i+) printf(%c,bi);printf(n); ,8.5.2字符串指針作函數(shù)參數(shù),將一個(gè)字符串從一個(gè)函數(shù)

28、傳遞到另一個(gè)函數(shù),可以使用傳地址的方式,即用字符數(shù)組名或字符指針變量作參數(shù)。有以下四種情況:,例 用函數(shù)調(diào)用實(shí)現(xiàn)字符串復(fù)制,(1)用字符數(shù)組作參數(shù),(2)用字符指針變量作參數(shù),void copy_string(char from,char to) int i=0; while(fromi!=0) toi=fromi; i+; toi=0; main() char a=I am a teacher.; char b=You are a student.; printf(string_a=%sn string_b=%sn,a,b); copy_string(a,b); printf(nstring

29、_a=%snstring_b=%sn,a,b); ,void copy_string(char *from,char *to) for(;*from!=0;from+,to+) *to=*from; *to=0; main() char *a=I am a teacher.; char *b=You are a student.; printf(string_a=%snstring_b=%sn,a,b); copy_string(a,b); printf(nstring_a=%snstring_b=%sn,a,b); ,對(duì)copy_string函數(shù)的幾種簡化- :,void copy_stri

30、ng(char *from, char *to) while(*to=*from) !=0) to+; from+ ,*to=*from是一個(gè)賦值表達(dá)式,其值等于*from。to+和from+分別使指針指向下一個(gè)字節(jié)。 先執(zhí)行賦值表達(dá)式,再判賦值表達(dá)式的值(等于*from)是否為0,因此,from串中的結(jié)尾字符0被賦值給to。,對(duì)copy_string函數(shù)的幾種簡化- :,Void copy_string(char *from, char *to) while(*to+=*from+) != 0); ,*to+=*from+先執(zhí)行*to=*from,再使to、from分別加1。,對(duì)copy_s

31、tring函數(shù)的幾種簡化- :,Void copy_string(char *from, char *to) while(*from != 0) *to+ = *from+; *to = 0; ,當(dāng)遇到*from=0時(shí),不執(zhí)行賦值運(yùn)算*to+=*from+,因此,最后應(yīng)加一句*to=0,對(duì)copy_string函數(shù)的幾種簡化- :,Void copy_string(char *from, char *to) while(*to+=*from+); ,與第種簡化相同,當(dāng)*from=0時(shí),表達(dá)式*to+=*from+的值等于0(假),結(jié)束while循環(huán)。,對(duì)copy_string函數(shù)的幾種簡化-

32、:,Void copy_string(char *from, char *to) for(;(*to+ =*from+) !=0;); 或 for(;*to+ =*from+;); ,for循環(huán)的結(jié)束條件是表達(dá)式*to+ =*from+的值(即*from的值)等于0。且form中的0已被賦給to。注意0的ASCII碼是不是0。,對(duì)copy_string函數(shù)的幾種簡化- :,Void copy_string(char from, char to) char *p1, *p2; p1 = from; p2 = to; while(*p2+=p1+) !=0) ,形參用數(shù)組,使用局部指針變量指向形參

33、數(shù)組,字符指針變量與字符數(shù)組 char *cp; 與 char str20; str由若干元素組成,每個(gè)元素放一個(gè)字符;而cp中存放字符串首地址 char str20; str=“I love China!”; () char *cp; cp=“I love China!”; () str是地址常量;cp是地址變量 cp接受鍵入字符串時(shí),必須先開辟存儲(chǔ)空間,例 char str10; scanf(“%s”,str); () 而 char *cp; scanf(“%s”, cp); (),改為: char *cp,str10; cp=str; scanf(“%s”,cp); (),字符串與數(shù)組關(guān)

34、系 字符串用一維字符數(shù)組存放 字符數(shù)組具有一維數(shù)組的所有特點(diǎn) 數(shù)組名是指向數(shù)組首地址的地址常量 數(shù)組元素的引用方法可用指針法和下標(biāo)法 數(shù)組名作函數(shù)參數(shù)是地址傳遞等 區(qū)別 存儲(chǔ)格式:字符串結(jié)束標(biāo)志 賦值方式與初始化 輸入輸出方式:%s %c,char str=“Hello!”; () char str=“Hello!”; () char str=H,e,l,l,o,!; () char *cp=“Hello”; () int a=1,2,3,4,5; () int *p=1,2,3,4,5; (),char str10,*cp; int a10,*p; str=“Hello”; () cp=“H

35、ello!”; () a=1,2,3,4,5; () p=1,2,3,4,5; (),8.6 指針與多維數(shù)組,8.6.1多維數(shù)組的地址 二維數(shù)組 static int a34 = 1,3,5,7,9,11,13,15,17,19,21,23; 理解為: 有三個(gè)元素a0、a1、a2,每一個(gè)元素代表一行,每一個(gè)元素是一個(gè)包含4個(gè)元素的數(shù)組。,多維數(shù)組的地址,a,a+1,a+2,2000,a0+1,a0+2,a0+3,指向多維數(shù)組的指針變量,例:用指針變量輸出數(shù)組元素的值。 main() static int a34 = 1,3,5,7,9,11,13,15,17,19,21,23; int *p;

36、 for(p=a0; pa0+12; p+) if ( (p-a0)%4 = 0) printf(n); printf(%4d, *p); ,指向多維數(shù)組的指針變量,注意:本例用指針順序訪問二維數(shù)組的元素。若需訪問二維數(shù)組anm(n行m列)的某個(gè)元素aij,計(jì)算該元素的相對(duì)位置公式為: i*m+j (i,j=0,1,2, .) 這種方法相當(dāng)于把二維數(shù)組轉(zhuǎn)化為一維數(shù)組來使用。,指向多維數(shù)組的指針變量,直接用二維數(shù)組下標(biāo)訪問元素: main() static int a34 = 1,3,5,7,9,11,13,15,17,19,21,23; int i,j; for(i=0; i3; i+) fo

37、r(j=0;j4;j+) printf(%4d,aij); printf(n); 方式雖然清晰,但需進(jìn)行兩層循環(huán),且為了計(jì)算每一個(gè)元素aij的位置,均進(jìn)行i*4+j的運(yùn)算,執(zhí)行效率非常低。,8.7 指針與函數(shù),C語言中的指針,既可以指向變量(整型、字符型、實(shí)型、數(shù)組等),也可以指向程序的代碼(如函數(shù))。 一個(gè)函數(shù)在編譯時(shí)被分配一個(gè)入口地址(第一條指令的地址),這個(gè)入口地址稱為函數(shù)的指針。如果一個(gè)指針變量的值等于函數(shù)的入口地址,稱為指向函數(shù)的指針變量。 可以通過函數(shù)指針來調(diào)用函數(shù)。,指針與函數(shù),函數(shù)指針:函數(shù)在編譯時(shí)被分配的入口地址,用函數(shù)名表示,p,指向函數(shù)的指針變量,例 用函數(shù)指針變量調(diào)用函

38、數(shù),比較兩個(gè)數(shù)大小,main() int max(int ,int); int a,b,c; scanf(%d,%d, ,main() int max(int ,int), (*p)(); int a,b,c; p=max; scanf(%d,%d, ,指向函數(shù)的指針變量,函數(shù)指針變量賦值:如p=max;,函數(shù)返回值的數(shù)據(jù)類型,專門存放函數(shù)入口地址 可指向返回值類型相同的不同函數(shù),定義形式: 數(shù)據(jù)類型 (*指針變量名)(形參類型 ); 如 int (*p)();,函數(shù)指針變量指向的函數(shù)必須有函數(shù)說明,函數(shù)調(diào)用形式: c=max(a,b); c=(*p)(a,b); c=p (a,b); 對(duì)函數(shù)

39、指針變量pn, p+, p-無意義,例 用函數(shù)指針變量作參數(shù),求最大值、最小值和兩數(shù)之和,用函數(shù)指針變量作函數(shù)參數(shù),返回指針的函數(shù),一般形式: 類型標(biāo)識(shí)符 * 函數(shù)名(參數(shù)表) 例、int *a (int x, int y) 聲明一個(gè)函數(shù),函數(shù)名為a,其返回值類型是“指向整型的指針”,函數(shù)形式參數(shù)為 int x 和 int y,例 有若干學(xué)生的成績(每個(gè)學(xué)生四門課程),要求用戶在輸入學(xué)生序號(hào)(從開始)后,能輸出該學(xué)生的全部成績。 分析:設(shè)計(jì)一個(gè)指針pointer指向一個(gè)學(xué)生的四門成績 float (*pointer)4,pointer是一個(gè)指向一維數(shù)組的指針。數(shù)組元素個(gè)數(shù)為4(四門課程) po

40、inter+1指向下一個(gè)學(xué)生的成績。 輸入學(xué)生序號(hào)后,使pointer指向該學(xué)生的成績,然后返回pointer指針,main() float score4=60,70,80,90, 56,89,67,88,34,78,90,66; float *search(float (*pointer)4,int n), *p; int i,m; printf(Enter the number of student:); scanf(%d, ,例 對(duì)上例中的學(xué)生,找出有不及格成績的學(xué)生及其學(xué)號(hào)。 分析:上例中search函數(shù)返回學(xué)生成績的首地址。本例用返回地址區(qū)分學(xué)生成績中有無不及格課程,若有不及格課程時(shí)

41、,仍返回學(xué)生成績的首地址;若無不及格課程,則返回學(xué)生成績的末地址(等于下一個(gè)學(xué)生的首地址)。,float * search( float (*pointer)4 ); void main()static float score4 =60,70,80,90,56,89,67,88,34,78,90,66 ;float *p;int i, j; for(i=0; i3; i+) /* 三個(gè)學(xué)生 */p = search(score+i);if (p = *(score+i) /* p指向i號(hào)學(xué)生成績首地址,該生有不及格課程 */ printf(No.%d scores:t, i); /* 顯示該生

42、的四門課程成績 */ for(j=0; j4; j+)printf(%5.2t, *(p+j); printf(n); ,float * search( float (*pointer)4 )int i;float *pt;pt = *(pointer + 1); /*設(shè)pt指向成績末地址(等于下一個(gè)學(xué)生成績首地址),即先假設(shè)無不及格成績 */for(i=0; i4; i+) /* 查四門課程中有無不及格成績 */if ( *(*pointer+i)60 ) pt = *pointer; /*有不及格課程,pt指向成績首地址*/return pt; ,8.8 指針數(shù)組,概念:指針數(shù)組是一個(gè)數(shù)組

43、,該數(shù)組中的每一個(gè)元素是指針變量。 形式: 存儲(chǔ)類型 類型標(biāo)識(shí)符 *數(shù)組名數(shù)組元素個(gè)數(shù) 例、 int *p4; 定義一個(gè)指針數(shù)組,數(shù)組名p,有4個(gè)元素, 每一個(gè)元素是指向整型變量的指針。 區(qū)分:int (*p)4(指向數(shù)組的指針)定義一個(gè)指針變量,它指向有4個(gè)元素的一維數(shù)組。,char name59=“gain”,“much”,“stronger”, “point”,“bye”;,用途:處理多個(gè)字符串。 字符串本身是一維數(shù)組,多個(gè)字符串可以用二維數(shù)組來處理,但會(huì)浪費(fèi)許多內(nèi)存。用指針數(shù)組處理多個(gè)字符串,不會(huì)浪費(fèi)內(nèi)存。,char *name5=“gain”,“much”,“stronger”, “

44、point”,“bye”;,二維數(shù)組存儲(chǔ)空間固定 字符指針數(shù)組相當(dāng)于可變列長的二維數(shù)組 分配內(nèi)存單元=數(shù)組維數(shù)*2+各字符串長度,指針數(shù)組元素的作用相當(dāng)于二維數(shù)組的行名 但指針數(shù)組中元素是指針變量 二維數(shù)組的行名是地址常量,指針數(shù)組賦值或初始化,賦值: main() int b23,*pb2; pb0=b0; pb1=b1; . ,int *pb2,int b23,初始化: main() int b23,*pb =b0,b1; . ,初始化: main() char *p =Fortran, Lisp, Basic,NULL; .,main() int b23,*pb2; int i,j; for(i=0;i2;i+) for(j=0;j3;j+) bij=(i+1)*(j+1); pb0=b0; pb1=b1; for(i=0;i2;i+) for(j=0;j3;j+,pbi+) printf(b%d%d:%2dn,i,j,*pbi); ,例 用指針數(shù)組處理二維數(shù)組,例 對(duì)字符串排序(簡單選擇排序),main() void sort(char *name,int n), print(char *name,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論