C語言程序設計第8章地址和指針配套教材高等教育出版社清華大學出版社_第1頁
C語言程序設計第8章地址和指針配套教材高等教育出版社清華大學出版社_第2頁
C語言程序設計第8章地址和指針配套教材高等教育出版社清華大學出版社_第3頁
C語言程序設計第8章地址和指針配套教材高等教育出版社清華大學出版社_第4頁
C語言程序設計第8章地址和指針配套教材高等教育出版社清華大學出版社_第5頁
已閱讀5頁,還剩54頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第8章善于利用指針8.1變量的地址和指針8.2指針變量的定義和指針變量的基類型8.3給指針變量賦值8.4對指針變量的操作8.5

函數(shù)之間地址值的傳遞2023/2/43:158.1變量的地址和指針如果在程序中定義了一個變量,在對程序進行編譯時,系統(tǒng)就會給該變量分配內(nèi)存單元編譯系統(tǒng)根據(jù)程序中定義的變量類型,分配一定長度的空間例如,VC++為整型變量分配4個字節(jié),對單精度浮點型變量分配4個字節(jié),對字符型變量分配1個字節(jié)2023/2/43:158.1變量的地址和指針內(nèi)存區(qū)的每一個字節(jié)有一個編號,這就是“地址”,它相當于旅館中的房間號。在地址所標識的內(nèi)存單元中存放數(shù)據(jù),這相當于旅館房間中居住的旅客一樣。由于通過地址能找到所需的變量單元,我們可以說,地址指向該變量單元。將地址形象化地稱為“指針”2023/2/43:15務必弄清楚存儲單元的地址和存儲單元的內(nèi)容這兩個概念的區(qū)別例如:2023/2/43:15inti=3,j=6,k;printf(“%d”,i);通過變量名i找到i的地址2000,從而從存儲單元讀取32023/2/43:15inti=3,j=6,k;k=i+j;從這里取3將9送到這里從這里取6直接存取2023/2/43:15inti=3,j=6,k;定義特殊變量i_pointer將i的地址存到這里間接存取i_pointer=&i;*i_pointer=50;502023/2/43:15i200032000i_pointer*i_pointer20003直接存取間接存取2023/2/43:15i=3;*i_pointer=3;為了表示將數(shù)值3送到變量中,可以有兩種表達方法:(1)將3直接送到變量i所標識的單元中,例如:i=3;(2)將3送到變量i_pointer所指向的單元(即變量i的存儲單元),例如:*i_pointer=3;其中*i_pointer表示i_pointer指向的對象2023/2/43:15指向就是通過地址來體現(xiàn)的假設i_pointer中的值是變量i的地址(2000),這樣就在i_pointer和變量i之間建立起一種聯(lián)系,即通過i_pointer能知道i的地址,從而找到變量i的內(nèi)存單元2023/2/43:15由于通過地址能找到所需的變量單元,因此說,地址指向該變量單元將地址形象化地稱為“指針”。意思是通過它能找到以它為地址的內(nèi)存單元2023/2/43:15一個變量的地址稱為該變量的“指針”例如,地址2000是變量i的指針如果有一個變量專門用來存放另一變量的地址(即指針),則它稱為“指針變量”i_pointer就是一個指針變量。指針變量就是地址變量,用來存放地址的變量,指針變量的值是地址(即指針)2023/2/43:15“指針”和“指針變量”是不同的概念可以說變量i的指針是2000,而不能說i的指針變量是2000指針是一個地址,而指針變量是存放地址的變量2023/2/43:152023/2/43:153變量i2000指針i_pointer*i_pointeri*i_pointer&ii_pointeri=3;*i_pointer=38.2指針變量的定義和指針變量的基類型定義指針變量的一般形式為:

類型*指針變量名;如:int*pointer_1,*pointer_2;int是為指針變量指定的“基類型”基類型指定指針變量可指向的變量類型如pointer_1可以指向整型變量,但不能指向浮點型變量2023/2/43:158.2指針變量的定義和指針變量的基類型下面都是合法的定義和初始化:float*pointer_3;char*pointer_4;inta,b;int*pointer_1=&a,*pointer_2=&b;*pointer_1=&a;錯誤pointer_3=&a;錯誤pointer_1=&a;正確pointer_3=2000;錯誤2023/2/43:158.3給指針變量賦值給指針變量賦值,可以通過三種方式:用求地址運算符“&”給指針變量賦值。如:p=&a;通過指針變量獲得地址。如有p=&a;q=p;

