第1講 指針(1)_第1頁
第1講 指針(1)_第2頁
第1講 指針(1)_第3頁
第1講 指針(1)_第4頁
第1講 指針(1)_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第第1講講 指針指針(1)l 指針的概念指針的概念 l 指針變量指針變量 教學(xué)目標(biāo)教學(xué)目標(biāo)n 理解指針的概念和作用;理解指針的概念和作用;n 掌握指針變量的定義、取地址和間接訪問運算,能夠利用指掌握指針變量的定義、取地址和間接訪問運算,能夠利用指針變量作為函數(shù)參數(shù)、得到個要改變的值。針變量作為函數(shù)參數(shù)、得到個要改變的值。重點:重點:指針的概念和作用,指針變量的定義和指針的概念和作用,指針變量的定義和&、*運算,指針運算,指針變量作形參的作用變量作形參的作用難點:難點:指針的概念,指針變量的定義和指針的概念,指針變量的定義和&、*運算,指針變量作運算,指針變量作形參的作用形參的作

2、用1. 指針的概念指針的概念 指針指針是是C語言的一個語言的一個重要概念重要概念,也是,也是C語言的一個語言的一個重要特色重要特色,正確而靈活地運用它,可以使程序正確而靈活地運用它,可以使程序簡潔、緊湊、高效簡潔、緊湊、高效。不掌握不掌握指針就是沒有掌握指針就是沒有掌握C的精華。的精華。 在介紹指針之前,有必要了解內(nèi)存地址的相關(guān)知識。在介紹指針之前,有必要了解內(nèi)存地址的相關(guān)知識。(1)內(nèi)存地址內(nèi)存地址 程序必須裝載到內(nèi)存中才能運行,而計算機的程序必須裝載到內(nèi)存中才能運行,而計算機的內(nèi)存是一維內(nèi)存是一維線性空間線性空間。 假設(shè)計算機內(nèi)存為假設(shè)計算機內(nèi)存為4GB,則它是由,則它是由232個存儲單元

3、個存儲單元(大小為大小為1byte)組成,可以將這些存儲單元按照從小到大的組成,可以將這些存儲單元按照從小到大的順序編順序編址,址,都是用二進(jìn)制表示的,轉(zhuǎn)換為十六進(jìn)制都是用二進(jìn)制表示的,轉(zhuǎn)換為十六進(jìn)制則對應(yīng)的地址范圍為則對應(yīng)的地址范圍為0X000000000XFFFFFFFF。為直觀起見,內(nèi)存地址常用十為直觀起見,內(nèi)存地址常用十進(jìn)制數(shù)描述。進(jìn)制數(shù)描述。內(nèi)存線性空間內(nèi)存線性空間存儲單元,大小為存儲單元,大小為1B計算機控制器計算機控制器通過存儲通過存儲單元地址可以存取其中單元地址可以存取其中的內(nèi)容的內(nèi)容。存儲單元地址存儲單元地址 在地址所標(biāo)識的內(nèi)存在地址所標(biāo)識的內(nèi)存單元中存放數(shù)據(jù)單元中存放數(shù)據(jù),

4、這相,這相當(dāng)于旅館房間中居住的當(dāng)于旅館房間中居住的旅客一樣。旅客一樣。 由于通過地址能找到由于通過地址能找到所需的變量單元,我們所需的變量單元,我們可以說,可以說,地址指向該變地址指向該變量單元量單元。將將地址地址形象化地稱為形象化地稱為“指針指針”(2)不同類型的數(shù)據(jù)占用內(nèi)存單元的個數(shù)、存儲方式不同不同類型的數(shù)據(jù)占用內(nèi)存單元的個數(shù)、存儲方式不同0 x0012FF7C0X0012FF7D0X0012FF7E0X0012FF7Fint a=100;0X0012FF740X0012FF750X0012FF7Bdouble pi=3.14;4bytes8bytes1003.14數(shù)據(jù)單元數(shù)據(jù)單元數(shù)據(jù)單

