指針與指針變量_第1頁
指針與指針變量_第2頁
指針與指針變量_第3頁
指針與指針變量_第4頁
指針與指針變量_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第五章 指針 之 第一節(jié) 指針與指針變量1.指針的基本概念 計算機(jī)內(nèi)存是有一片連續(xù)的存儲單元組成,操作系統(tǒng)給每個單元一個編號,這個編號稱為內(nèi)存單元的地址,每個存儲單元占內(nèi)存一個字節(jié)。 定義變量時,系統(tǒng)就按照其類型為變量分配一塊連續(xù)的存儲單元。 則這塊存儲單元的首地址稱為該變量的指針(也稱該變量的地址)。 如:float f ; 假設(shè)分配給f的是地址為1500、1501、1502、1503的四個連續(xù)字節(jié)。 則稱地址1500是變量f的指針(或說變量f的地址是1500)。 所以,變量的地址就是變量的指針。 第五章 指針 之 第一節(jié) 指針與指針變量n先來看 卡片管理系統(tǒng) 假設(shè)有許多存儲不同數(shù)據(jù)的卡片,

2、如圖。想對這些數(shù)據(jù)快速存取,一個好方法就是對每張卡片編號,再為每張卡片取個名字,讓名字和編號一一對應(yīng)起來。 這樣就能通過名字存取卡片上的數(shù)據(jù),比如指出卡片名f,就可以由對應(yīng)地址1500處取出數(shù)據(jù)456.789。123您好!456.7891500卡片上數(shù)據(jù)卡片編號 1500015002卡片名字 abchipf. 注意:p 是一種特殊的卡片,它存儲的是卡片 f的編號,則通過p 也能間接地存取卡片f的數(shù)據(jù)。 圖5.1第五章 指針 之 第一節(jié) 指針與指針變量n變量值的存取與卡片數(shù)據(jù)存取相類似。 每個變量都有名字和地址。同樣是使用變量名通過相應(yīng)地址存取數(shù)據(jù)。可以把圖5.1理解成變量存儲的情況,如圖5.2

3、。 假設(shè)變量f為float型。則讀取f的值是從地址1500開始的四個字節(jié)中取出數(shù)據(jù)456.789。這種稱為“直接存取”方式。 特殊變量p存儲了變量f的地址。則可以通過訪問p變量,可以得到地址1500,再訪問1500的存儲單元,也可以得到f的值456.789。這種稱為“間接存取“方式。 變量的值地址編號 1000500015001002變量名 abchipf.123您好!456.7891500 圖5.2第五章 指針 之 第一節(jié) 指針與指針變量 象p變量這種,專門存放其他變量的地址的變量,稱為指針變量。 如圖5.2,指針變量p里已經(jīng)存儲了f 變量的地址,我們又說指針變量p指向了變量 f 。2。指針

4、變量的定義 定義的一般形式: 類型名類型名 * 標(biāo)識符標(biāo)識符 ; 如: int i, * ip, * jp ; /* 定義了ip和jp兩個可以指向整型變量的指針變量*/ float f, *p; /* 定義了一個可以指向float型變量的指針變量p*/ 注意:a.定義了一個指針變量,在沒有對它賦值前,它指向的存儲單元是不確定的。 b.一個指針變量只能指向其類型相同的變量第五章 指針 之 第一節(jié) 指針與指針變量3.指針變量的賦值 1). 通過地址運(yùn)算符&賦值 “&”是單目運(yùn)算符,作用是對其右邊的對象進(jìn)行取地址。 如: float f, *p; p=&f; /* 這樣指針變

5、量p就指向變量f了 */ 2).指針變量初始化。 如: float f, *p=&f; 變量p 指向 ff3d 變量fff3df的值第五章 指針 之 第一節(jié) 指針與指針變量3)通過其他指針變量賦值 可以把一個指針變量的地址值賦給另一個指針變量,這樣兩個指針變量均指向同一個地址。 如: int i, * p1=&i, * p2; p2=p1; 指向 2f3a 變量p1 變量i 變量p2 注意,當(dāng)把一個指針變量的地址值賦給另一個指針變量時,賦值號兩邊指針變量所指的數(shù)據(jù)類型必須相同。2f3ai的值2f3a第五章 指針 之 第一節(jié) 指針與指針變量如: int i, * pi=&