則此時指針變量q中也存放了變量a的地址通過標準庫函數(shù)malloc、calloc獲得地址,見第13章使p指向aq也指向p所指的地址2023/2/43:15例8.1通過指針變量訪問整型變量。解題思路:先定義2個整型變量,再定義2個指針變量,分別指向這兩個整型變量,通過訪問指針變量,可以找到它們所指向的變量,從而得到這些變量的值。2023/2/43:15#include<stdio.h>intmain(){inta=100,b=10;

int*pointer_1,*pointer_2;

pointer_1=&a;

pointer_2=&b;printf(“a=%d,b=%d\n”,a,b);printf(“*pointer_1=%d,*pointer_2=%d\n”,*pointer_1,*pointer_2);return0;}定義兩個指針變量使pointer_1指向a使pointer_2指向b直接輸出變量a和b的值間接輸出變量a和b的值2023/2/43:15#include<stdio.h>intmain(){inta=100,b=10;

int*pointer_1,*pointer_2;

pointer_1=&a;

pointer_2=&b;printf(“a=%d,b=%d\n”,a,b);printf(“*pointer_1=%d,*pointer_2=%d\n”,*pointer_1,*pointer_2);return0;}此處*與類型名在一起。此時共同定義指針變量此處*與指針變量一起使用。此時代表指針變量所指向的變量2023/2/43:158.4對指針變量的操作在引用指針變量時,可能有三種情況:給指針變量賦值。如:p=&a;引用指針變量指向的變量。如有p=&a;*p=1;

則執(zhí)行printf(“%d”,*p);將輸出1引用指針變量的值。如:printf(“%o”,p);使p指向a*p相當于a以八進制輸出a的地址2023/2/43:158.4對指針變量的操作要熟練掌握兩個有關的運算符:(1)&

取地址運算符。

&a是變量a的地址(2)*指針運算符(“間接訪問”運算符)如果:p指向變量a,則*p就代表a。k=*p;(把a的值賦給k)

*p=1;(把1賦給a)2023/2/43:158.4對指針變量的操作指針運算指針變量加(減)一個整數(shù)例如:p++,p--,p+i,p-i,p+=i,p-=i等均是指針變量加(減)一個整數(shù)。將該指針變量的原值(是一個地址)和它指向的變量所占用的存儲單元的字節(jié)數(shù)相加(減)。2023/2/43:158.4對指針變量的操作指針運算(2)指針變量賦值將一個變量地址賦給一個指針變量不應把一個整數(shù)賦給指針變量2023/2/43:158.4對指針變量的操作指針運算(3)兩個指針變量可以相減如果兩個指針變量都指向同一個數(shù)組中的元素,則兩個指針變量值之差是兩個指針之間的元素個數(shù)2023/2/43:158.4對指針變量的操作指針運算(4)兩個指針變量比較若兩個指針指向同一個數(shù)組的元素,則可以進行比較指向前面的元素的指針變量“小于”指向后面元素的指針變量如果p1和p2不指向同一數(shù)組則比較無意義2023/2/43:158.4對指針變量的操作指針運算(5)指針變量可以有空值,即該指針變量不指向任何變量,可以這樣表示:p=NULL;2023/2/43:15