5、元數(shù)據(jù)單元首地址首地址char ch=A;char str =“China”;A0anIhCn由此可見,由此可見,數(shù)據(jù)單元在內(nèi)存中是連續(xù)存放的數(shù)據(jù)單元在內(nèi)存中是連續(xù)存放的,根據(jù)其,根據(jù)其首地址首地址和和數(shù)據(jù)類型數(shù)據(jù)類型,就能,就能確定其所占用的存儲單元個數(shù)和數(shù)據(jù)存儲方確定其所占用的存儲單元個數(shù)和數(shù)據(jù)存儲方式式,實現(xiàn)存取,實現(xiàn)存取數(shù)據(jù)數(shù)據(jù)的目的的目的。(3)兩種存取變量的方式兩種存取變量的方式輸出單元輸出單元1200開始的開始的4B內(nèi)容內(nèi)容 3456 內(nèi)存地址空間內(nèi)存地址空間data1輸出單元輸出單元200開始的開始的4B內(nèi)容內(nèi)容 3456這些操作由編譯系統(tǒng)、這些操作由編譯系統(tǒng)、操作系統(tǒng)自動完成

6、,操作系統(tǒng)自動完成,用戶不用考慮。用戶不用考慮。n直接存取方式:直接存取方式:按變量名存取按變量名存取 在在程序中定義的變量編譯時系統(tǒng)為其程序中定義的變量編譯時系統(tǒng)為其分配內(nèi)存單元分配內(nèi)存單元,以下列代碼為例進(jìn)行說明:以下列代碼為例進(jìn)行說明:int data1=3456;printf(“%d”, data1);3456data1n間接存取方式:間接存取方式:l 變量變量i的地址存放在變量的地址存放在變量p中,通過中,通過p來存取來存取i的值的值,這種變量的存取方式稱為這種變量的存取方式稱為間接存取方式間接存取方式2000pi20003345l 指向就是通過地址來體現(xiàn)的指向就是通過地址來體現(xiàn)的,

7、如上例,如上例,p中存放了中存放了i的地址,的地址,通過通過p就能知道就能知道i的地址,從而找到變量的地址,從而找到變量i的內(nèi)存單元;的內(nèi)存單元;l 由于通過由于通過地址地址能找到所需的變量單元,因此說,能找到所需的變量單元,因此說,地址指向地址指向該該變量單元;變量單元;l 將將地址地址形象化地稱為形象化地稱為“指針指針”,意思是通過它能找到以它為,意思是通過它能找到以它為地址的內(nèi)存單元;地址的內(nèi)存單元;l 一個變量的地址一個變量的地址稱為稱為該變量的該變量的“指針指針”,專門用來,專門用來存放另一變存放另一變量的地址量的地址(即指針即指針)的的變量變量,稱為,稱為“指針變量指針變量”?!爸?/p>

8、針指針”與與“指針變量指針變量”不同不同。(4)什么是指針?什么是指針?n概念:指針是一個概念:指針是一個特定類型數(shù)據(jù)特定類型數(shù)據(jù)的的存儲地址存儲地址,比如一個變量的,比如一個變量的地址地址如:如:int a=100;0 x0012FF7C指針指針n 說明:說明:l 指針指針也是一種數(shù)據(jù)類型也是一種數(shù)據(jù)類型,占占4個字節(jié)個字節(jié);l 用戶定義的對象用戶定義的對象必須由系統(tǒng)分配存儲空間必須由系統(tǒng)分配存儲空間;l 空指針值:空指針值:即即NULL,它不指指向任何地方,它不指指向任何地方,在在VC定義定義為常為常數(shù)數(shù)0,任何類型的指針變量都可以賦予該值。,任何類型的指針變量都可以賦予該值。 2. 指針

9、變量指針變量(1)概念與定義格式概念與定義格式n概念:用來概念:用來存放一個數(shù)據(jù)存放一個數(shù)據(jù)(對象對象)的地址的變量的地址的變量。指針變量的。指針變量的值是地址值是地址(即指針即指針)n定義格式:定義格式:數(shù)據(jù)數(shù)據(jù)類型類型 * 變量名變量名 =指針表達(dá)式指針表達(dá)式;n 說明:說明:l *是指針類型的標(biāo)志,不能省略是指針類型的標(biāo)志,不能省略;它不是指針變量名的組成部;它不是指針變量名的組成部分;分; l 數(shù)據(jù)類型是數(shù)據(jù)類型是指針變量中所存地址指向的數(shù)據(jù)的類型指針變量中所存地址指向的數(shù)據(jù)的類型,又稱基,又稱基類型,它類型,它決定了數(shù)據(jù)占用的存儲單元長度及存儲方式?jīng)Q定了數(shù)據(jù)占用的存儲單元長度及存儲方

