指針和結構體_第1頁
指針和結構體_第2頁
指針和結構體_第3頁
指針和結構體_第4頁
指針和結構體_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、復習:指針和結構體1指針指針變量的定義與引用指針的運算指針與數(shù)組指針與內(nèi)存的動態(tài)分配2指針變量的定義與引用計算機將內(nèi)存的每一個字節(jié)都編了號,這個編號稱為內(nèi)存的地址。在對內(nèi)存的某個單元進行操作之前,程序必須知道這個單元的地址。2000200120022003200420053指針變量的定義與引用C語言中,指針實際上就是內(nèi)存地址;但如果某個變量的值實際上就是另一個變量的地址,那么這個變量被稱為指針變量。例如,已知有個int型變量a,那么如果將a的地址賦值給變量p(即p=&a;),那么p就是一個指針變量p的值是地址,也就是指針通常我們用箭頭表示指向關系4指針變量的定義與引用C語言可以通過變量名來引用

2、變量的內(nèi)存單元。通過變量名來引用變量的內(nèi)存單元被稱為直接引用。而通過內(nèi)存地址來引用內(nèi)存單元的做法稱為間接引用。C語言要依靠指針變量來實現(xiàn)變量的間接引用。例如,下面定義了兩個變量:int a,b;那么a=3表示將a的內(nèi)存單元賦值成3,而b=a則表示將a的內(nèi)存單元的值復制到b的內(nèi)存單元中。變量引用:5指針變量的定義與引用指針變量的定義格式是:int a,*p;int *p1,*p2;其中:數(shù)據(jù)類型符可以是任何一種有效的數(shù)據(jù)類型標識符,是指針變量所指向的內(nèi)存單元的數(shù)據(jù)類型;*號表明后面的變量名是個指針變量;變量名必須是一個合法的標識符。例如,下面的定義中,a是int型變量,p是指針變量(不是int型

3、變量),并且p所指向的單元是個int型數(shù)據(jù):int a ; int *p; 6指針變量的定義與引用在定義指針變量時,可以對指針變量賦初值。但要注意,指針必須要指向一個有效的地址單元。所謂指向有效地址單元,即是程序員自己確切地知道指針指向何處。通常在為指針變量賦初值時,將指針指向前面定義的變量。例如,下面的定義:int a;int *p=&a;但如果象下面這樣定義是錯誤的:int *p=&a; int a;7指針變量的定義與引用當一個指針指向一個變量時,程序就可以利用這個指針間接引用這個變量。間接引用的格式是:*指針變量。例如,char ch;char *p;p=&ch; /指向ch,見右圖*p

4、=a; /相當于ch=a102000pa112000paa2000pch又如,下面的程序將輸出:? int a,*p;p=&a;*p=10;a+;printf(a=%d,*p=%d,a,*p);a=11,*p=118指針變量的定義與引用*是間接引用運算符,是單目運算符,優(yōu)先級與+、-的優(yōu)先級相同,具有右結合性。表達式(*p)+不同于*p+。*p+中的+作用于p,而不是*p。指針變量之間也可以相互賦值,賦值時,如果=號右邊的指針類型與左邊的指針類型不同時,需要進行類型強制轉換。例如:int a;int *p1,*p2;char *pc;p1=&a; /p1指向ap2=p1; /p2也指向了apc

5、=(char *)p1;/pc也指向了a,p1、p2和pc的值是相同的,都是變量a的地址9指針變量的定義與引用程序在利用指針間接引用內(nèi)存單元時,將按照指針變量定義時所指向的數(shù)據(jù)類型來解釋引用的內(nèi)存單元。例如,下面的程序將輸出:?unsigned int a;int *pi=&a;char *pc=(char *)&a;*pi=0 xFFFE;*pc=0;printf(%x,a);FF0010練一練1、將下面程序中的變量a改為,int *a; ,修改程序保證運行結果不變。(pointer.c)void main() int a; scanf(%d,&a); a+=33; printf(a=%dn

6、,a); 思考題1、指針是地址嗎?指針有負值嗎?2、指針變量占多大內(nèi)存,指向long的指針是否比指向char的指針更占內(nèi)存?3、可以用一行定義語句同時定義int型變量和int型指針嗎?4、當一個指針p指向一個變量a時,利用p進行間接引用(*p)時,則*p的數(shù)據(jù)類型是受p的類型決定還是a的類型決定?11指針的運算指針是地址,地址是一種無符號的整數(shù)。但指針卻不能象整數(shù)那樣參與乘法和除法。因為指針乘以或除以一個數(shù)沒有任何意義。1、指針可以參與加法運算。例如,int a;int *p=&a;/假設這時p的值是2001p+=3; /這時p的值將是2001+6=2007,而不是200412指針的運算如果指