例8.2輸入a和b兩個整數(shù),按先大后小的順序輸出a和b。解題思路:用指針方法來處理這個問題。不交換整型變量的值,而是交換兩個指針變量的值。2023/2/43:15#include<stdio.h>intmain(){int*p1,*p2,*p,a,b;printf(“integernumbers:");scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(a<b){p=p1;p1=p2;p2=p;}printf(“a=%d,b=%d\n”,a,b);printf(“%d,%d\n”,*p1,*p2);return0;}abp1p2p59&a&b成立2023/2/43:15#include<stdio.h>intmain(){int*p1,*p2,*p,a,b;printf(“integernumbers:");scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(a<b){p=p1;p1=p2;p2=p;}printf(“a=%d,b=%d\n”,a,b);printf(“%d,%d\n”,*p1,*p2);return0;}abp1p2p59&a&b&b&a2023/2/43:15#include<stdio.h>intmain(){int*p1,*p2,*p,a,b;printf(“integernumbers:");scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(a<b){p=p1;p1=p2;p2=p;}printf(“a=%d,b=%d\n”,a,b);printf(“%d,%d\n”,*p1,*p2);return0;}abp1p2p59&a&b&b&a2023/2/43:15#include<stdio.h>intmain(){int*p1,*p2,*p,a,b;printf(“integernumbers:");scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(a<b){p=p1;p1=p2;p2=p;}printf(“a=%d,b=%d\n”,a,b);printf(“%d,%d\n”,*p1,*p2);return0;}abp1p2p59&a&b&b&a可否改為p1=&b;p2=&a;?2023/2/43:15注意:a和b的值并未交換,它們?nèi)员3衷档玴1和p2的值改變了。p1的值原為&a,后來變成&b,p2原值為&b,后來變成&a這樣在輸出*p1和*p2時,實際上是輸出變量b和a的值,所以先輸出9,然后輸出52023/2/43:15

例8.3題目要求同例8.2,即對輸入的兩個整數(shù)按大小順序輸出?,F(xiàn)用函數(shù)處理,而且用指針類型的數(shù)據(jù)作函數(shù)參數(shù)。解題思路:定義一個函數(shù)swap,將指向兩個整型變量的指針變量作為實參傳遞給swap函數(shù)的形參指針變量,在函數(shù)中通過指針實現(xiàn)交換兩個變量的值。2023/2/43:158.5函數(shù)之間地址值的傳遞#include<stdio.h>intmain(){voidswap(int*p1,int*p2);inta,b;int*pointer_1,*pointer_2;printf("pleaseenteraandb:");scanf(“%d,%d”,&a,&b);pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);printf(“max=%d,min=%d\n”,a,b);return0;}abpointer_159&a&bpointer_22023/2/43:15voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}abpointer_159&a&bpointer_2p1&ap2&b952023/2/43:15voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}voidswap(int*p1,int*p2){int*temp;

*temp=*p1;*p1=*p2;*p2=*temp;}錯?。?!無確定的指向2023/2/43:15#include<stdio.h>intmain(){……if(a<b)swap(a,b);printf(“max=%d,min=%d\n”,a,b);return0;}voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}

錯!?。o法交換a,bab59xy59952023/2/43:15如果想通過函數(shù)調(diào)用得到n個要改變的值:①在主調(diào)函數(shù)中設n個變量,用n個指針變量指向它們②設計一個函數(shù),有n個指針形參。在這個函數(shù)中改變這n個形參的值③在主調(diào)函數(shù)中調(diào)用這個函數(shù),在調(diào)用時將這n個指針變量作實參,將它們的地址傳給該函數(shù)的形參④在執(zhí)行該函數(shù)的過程中,通過形參指針變量,改變它們所指向的n個變量的值⑤主調(diào)函數(shù)中就可以使用這些改變了值的變量2023/2/43:15例8.4對輸入的兩個整數(shù)按大小順序輸出。解題思路:嘗試調(diào)用swap函數(shù)來實現(xiàn)題目要求。在函數(shù)中改變形參(指針變量)的值,希望能由此改變實參(指針變量)的值2023/2/43:15#include<stdio.h>intmain(){voidswap(int*p1,int*p2);inta,b;int*pointer_1,*pointer_2;scanf("%d,%d",&a,&b);pointer_1=&a;pointer_2=&b;if(a<b)swap(pointer_1,pointer_2);printf("max=%d,min=%d\n",a,b);return0;}voidswap(int*p1,int*p2){int*p;p=p1;p1=p2;p2=p;}錯?。。≈唤粨Q形參指向2023/2/43:15注意:函數(shù)的調(diào)用可以(而且只可以)得到一個返回值(即函數(shù)值),而使用指針變量作參數(shù),可以得到多個變化了的值。如果不用指針變量是難以做到這一點的。要善于利用指針法。2023/2/43:15