10、式,不同,不同數(shù)據(jù)類型占用的存儲單元長度可能不同,即使長度相同,存數(shù)據(jù)類型占用的存儲單元長度可能不同,即使長度相同,存儲方式也不同;數(shù)據(jù)類型是通過指針存取數(shù)據(jù)的基礎(chǔ),儲方式也不同;數(shù)據(jù)類型是通過指針存取數(shù)據(jù)的基礎(chǔ),不允不允許定義無數(shù)據(jù)類型的指針變量許定義無數(shù)據(jù)類型的指針變量;l 允許對指針變量初始化,即允許對指針變量初始化,即定義時并賦地址值定義時并賦地址值。例如:例如:int a=100;int *p_a=&a;100a首地址:首地址:0 x0012FF7Cp_a指向指向p_str指向指向 (指針變量未賦值指針變量未賦值)?&a即是即是0 x0012FF7Cn 懸空指針:懸空

11、指針:l 如果一個如果一個指針變量,既沒有賦指針變量,既沒有賦NULL值,又沒有指向有效的值,又沒有指向有效的內(nèi)存地址內(nèi)存地址,則稱為,則稱為“懸空指針懸空指針”;l 懸空指針的懸空指針的值是不確定的值是不確定的,這個未知地址可能指向一個有用,這個未知地址可能指向一個有用數(shù)據(jù)或一段代碼,直接操作可能帶來危險,甚至導(dǎo)致系統(tǒng)崩數(shù)據(jù)或一段代碼,直接操作可能帶來危險,甚至導(dǎo)致系統(tǒng)崩潰,潰,應(yīng)盡力避免懸空指針的使用應(yīng)盡力避免懸空指針的使用;問題:為什么指針變量通常用問題:為什么指針變量通常用p開頭?開頭?指針指針(pointer)的首字符是的首字符是pn 如何避免懸空指針的使用?如何避免懸空指針的使用?

12、定義指針變量時堅持對其進(jìn)行初始化定義指針變量時堅持對其進(jìn)行初始化,若不,若不能能確定確定它它指指向向哪一哪一個變量,則讓該指針個變量,則讓該指針變量變量初始化為初始化為NULL,例如:,例如: 如如 int *p = NULL; /正確地進(jìn)行初始化正確地進(jìn)行初始化n 空類型與空指針的比較空類型與空指針的比較l void: 空類型空類型,即即不指明任何具體的數(shù)據(jù)類型不指明任何具體的數(shù)據(jù)類型;l void * :空類型指針空類型指針,不指向任何類型,即,不指向任何類型,即 void * 指針僅僅為指針僅僅為一個地址一個地址;l 允許將其它指針的值賦給空類型指針允許將其它指針的值賦給空類型指針,但不

13、允許將空類型指針賦,但不允許將空類型指針賦給其它指針,除非進(jìn)行強制轉(zhuǎn)換;給其它指針,除非進(jìn)行強制轉(zhuǎn)換;l NULL與與void * 不同不同:NULL是一個指針值,任何類型的指針可是一個指針值,任何類型的指針可以賦予該值以賦予該值,而,而void * 是一種類型,是一種無任何類型的指針;是一種類型,是一種無任何類型的指針;l 可以根據(jù)實際需要,可以根據(jù)實際需要,對指針類型進(jìn)行強制轉(zhuǎn)換對指針類型進(jìn)行強制轉(zhuǎn)換。(2)指針的兩個特殊運算符指針的兩個特殊運算符(單目運算符單目運算符)& :取地址運算符取地址運算符,返回其操作對象的內(nèi)存地址,通常其操返回其操作對象的內(nèi)存地址,通常其操作對象為一個

14、變量,例如作對象為一個變量,例如 p_a=&a ;* :間接訪問運算符間接訪問運算符,存取指針?biāo)竼卧闹?,如:,存取指針?biāo)竼卧闹?,如:printf(“%d”, *p_a); 可以輸出變量可以輸出變量a的值。的值。/例例1:運算符:運算符 & 與與 * 使用舉例:使用舉例:#include int main()int a=10;int * p_a;p_a=&a;/取地址取地址printf(“變量變量a的地址的地址(十六進(jìn)制十六進(jìn)制): %Xn,p_a);printf(修改前:直接訪問修改前:直接訪問 a=%d, 間接訪問間接訪問 a=%dn,a,*p_a);*p_a