7、針p是這樣定義的:ptype *p;并且p的當前值是ADDR,那么p+n的值將是 ADDR+n*sizeof(ptype)。也就是說,p將以sizeof(ptype)為單位進行相加。例如,int *pi;char *pc;long *pl;pi=(int *)1000;pc=(char *)1000;pl=(long *)1000;pi+; pc+; pl+; 雖然指針可以參與加法運算,但將兩個指針相加沒有任何意義。/pi的值將是1002/pc的值將是1001/pl的值將是100413指針的運算2、指針也可以參與減法運算如果指針p是這樣定義的:ptype *p;并且p的當前值是ADDR,那么p

8、-n的值將是ADDR-n*sizeof(ptype)也就是說,p將以sizeof(ptype)為單位進行相減。如果兩個指針指向了同一塊內(nèi)存的不同地方,那么可以比較兩個指針的大小,也可以通過兩個指針的相減運算可以計算出兩個指針間的數(shù)據(jù)單元的個數(shù)。14指針與數(shù)組指針與一維數(shù)組的關系我們可以這樣定義并引用數(shù)組元素:int a10;int k;for(k=0;k10;k+) ak=k+1; /將數(shù)組a的各單元賦值成1,2,3,.,9,10for(k=0;k10;k+) *(a+k)=k+1; / *(a+k)等價于akC語言還規(guī)定:ak表示數(shù)組a的第k+1個元素。數(shù)組變量名是數(shù)組在內(nèi)存中的地址,也就是

9、數(shù)組第一個元素在內(nèi)存中的地址。地址也就是指針,因此,a可以看成是指向int型數(shù)據(jù)的指針,我們可以用指針的間接引用運算符和數(shù)組變量名來引用數(shù)組元素。例如,上面的程序中的for語句也可以寫成:15指針與數(shù)組指針與一維數(shù)組的關系假設int型數(shù)組變量a的值是2000,也就是說,數(shù)組a的第一個單元a0的地址是2000(即是a的值)第二個單元a1的地址是2002(即a+1)以此類推,a2地址是2004(即a+2).ak的地址是a+k*2。所以,*(a+k)就是對ak的引用。既然數(shù)組名是一個指針,那么當將數(shù)組名賦值給一個真正的指針變量后,那個指針變量可以充當數(shù)組名使用,既可以使用下標來引用數(shù)組單元,又可以使

10、用指針間接引用運算符來引用數(shù)組單元。char str10;int k;for(k=0;k10;k+) strk=A+k;/也可寫成:*(str+k)=A+k;char str10;int k; char *p;p=str;for(k=0;k10;k+) pk=A+k; /也可寫成:*(p+k)=A+k;16練一練1、閱讀下面的程序(pointer2.c),寫結果:void main() int a=A,B,C; int k; int *p=a; for(k=0;k3;k+) printf(“%c”,pk); 如果將p的數(shù)據(jù)類型改為:char *p;程序運行結果將是:ABCA B17指針與內(nèi)存的

11、動態(tài)分配我們現(xiàn)在來考慮這樣一個問題:事先不知道學生的數(shù)量,編寫程序先輸入學生的數(shù)量,然后輸入學生的成績。從問題的性質來看,必須利用數(shù)組存放學生的成績。但程序中要定義數(shù)組,必須事先指定數(shù)組的大小。如果指定的太小,不滿足程序的要求,如果指定的太大,而學生的數(shù)量太小,則會造成內(nèi)存的浪費。能否解決這個兩難問題呢?C語言提供了動態(tài)分配內(nèi)存的手段來解決這個問題。18指針與內(nèi)存的動態(tài)分配實際上,C語言有兩種分配內(nèi)存的方式:一種是定義變量。當程序中定義了一個變量時,系統(tǒng)就自動為這個變量分配一塊內(nèi)存,這塊內(nèi)存的大小由變量的數(shù)據(jù)類型決定。象下面那樣定義一個數(shù)組變量:int a10;系統(tǒng)就自動為這個數(shù)組分配大小為2