例8.5輸入3個整數(shù)a,b,c,要求按由大到小的順序?qū)⑺鼈冚敵?。用函?shù)實現(xiàn)。解題思路:采用例8.3的方法在函數(shù)中改變這3個變量的值。用swap函數(shù)交換兩個變量的值,用exchange函數(shù)改變這3個變量的值。2023/2/43:15#include<stdio.h>intmain(){voidexchange(int*q1,int*q2,int*q3);inta,b,c,*p1,*p2,*p3;scanf("%d,%d,%d",&a,&b,&c);p1=&a;p2=&b;p3=&c;exchange(p1,p2,p3);printf(“%d,%d,%d\n",a,b,c);return0;}調(diào)用結束后不會改變指針的指向2023/2/43:15voidexchange(int*q1,int*q2,int*q3){voidswap(int*pt1,int*pt2);if(*q1<*q2)swap(q1,q2);if(*q1<*q3)swap(q1,q3);if(*q2<*q3)swap(q2,q3);}voidswap(int*pt1,int*pt2){inttemp;temp=*pt1;*pt1=*pt2;*pt2=temp;}交換指針指向的變量值2023/2/43:15有關指針的小結1.首先要準確地弄清楚指針的含義。指針就是地址,凡是出現(xiàn)“指針”的地方,都可以用“地址”代替,例如,變量的指針就是變量的地址,指針變量就是地址變量要區(qū)別指針和指針變量。指針就是地址本身,而指針變量是用來存放地址的變量。2023/2/43:15有關指針的小結2.什么叫“指向”?地址就意味著指向,因為通過地址能找到具有該地址的對象。對于指針變量來說,把誰的地址存放在指針變量中,就說此指針變量指向誰。但應注意:只有與指針變量的基類型相同的數(shù)據(jù)的地址才能存放在相應的指針變量中。2023/2/43:15有關指針的小結void*指針是一種特殊的指針,不指向任何類型的數(shù)據(jù),如果需要用此地址指向某類型的數(shù)據(jù),應先對地址進行類型轉(zhuǎn)換??梢栽诔绦蛑羞M行顯式的類型轉(zhuǎn)換,也可以由編譯系統(tǒng)自動進行隱式轉(zhuǎn)換。無論用哪種轉(zhuǎn)換,讀者必須了解要進行類型轉(zhuǎn)換2023/2/43:15以下關于地址和指針的敘述中正確的是()

A可以取變量的地址賦值給同類型的指針變量 B可以取常量的地址賦值給同類型的指針變量 C可以取一個指針變量的地址賦給本指針變量,這樣就使得指針變量指向自身 D所有指針變量如果未賦初值,則自動賦空值NULL

參考答案:A【解析】在計算機內(nèi)存中,用一個字節(jié)表示一個內(nèi)存單元并為每一個存儲單元編號,這個編號就是存儲單元的"地址"。一個變量的地址稱為該變量的"指針"。專門用來存放變量地址的變量,稱為"指針變量"。A選項正確。常量存儲在編譯文件中,不能取地址。B選項錯誤。一個指針變量的地址只能賦給指向這種類型的指針變量,與其本身類型不同,不能賦值,C選項錯誤。未賦初值的指針變量自動賦任意地址值,D選項錯誤。2023/2/43:15以下關于指針的敘述正確的是()

A所有類型的指針變量所占內(nèi)存的大小是一樣的 B指針變量所占內(nèi)存的大小與其類型有關,char型指針變量只占1個字節(jié),double型指針變量占8個字節(jié) C指針變量可直接指向任何類型的變量,而不會出現(xiàn)編譯或運行錯誤 D指針變量既可以直接指向結構體,也可直接指向結構體中某個成員,而不會出現(xiàn)編譯或運行錯誤

參考答案:A【解析】專門用來存放變量地址的變量稱為"指針變量",所有地址值所占字節(jié)都是一樣的,故指針變量所占內(nèi)存大小一樣,A選項正確,B選項錯誤。由于一個變量的地址(指針)還隱含有這個變量的類型信息,所以不能隨意把一個地址存放到任何一個指針變量中去,只能把具有相同類型的變量的地址,存放到這個指針變量中,結構體變量與某個成員類型不同,不能用同樣的指針指向它們,C、D選項錯誤。2023/2/43:15以下敘述中正確的是() A如果p是指針變量,則&p是不合法的表達式 B如果p是指針變量,則*p表示變量p的地址值

C在對指針進行加、減算術運算時,數(shù)字1表示1個存儲單元的長度 D如果p是指針變量,則*p+1和*(p+1)的效果是一樣的