6、i; float *pf; pf=pi; /* 這句是非法的*/ 4). 用NULL給指針變量賦空值 可以給指針變量賦空值,如: p= NULL ; NULL是在 stdio.h頭文件中定義的預(yù)定義標(biāo)識符,因此在使用 NULL時,應(yīng)該在程序中加上文件包含#include“stdio.h”。在C語言中當(dāng)指針值為NULL時,指針不指向任何有效數(shù)據(jù)。由于NULL與整數(shù)0相對應(yīng),所以下面三條語句等價: p= NULL;或 p= 0; 或 p=0 ; NULL可以賦值給指向任何類型的指針變量。第五章 指針 之 第一節(jié) 指針與指針變量5).通過調(diào)用標(biāo)準(zhǔn)庫函數(shù)賦值 可以調(diào)用庫函數(shù)malloc和calloc在

7、內(nèi)存中開辟動態(tài)存儲單元,并把所開辟的動態(tài)存儲單元的首地址賦給指針變量。由于這兩個函數(shù)返回的是“void?!睙o類型指針類型,因此將它們的返回值賦值給指針變量時要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。(1)malloc函數(shù) 調(diào)用該函數(shù),在內(nèi)存的動態(tài)存儲區(qū)中分配一個指定長度(以字節(jié)為單位)的連續(xù)存儲空間,如果調(diào)用該函數(shù)成功,則返回所分配空間的首地址,如果分配不成功測返回NULL。 調(diào)用形式為: malloc(表達(dá)式) 如: int *p; p=( int *)malloc (sizeof (10*int );分配成功,p就能得到20個字節(jié)空間的首地址第五章 指針 之 第一節(jié) 指針與指針變量 (2)calloc 函數(shù) 調(diào)

8、用該函數(shù),在內(nèi)存動態(tài)存儲區(qū)中分配一塊連續(xù)的存儲空間. 函數(shù)調(diào)用形式為: calloc(n,size) 如:int *p; p=( int *)calloc (20,sizeof (int ); /* 效果等同于上面的malloc例子*/ 指向20個字節(jié)首地址 p f73b f73c f73d(3)free函數(shù) 調(diào)用該函數(shù),用來釋放由 malloc或。alloc函數(shù)分配的存儲空間,調(diào)用該函數(shù)不返回任何值。函數(shù)調(diào)用形式為: free(指針變量) 其中指針變量應(yīng)指向調(diào)用malloc或calloc時所分配存儲區(qū)的首地址, 如 : free(p);f73b 第五章 指針 之 第二節(jié) 指針運(yùn)算符52 方針

9、運(yùn)算符 指針運(yùn)算符 “ * ” 和 取地址運(yùn)算符“ & ” 521 指針運(yùn)算符“ * ” 指針運(yùn)算符的運(yùn)算對象必須放在指針運(yùn)算符的右側(cè),是用來存取相應(yīng)的存儲單元中的數(shù)據(jù)。運(yùn)算符和* 都是單目運(yùn)算符,它們具有相同的優(yōu)先級,結(jié)合方向均為“從右到左”. 例如: int i123,j,* p; p= i; 則 j=*p;和j=*&i ;都將把變量 i的值賦給變量 j。而* p= 456; 和 * i= 456;都將把整數(shù)456賦給變量 i。 第五章 指針 之 第二節(jié) 指針運(yùn)算符 所以: 1. *&i 等價于&*i等價于變量i. 2當(dāng)一個指針變量 p指向某變量 i時(p=

10、 i;),則表達(dá)式* p與變量 i等價。例如: p= i; printf(”dn”,* p) /* 相當(dāng)于 printf(”dn”,i);* / j= (* p)+ +; /* 相當(dāng)于j= i十十;* / 注意表達(dá)式(* p)+ + 中的括號不能省略,如果沒有括號,則* p+等價于*(p+),此時先使用變量i的值,再使p的值改變,這樣p就不再指向變量i了。第五章 指針 之 第二節(jié) 指針運(yùn)算符 指針變量的值是可以改變的. 通過* p方式存取它所指向變量的值是以間接存取的形式進(jìn)行的.如: int i= 1,j= 2,* p; P= i; * p = 100;/* 相當(dāng)于i + = 100;* /

11、P= j; (*p) - -;/* 相當(dāng)于j - -;* / 另外,注意: 若有 int i, *p=&i; /* 相當(dāng)于 int I , * p;p= i;* / 則 1. *p 等價于 i 等價于 *&i 2. *p 等價于 p 3* i是非法的表達(dá)式,因?yàn)閕不是地址,也不是指針變量。而指針運(yùn)算符“ * ”的運(yùn)算對象必須是指針變量或地址。第五章 指針 之 第二節(jié) 指針運(yùn)算符例 51由鍵盤機(jī)一個正整數(shù),求出其最高位數(shù)字。用指針變量來完成本題。 main() long i,*p; pi; printf(請輸人一個正整數(shù):”); scanf(”ld,p); /* 本語句等價于sc

12、anf(”ld,i);* / while(* P= 10)* P/= 10;/* 求出該正整數(shù)的最高位數(shù)字* / printf( 最高位數(shù)字是:ld。n”,* P); 運(yùn)行結(jié)果: 請輸人一個正整數(shù):56789 最高位數(shù)字是:5。 語句P=&i ;是不可少的,若指針變量P在使用之前未賦初值,它可能指向內(nèi)存中任意一個地址,可能導(dǎo)致程序出現(xiàn)意想不到的錯誤。第五章 指針 之 第二節(jié) 指針運(yùn)算符522 無類型指針 可定義一個指針變量,指向 void *類型,在將它的值賦給另一個指針變量時,要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。 int * pl; char * p2 ; void *q; /*定義 q為無類型指針

13、變量* / q= malloc( slzeof(int) ); p1= (int* )q; /* 將 q的地址賦值給指針變量 P1,q與 p1指向同一地址* / * pl= 0X4142; /* 對 pl所指的內(nèi)存賦值 0 x4124(即十進(jìn)制數(shù) 16706)* / p2= (char *)q ; /* 將 q的地址賦值給指針變量 p2,q與 p2指向同一地址* / printf(%d,c,cn”,* pl,* p2,* (p21); free(q); 以上程序段運(yùn)行的結(jié)果是: 16706,B,A第五章 指針 之 第二節(jié) 指針運(yùn)算符 可以用無類型指針q指向內(nèi)存中的一塊存儲單元,當(dāng)用不同類型的指

14、針與q指向同一地址時,可存取不同類型的數(shù)據(jù)。若指向整型類型的指針ql指向q所指的地址時,則可用* pl存取整型數(shù)據(jù);若指向字符型的指針 p2指向 q所指的地址時,則可用* p2存取字符型數(shù)據(jù),上述程序段中,0 x41(即十進(jìn)制數(shù) 65)是字符A 的 ASCll碼。 也可以用強(qiáng)制類型轉(zhuǎn)換,把一個指針的值賦值給一個無類型指針。 例如: float f,* p3f; void * q; q= (void * )p3; 則此時q和p3都指向?qū)嵭妥兞縡。第五章 指針 之 第三節(jié) 指針與數(shù)組531 指針與一維數(shù)組1一維數(shù)組和數(shù)組元素的地址 一個數(shù)組的元素在內(nèi)存中是連續(xù)存放的,數(shù)組第一個元素的地址稱數(shù)組第一

15、個元素的地址稱數(shù)組的首地址數(shù)組的首地址。在C語言中,數(shù)組名是該數(shù)組的首地址數(shù)組名是該數(shù)組的首地址。例如有以下定義語句: int a10,*p; 則語句p= a;和p= ao;是等價的( 即a等價于&ao ),都表示指針變量p指向a數(shù)組的首地址。 數(shù)組首地址的值是一個地址常量,是不能改變的。因此,語句 a= p;或 a;都是非法的.第五章 指針 之 第三節(jié) 指針與數(shù)組在C語言中, 若定義 int a6;則: 數(shù)組的0元素a0的地址是a (等價于 &a0); 數(shù)組的1元素 a1的地址是 a+1(等價于&a1 ); 數(shù)組的2元素a2的地址是a+2(等價于&a2 );

16、數(shù)組的i元素a i 的地址是a+ i(等價于&ai );例如,有下述程序段:例如,有下述程序段: int a6= 1,2,3,4,5,6,* p= a; /* p指向整型數(shù)組指向整型數(shù)組 a的首地址的首地址* / double d 6= 1l,22,33,44,55,66,* q= d;假設(shè)數(shù)組假設(shè)數(shù)組a的首地址是的首地址是2000,假設(shè)數(shù)組,假設(shè)數(shù)組d的首地址是的首地址是3000.第五章 指針 之 第三節(jié) 指針與數(shù)組 則上述兩個數(shù)組分配的內(nèi)存情況如圖 54所示,應(yīng)注意整型數(shù)組(int)每下移一個元素地址加2字節(jié),雙精度實(shí)型數(shù)組(double)每下移一個元素地址加 8字節(jié)。 圖5.4

17、a第五章 指針 之 第三節(jié) 指針與數(shù)組 數(shù)組數(shù)組d 的內(nèi)存情況的內(nèi)存情況: 圖圖5.4 b 此時的此時的 q+1 等價于等價于 d+1, 也等價于也等價于 &d1 q+i 等價于等價于 d+i, 也等價于也等價于 &di第五章 指針 之 第三節(jié) 指針與數(shù)組2通過一維數(shù)組名所代表的地址存取數(shù)組元素通過一維數(shù)組名所代表的地址存取數(shù)組元素 根據(jù)指針運(yùn)算符根據(jù)指針運(yùn)算符“ * ”的運(yùn)算的運(yùn)算 規(guī)則知規(guī)則知*(b十十i)與元素)與元素ai等價等價 例如,下述程序段:例如,下述程序段: int a 1,2,3,4,5,6,7,8,9,10 ; * (a十十5)= 50; /*相當(dāng)于相當(dāng)于a

18、5= 5O;* / scanf(”%d”,&a8); /*相當(dāng)于相當(dāng)于scanf(%d ,a十十8););* / printf(”dn,* (a5);); /*相當(dāng)于相當(dāng)于 printf”dn,a 5 ););* /第五章 指針 之 第三節(jié) 指針與數(shù)組3通過指針運(yùn)算符通過指針運(yùn)算符“ * ”存取數(shù)組元素存取數(shù)組元素 設(shè)有如下程序段:設(shè)有如下程序段: int a10 ,* p; p = a; 則則 *(pi)與元素)與元素a i 等價等價 以下程序段合法以下程序段合法: int a 1,2,3,4,5,6,7,8,9,10,*pa; *(p+5)=50;/*相當(dāng)于相當(dāng)于a5=50; */ scanf(”d”,a8););/*相當(dāng)于相當(dāng)于 scanf(”d”,p8););*/ printf(”d n”,*( p5 ); /*相當(dāng)于相當(dāng)于 printf ( ”dn”,a5 ) ;*/第五章 指針 之 第三節(jié) 指針與數(shù)組4通過帶下標(biāo)的指針變量存取數(shù)組元素 C語言中的下標(biāo)運(yùn)算符“ ”可以構(gòu)成表達(dá)式,假設(shè)p為指針變量且指向數(shù)組首元素,i為整型表達(dá)式,則可以把pi看成是表達(dá)式,首先按p+i計算地址,然后再存取此地址單元中的值。因此pi與*(p + i

溫馨提示

  • 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論