12、0個字節(jié)的內(nèi)存塊。這種內(nèi)存分配方式稱為靜態(tài)內(nèi)存分配。另一種內(nèi)存分配方式是動態(tài)內(nèi)存分配。動態(tài)內(nèi)存分配是指在程序運行過程中,根據(jù)程序的實際需要來分配一塊大小合適的內(nèi)存。這塊內(nèi)存可以是一個數(shù)組,也可以是其它類型的數(shù)據(jù)單元。動態(tài)分配的內(nèi)存需要有一個指針變量記錄內(nèi)存的地址。19指針與內(nèi)存的動態(tài)分配要想在程序中動態(tài)分配內(nèi)存,需要調(diào)用標準庫函數(shù)malloc。malloc函數(shù)的原型:void *malloc(unsigned int size);malloc函數(shù)只帶一個參數(shù),這個參數(shù)的含義是要分配內(nèi)存的大?。ㄒ宰止?jié)為單位)。返回值是一個指向空類型(void)的指針,說明返回的指針所指向的內(nèi)存塊可以是任何類型。

13、如果malloc分配內(nèi)存失敗,則返回值是NULL(空指針)。如果要分配10個int型的數(shù)組,可以這樣調(diào)用malloc函數(shù):int *p;int k;p=(int *)malloc(10*sizeof(int);if(p!=NULL) for(k=0;k10;k+) pk=k+1;注意:malloc函數(shù)可能返回NULL,因此一定要檢查分配的內(nèi)存指針是否為空,如果是空指針,則不能引用這個指針,否則將造成系統(tǒng)崩潰。20指針與內(nèi)存的動態(tài)分配動態(tài)分配的內(nèi)存是可以釋放的。計算機中最寶貴的資源就是內(nèi)存,程序在需要時可以調(diào)用malloc函數(shù)向系統(tǒng)申請內(nèi)存,在不再需要這塊內(nèi)存時就應該將內(nèi)存返還給系統(tǒng)。如果程序只

14、申請內(nèi)存,用完了卻不返還,很容易將內(nèi)存耗盡,使程序最終無法運行。因此,一定要堅持好借好還,再借不難的原則。釋放內(nèi)存的函數(shù)是free。free函數(shù)只帶一個參數(shù),這個參數(shù)就是要釋放的內(nèi)存指針。下面是它的原型:void free(void * block);注意:調(diào)用malloc和free函數(shù)的源程序中要包含 stdlib.h文件。21結構體復雜數(shù)據(jù)類型概述結構體22復雜數(shù)據(jù)類型概述已經(jīng)學過的數(shù)據(jù)類型:整型:int,unsigned int,short int,long int實型:float,double,long double字符型:char數(shù)組:int an;指針:int *p;空類型:NUL

15、L思考:如何定義一個學生的信息,包括:姓名、性別、年齡、班級、學號、成績?23復雜數(shù)據(jù)類型概述如何定義一個學生的信息,包括:姓名、性別、年齡、班級、學號、成績?為了增強C語言的數(shù)據(jù)描述能力,C語言允許程序員定義自己的數(shù)據(jù)類型。這些數(shù)據(jù)類型被稱為復雜數(shù)據(jù)類型。C語言允許程序員定義的數(shù)據(jù)類型主要包括結構體、共用體以及枚舉類型。24結構體1、結構體類型的定義一個復雜的數(shù)據(jù)對象(比如學生信息)可能由多個數(shù)據(jù)項構成,比如學生的姓名、年齡、性別等數(shù)據(jù)項組合在一起構成了學生信息這個數(shù)據(jù)對象。這種數(shù)據(jù)對象可以用結構體類型來描述。結構體類型的定義格式是:struct 結構體類型名 數(shù)據(jù)類型名1 成員名1; 數(shù)據(jù)

16、類型名2 成員名2; . . 數(shù)據(jù)類型名n 成員名n; ; /必須以分號結尾結構體類型名必須是一個合法標識符類型定義時成員不能賦初值成員的數(shù)量、類型和順序不限整個結構體的定義必須以分號結尾結構體類型通常在函數(shù)外定義,但也可以在函數(shù)內(nèi)部定義結構體類型的作用域是從定義處到函數(shù)尾或文件尾25結構體1、結構體類型的定義下面定義的結構體類型可以用于描述學生信息:struct student_info char name20;/姓名 unsigned int age; /年齡 unsigned int gender; /性別 unsigned int class;/班級 int grade;/成績 ;結構

17、體類型的變量所占內(nèi)存的大小是它的成員所占內(nèi)存大小的和。對于struct student_info來說,sizeof(struct student_info)=sizeof(name)+sizeof(age)+sizeof(gender)+sizeof(class)+sizeof(grade).26結構體2、結構體變量的定義和引用前面介紹的僅僅是結構體類型的定義,是一種數(shù)據(jù)類型的定義,不是變量定義。結構體類型的變量的定義格式是:struct 結構體類型名 變量名;其中關鍵字struct必不可少,結構體類型名必須在定義變量之前定義。例如,下面定義了一個student_info類型的變量:struc

18、t student_info stu;定義這個變量時,程序將為這個變量分配大小是sizeof(struct student_info)的內(nèi)存空間,并且按照結構體類型定義中成員定義的順序為各個成員安排內(nèi)存空間。27結構體2、結構體變量的定義和引用程序員也可以一次定義多個結構體類型變量,變量間用逗號分開:struct student_info stu1,stu2;定義結構體變量時可以對變量賦初值。格式:struct 結構體類型名 變量名=成員1的值,成員2的值,.,成員n的值;注意:賦初值時, 中間的數(shù)據(jù)順序必須與結構體成員的定義順序相一致,否則就會出現(xiàn)混亂。 gender grade struc

19、t student_info stu=“Yang”,18,1,2,89; /正確 name age classstruct student_info stu=18,“Yang”,1,2,89; /錯誤28結構體2、結構體變量的定義和引用也可以在定義結構體類型時直接定義變量,也可以賦初值:struct student_info char name20; /姓名 unsigned int age,gender,class;/年齡,性別,班級 int grade; /成績 stu=“wang”,18,1,2,89;如果在定義結構體類型時直接定義變量,那么可以省略結構體類型名。例如,上面的結構體定義語

20、句可以這樣寫:struct char name20; /姓名 unsigned int age,gender,class;/年齡,性別,班級 int grade; /成績 stu=“wang”,18,1,2,89;29結構體2、結構體變量的定義和引用有了結構體類型符,就可以定義結構體類型的指針了。比如:struct student_info *p;對結構體類型的變量中的各成員的引用格式有兩種:(1)如果通過結構體變量來訪問某成員,它的格式是:變量名.成員名(2)如果通過結構體類型的指針訪問某成員,它的格式是: 指針成員名 或 (*指針).成員名其中,“.”和“”稱為結構體成員引用運算符,是優(yōu)先

21、級最高的運算符。它們與下標運算符和圓括號()是同一個優(yōu)先級,具有左結合性。30結構體2、結構體變量的定義和引用下面是結構體變量成員引用的例子:struct student_info stu;struct student_info *pstu;pstu=&stu; /指針pstu指向strcpy(,“Zhang”);/將“Zhang”復制到stu的name成員中stu.grade=100; /對stu的成員grade賦值pstuclass=2; /對stu的成員class賦值(*pstu).gender=1; /對stu的成員gender賦值31結構體2、結構體變量的定義和引用結

22、構體變量可以做整體賦值,但只能將同類型的結構體變量相互賦值,不能像賦初值那樣對結構體變量賦值,也不能對結構體變量作整體輸入。例如,/賦初值struct student_info stu1,stu2=“yang”,18,1,2,89;/同類型的結構體變量相互賦值stu1=stu2; /不能對結構體變量賦值stu1=“yang”,18,1,2,89;/*錯誤*/不能整體輸入scanf(“%s,%d,%d,%d,%d”,&stu1); /錯誤32結構體2、結構體變量的定義和引用結構體中的成員不能是自身類型的變量,但可以是另一個結構體類型的變量,也可以是自身類型的指針。例如,struct SA int a; float f; ;struct SB int b; struct SB sb; / 錯誤,不能包含自身類型的變量 struct SA

溫馨提示

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

評論

0/150

提交評論