15、=10000;/通過間接訪問,修改通過間接訪問,修改a值值printf(修改后:直接訪問修改后:直接訪問 a=%d, 間接訪問間接訪問 a=%dnn,a,*p_a);return 0;例例2: 輸入輸入a和和b兩個整數(shù),按先大后小的順序輸出兩個整數(shù),按先大后小的順序輸出a和和b。n 解題思路:解題思路:用指針方法來處理這個問題。不交換整型變量的用指針方法來處理這個問題。不交換整型變量的值,而是值,而是交換兩個指針變量的值交換兩個指針變量的值。#include int main() int *p1,*p2,*p,a,b;printf(please enter two integer number

16、s:);scanf(%d %d,&a,&b); / 輸入兩個整數(shù)輸入兩個整數(shù)p1=&a; / 使使p1指向變量指向變量ap2=&b; / 使使p2指向變量指向變量b if(ab) / 如果如果abp=p1;p1=p2;p2=p; /p1與與p2的值互換的值互換printf(a=%d,b=%dn,a,b); / 輸出輸出a,bprintf(max=%d,min=%dn,*p1,*p2);/ 輸出輸出p1和和p2所指向的變量的值所指向的變量的值return 0;n 說明:說明:l 一條語句中一條語句中定義多個變量定義多個變量,每一個指針變量前的每一個指針變量前的*號

17、不能省號不能省略略,例如:,例如:int *p_a, *p_b;l 指針變量的賦值指針變量的賦值=:u賦值號兩邊的指針類型必須相同賦值號兩邊的指針類型必須相同;u其它指針的值其它指針的值可以賦值給可以賦值給空類型指針空類型指針,反過來不允許;,反過來不允許;u不同類型指針變量賦值時,要進(jìn)行不同類型指針變量賦值時,要進(jìn)行強制轉(zhuǎn)換。強制轉(zhuǎn)換。指出下列代碼中的錯誤:指出下列代碼中的錯誤:int *p,a=1; float *q;*p=5; q=&a; printf(p的地址:的地址:%X,p的值:的值:%dn,p,*p); printf(q的地址:的地址:%X,q的值:的值:%fn,q,*q

18、); n p未指向有效地址,是懸未指向有效地址,是懸空空指針;指針;n q指向的變量數(shù)據(jù)類型與指針變量指向的變量數(shù)據(jù)類型與指針變量定義的數(shù)據(jù)類型不一致。定義的數(shù)據(jù)類型不一致。(3) 指針變量作為函數(shù)參數(shù)指針變量作為函數(shù)參數(shù)例例3: 題目要求同例題目要求同例 2,即對輸入的兩個整數(shù)按大小順序輸出。,即對輸入的兩個整數(shù)按大小順序輸出?,F(xiàn)用函數(shù)處理,而且用指針類型的數(shù)據(jù)作函數(shù)參數(shù)?,F(xiàn)用函數(shù)處理,而且用指針類型的數(shù)據(jù)作函數(shù)參數(shù)。n 解題思路:解題思路:定義一個函數(shù)定義一個函數(shù)swap,將指向兩個整型變量的指,將指向兩個整型變量的指針變量作為實參傳遞給針變量作為實參傳遞給swap函數(shù)的形參指針變量,在函

19、數(shù)函數(shù)的形參指針變量,在函數(shù)中通過指針實現(xiàn)交換兩個變量的值。中通過指針實現(xiàn)交換兩個變量的值。#include int main()void swap(int *p1,int *p2);int a,b;int *pointer_1,*pointer_2;printf(please enter a and b:);scanf(%d%d,&a,&b);pointer_1=&a;pointer_2=&b;if(ab) swap(pointer_1,pointer_2);printf(max=%d, min=%dnn,a,b);return 0; void swap(in

20、t *p1,int *p2)int temp;temp=*p1;*p1=*p2;*p2=temp;void swap(int *p1,int *p2)int *temp;*temp=*p1;*p1=*p2;*p2=*temp;問題:能否將問題:能否將swap()寫成如下形式?寫成如下形式?錯!錯!無確定的指向無確定的指向問題:問題:int *temp;與與*temp=;的星號的星號(*)有什么不同?有什么不同?思考:以下程序代碼能否實現(xiàn)數(shù)據(jù)的交換?思考:以下程序代碼能否實現(xiàn)數(shù)據(jù)的交換? #include int main() if (ab) swap(a,b); printf(“max=%d,