參考答案:C【解析】B選項中,如果p是指針變量,則*p表示變量p所指向的地址的值;A選項中,如果p是指針變量,則&p表示變量p的地址;D選項中,如果p是指針變量,*p+1表示將p所指的值加上1,而*(p+1)表示的是先將指針右移一位再取所指向變量的值。因此C選項正確。2023/2/43:15以下敘述中正確的是() A基類型不同的指針變量可以相互混用 B函數(shù)的類型不能是指針類型 C函數(shù)的形參類型不能是指針類型

D設有指針變量為double*p,則p+1將指針p移動8個字節(jié)

參考答案:D【解析】B選項中,所謂函數(shù)類型是指函數(shù)返回值的類型。在C語言中允許一個函數(shù)的返回值是一個指針(即地址),這種返回指針值的函數(shù)稱為指針型函數(shù);C選項中,函數(shù)的參數(shù)不僅可以是整型、實型、字符型等數(shù)據(jù),還可以是指針類型;A選項中,雖然不同基類型的指針變量占用字節(jié)數(shù)是相同的,但是不能混用。因此D選項正確。2023/2/43:15以下敘述中正確的是()

Aint*p1;int**p2;int*p3;都是合法的定義指針變量的語句 B指針變量只能通過求地址運算符(&)來獲得地址值 C語句p=NULL;與p=\0;是等價的語句 D語句p=NULL;執(zhí)行后,指針p指向地址為0的存儲單元 參考答案:A【解析】B選項描述不正確,指針變量可以通過求地址運算符(&)來獲得地址值,可以通過指針變量獲得地址值,還可以通過標準函數(shù)獲得地址值;C選項中,p=NULL;和p=0;或p='\0';等價;D選項中,語句p=NULL;執(zhí)行后,指針p并不是指向地址為0的存儲單元,而是具有一個確定的值-"空"。因此A選項正確。2023/2/43:15以下敘述中正確的是() A即使不進行強制類型轉(zhuǎn)換,在進行指針賦值運算時,指針變量的基類型也可以不同

B如果企圖通過一個空指針來訪問一個存儲單元,將會得到一個出錯信息 C設變量p是一個指針變量,則語句p=0;是非法的,應該使用p=NULL; D指針變量之間不能用關系運算符進行比較 參考答案:B【解析】A選項描述不正確,指針變量的賦值只能賦予地址,決不能賦予任何其它數(shù)據(jù),否則將引起錯誤;C選項中,p=NULL;和p=0;是等價的;D選項中,指向同一數(shù)組的兩指針變量進行關系運算可表示它們所值數(shù)組元素之間的關系。因此B選項正確。2023/2/43:15若在定義語句: inta,b,c,*p=&c;接著執(zhí)行以下選項中的語句,則能正確執(zhí)行的語句是() Ascanf("%d",a,b,c);

Bscanf("%d%d%d",a,b,c);

Cscanf("%d",p); Dscanf("%d",&p);

參考答案:C【解析】本題重點考察的知識點是標準輸入函數(shù)scanf()。scanf()函數(shù)要求,除了第1個參數(shù)為格式化字符串以外,其余參數(shù)均為相應變量的地址值。本題中,只有p是地址值,因此C選項正確。2023/2/43:15若有以下程序 #include<stdio.h> intk=7,m=5; voidf(int**s) {int*t=&k; s=&t;*s=&m;printf("%d,%d,%d,",k,*t,**s);} main() {inti=3,*p=&i,**r=&p; f(r); printf("%d,%d,%d\n",i,*p,**r);}則程序的輸出結果是() A7,5,7,3,5,7, B7,5,7,3,3,3,

C7,5,5,3,3,3, D7,7,5,3,3,3, 參考答案:C【解析】在主函數(shù)中首先初始化整型變量i,將i的地址賦給指針變量p,再將指針變量p的地址賦給指向指針的指針變量r;調(diào)用f函數(shù),將變量r的值傳遞給變量s;由于k和m分別賦值7和5,printf("%d,%d,%d,",k,*t,**s);,即結果為7,5,5;返回主函數(shù),printf("%d,%d,%d\n",i,*p,**r);,即結果為3,3,3?因此C選項正確?2023/2/43:15有以下程序 #include<stdio.h> main() {intm=1,n=2,*p=&m,*q=&n,*r;

溫馨提示

  • 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

提交評論