21、min=%dn”,a,b); return 0; void swap(int x,int y) int temp; temp=x; x=y; y=temp;普通類型作函數(shù)參數(shù)時,是普通類型作函數(shù)參數(shù)時,是“值傳遞值傳遞”方式,方式,函數(shù)調(diào)用時把函數(shù)調(diào)用時把實參復(fù)制給形參,在函數(shù)內(nèi)形參實參復(fù)制給形參,在函數(shù)內(nèi)形參的改變不影響實參的改變不影響實參。n 如果想通過函數(shù)調(diào)用得到個要改變的值:如果想通過函數(shù)調(diào)用得到個要改變的值: 在主調(diào)函數(shù)中設(shè)在主調(diào)函數(shù)中設(shè)個變量個變量,用,用個指針變量指向它們個指針變量指向它們; 設(shè)計一個函數(shù),有設(shè)計一個函數(shù),有n個指針形參個指針形參。在這個。在這個函數(shù)中改變這個函數(shù)

22、中改變這個形參的值形參的值; 在主調(diào)函數(shù)中調(diào)用這個函數(shù)在主調(diào)函數(shù)中調(diào)用這個函數(shù),在調(diào)用時,在調(diào)用時將這將這n個指針變量作個指針變量作實參,將它們的地址傳給該函數(shù)的形參;實參,將它們的地址傳給該函數(shù)的形參;如果想通過函數(shù)調(diào)用得到個要改變的值:如果想通過函數(shù)調(diào)用得到個要改變的值: 在在執(zhí)行該函數(shù)的過程中執(zhí)行該函數(shù)的過程中,通過形參指針變量,改變它們所指通過形參指針變量,改變它們所指向的個變量的值向的個變量的值;主調(diào)函數(shù)中主調(diào)函數(shù)中就就可以使用這些改變了值的變量可以使用這些改變了值的變量。不要企圖通過改變指針形參的值而使指針實參的值改變。不要企圖通過改變指針形參的值而使指針實參的值改變。下面例子并不

23、成功。下面例子并不成功。例例4: 對輸入的兩個整數(shù)按大小順序輸出對輸入的兩個整數(shù)按大小順序輸出n 解題思路:解題思路:嘗試調(diào)用嘗試調(diào)用swap函數(shù)來實現(xiàn)題目要求。在函數(shù)中函數(shù)來實現(xiàn)題目要求。在函數(shù)中改變形參改變形參(指針變量指針變量)的值,希望能由此改變實參的值,希望能由此改變實參(指針變量指針變量)的值的值。#include int main()void swap(int *p1,int *p2);int a,b;int*pointer_1,*pointer_2;printf(please enter two integer numbers:);scanf(%d%d,&a,&

24、b);pointer_1=&a;pointer_2=&b;if(ab)swap(pointer_1,pointer_2);printf(max=%d,min=%dnn,a,b);return 0; void swap(int *p1,int *p2)int *p;p=p1;p1=p2;p2=p;錯!錯!只交換形參指向,只交換形參指向,不影響實參指向不影響實參指向n 注意:注意:函數(shù)的調(diào)用可以函數(shù)的調(diào)用可以(而且只可以而且只可以)得到一個返回值得到一個返回值(即函數(shù)即函數(shù)值值),而使用指針變量作參數(shù),可以得到多個變化了的值而使用指針變量作參數(shù),可以得到多個變化了的值。如果不用指針

25、變量是難以做到這一點的如果不用指針變量是難以做到這一點的;n 要要善于利用指針法善于利用指針法。例例5: 輸入輸入3個整數(shù)個整數(shù)a,b,c,要求按由大到小的順序?qū)⑺鼈冚敵?,要求按由大到小的順序?qū)⑺鼈冚敵?,用函?shù)實現(xiàn)。用函數(shù)實現(xiàn)。n 解題思路:擴展解題思路:擴展例例3的方法在函數(shù)中改變這的方法在函數(shù)中改變這3個變量的值個變量的值,用用swap函數(shù)交換函數(shù)交換2個變量的值,用個變量的值,用exchange函數(shù)改變函數(shù)改變3個變量個變量的值。的值。#include int main() void exchange(int *q1, int *q2, int *q3); / 函數(shù)聲明函數(shù)聲明 int a

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論