




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第八章善于利用指針學(xué)習(xí)目標1.了解指針與地址的概念。2.掌握指針變量的定義、初始化及指針的運算。3.理解指針與數(shù)組本質(zhì)聯(lián)系,能用指針處理數(shù)組。4.掌握利用指針處理字符串的方法。5.了解指向函數(shù)的指針。6.掌握返回指針值的函數(shù)。7.掌握指針數(shù)組及應(yīng)用。8.掌握動態(tài)內(nèi)存分配及指向它的指針。教學(xué)重點與難點重點:指針的概念;指針與數(shù)組元素地址的內(nèi)在關(guān)系;使用指針處理數(shù)組;指針處理字符串;返回指針值的函數(shù);指針數(shù)組;動態(tài)內(nèi)存分配。難點:指針的概念;指針與數(shù)組元素之間的地址對應(yīng)關(guān)系;使用指針處理數(shù)組;返回指針值的函數(shù);指針數(shù)組;動態(tài)內(nèi)存分配。指針是C語言的靈魂可以為直接訪問計算機硬件提供了便捷的方法,是進行計算機系統(tǒng)軟件設(shè)計所不可缺少的。掌握C語言中的指針及相關(guān)概念、使用方法是學(xué)好C語言和實際應(yīng)用所必須的,同時指針的使用有時是危險的,錯誤的指針操作輕則影響程序結(jié)果的正確性,重則導(dǎo)致系統(tǒng)癱瘓。8.1指針是什么內(nèi)存區(qū)的每一個字節(jié)有一個編號,這就是“地址”,它相當于旅館中的房間號。在地址所標識的內(nèi)存單元中存放數(shù)據(jù),這相當于旅館房間中居住的旅客一樣。將地址形象化地稱為“指針”。在C語言中,編譯過程將每一個變量都要轉(zhuǎn)化成一個相應(yīng)的內(nèi)存單元地址。程序?qū)?nèi)存變量的訪問其實是通過對內(nèi)存地址所指的內(nèi)存單元中的內(nèi)容的訪問來達到。8.1指針是什么i200032000i_pointer*i_pointer20003直接存取間接存取內(nèi)存變量、指針、地址(指針)、變量值的關(guān)系8.2.1
使用指針變量變量的地址就是變量的指針,那什么是指針變量呢?指針變量是用于存放變量地址的變量,其作用是指向一個變量。變量本身有不同的數(shù)據(jù)類型。根據(jù)指針變量所指向變量的數(shù)據(jù)類型的不同,指針變量也可分為相應(yīng)的數(shù)據(jù)類型。8.2.2怎樣定義指針變量定義指針變量的一般形式為:
類型*指針變量名;如:int*pointer_1,*pointer_2;int是為指針變量指定的“基類型”基類型指定指針變量可指向的變量類型如pointer_1可以指向整型變量,但不能指向浮點型變量下面都是合法的定義和初始化: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;錯誤8.2.2怎樣定義指針變量8.2.3怎樣引用指針變量在引用指針變量時,可能有三種情況:給指針變量賦值。如:p=&a;引用指針變量指向的變量。如有
p=&a;*p=1;
則執(zhí)行printf(“%d”,*p);將輸出1引用指針變量的值。如:printf(“%o”,p);使p指向a*p相當于a以八進制輸出a的地址要熟練掌握兩個有關(guān)的運算符:(1)&
取地址運算符。用于獲取變量的地址。如&a是變量a的地址(2)*指針運算符(“間接訪問”運算符)用于獲取所指變量的值。
8.2.3怎樣引用指針變量&運算和*運算定義inti=3;int*j;j=&i;//設(shè)i的地址為2012則內(nèi)存中的狀況如下圖所示:32012*j的值是多少?&i的值是多少?&*j的值是多少?*&i的值是多少?例8.1通過指針變量訪問整型變量。解題思路:先定義2個整型變量,再定義2個指針變量,分別指向這兩個整型變量,通過訪問指針變量,可以找到它們所指向的變量,從而得到這些變量的值。#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的值
例8.2輸入a和b兩個整數(shù),按先大后小的順序輸出a和b。解題思路:用指針方法來處理這個問題。不交換整型變量的值,而是交換兩個指針變量的值。#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;}8.2.4指針變量作為函數(shù)參數(shù)
例8.3題目要求同例8.2,即對輸入的兩個整數(shù)按大小順序輸出?,F(xiàn)用函數(shù)處理,而且用指針類型的數(shù)據(jù)作函數(shù)參數(shù)。解題思路:定義一個函數(shù)swap,將指向兩個整型變量的指針變量作為實參傳遞給swap函數(shù)的形參指針變量,在函數(shù)中通過指針實現(xiàn)交換兩個變量的值。#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;}voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}abpointer_159&a&bpointer_2p1&ap2&b95voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}voidswap(int*p1,int*p2){int
*temp;
*temp=*p1;*p1=*p2;*p2=*temp;}錯!??!無確定的指向#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;}
錯!??!無法交換a,bab59xy5995例8.4對輸入的兩個整數(shù)按大小順序輸出。解題思路:嘗試調(diào)用swap函數(shù)來實現(xiàn)題目要求。在函數(shù)中改變形參(指針變量)的值,希望能由此改變實參(指針變量)的值#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;}錯?。?!只交換形參指向在主調(diào)函數(shù)中設(shè)置n個變量,并用n個指針分別指向它們;將n個指針變量作為函數(shù)實參,傳遞給函數(shù)形參(地址傳遞);通過形參指針變量改變這些變量的值;主調(diào)函數(shù)中相應(yīng)變量值已被改變,可以重新使用。指針作函數(shù)參數(shù)返回多個值的方法
例8.5輸入3個整數(shù)a,b,c,要求按由大到小的順序?qū)⑺鼈冚敵?。用函?shù)實現(xiàn)。解題思路:采用例8.3的方法在函數(shù)中改變這3個變量的值。用swap函數(shù)交換兩個變量的值,用exchange函數(shù)改變這3個變量的值。#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)用結(jié)束后不會改變指針的指向voidexchange(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;}交換指針指向的變量值8.3.1數(shù)組元素的指針一個變量有地址,一個數(shù)組包含若干元素,每個數(shù)組元素都有相應(yīng)的地址指針變量可以指向數(shù)組元素(把某一元素的地址放到一個指針變量中)所謂數(shù)組元素的指針就是數(shù)組元素的地址8.3數(shù)組的指針可以用一個指針變量指向一個數(shù)組元素
inta[10]={1,3,5,7,9,11,13,15,17,19};int*p;p=&a[0];等價于p=a;等價于int*p=a;或int*p=&a[0];注意:數(shù)組名a不代表整個數(shù)組,只代表數(shù)組首元素的地址?!皃=a;”的作用是“把a數(shù)組的首元素的地址賦給指針變量p”,而不是“把數(shù)組a各元素的值賦給p”。數(shù)組名不可被賦值;數(shù)組名常可用于初始化一個指針;數(shù)組名所代表的地址不能修改,否則會丟失數(shù)組空間。8.3.2引用數(shù)組元素時指針的運算數(shù)組定義后,則各數(shù)組元素依次存儲且位置固定。所以在指針指向數(shù)組元素時,允許以下運算:加一個整數(shù)(用+或+=),如p+1減一個整數(shù)(用-或-=),如p-1自加運算,如p++,++p自減運算,如p--,--p兩個指針相減,如p1-p2(只有p1和p2都指向同一數(shù)組中的元素時才有意義)(1)如果指針變量p已指向數(shù)組中的一個元素,則p+1指向同一數(shù)組中的下一個元素,p-1指向同一數(shù)組中的上一個元素。
floata[10],*p=a;
假設(shè)a[0]的地址為2000,則p的值為2000p+1的值為2004p-1的值為1996越界(2)如果p的初值為&a[0],則p+i和a+i就是數(shù)組元素a[i]的地址,或者說,它們指向a數(shù)組序號為i的元素。a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]pp+1,a+1p+i,a+ip+9,a+9(3)*(p+i)或*(a+i)是p+i或a+i所指向的數(shù)組元素,即a[i]。a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]pp+1,a+1p+i,a+ip+9,a+9*(p+i)a++、a--行不行?(4)如果指針p1和p2都指
向同一數(shù)組
p2-p1的值是4
不能p1+p2a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]p1p28.3.3通過指針引用數(shù)組元素引用一個數(shù)組元素,可用下面兩種方法:
(1)下標法
如a[i]形式。
(2)指針法
如*(a+i)或*(p+i)
其中a是數(shù)組名,p是指向數(shù)組元素的指針變量,其初值p=a
例8.6有一個整型數(shù)組a,有10個元素,要求輸出數(shù)組中的全部元素。解題思路:引用數(shù)組中各元素的值有3種方法:(1)下標法;(2)通過數(shù)組名計算數(shù)組元素地址,找出元素的值;(3)用指針變量指向數(shù)組元素分別寫出程序,以便比較分析。8.3.3通過指針引用數(shù)組元素(1)下標法。
#include<stdio.h>intmain(){inta[10];inti;printf(“enter10integernumbers:\n");for(i=0;i<10;i++)scanf("%d",&a[i]);for(i=0;i<10;i++)printf("%d",a[i]);printf("%\n");return0;}(2)通過數(shù)組名計算數(shù)組元素地址,找出元素的值#include<stdio.h>intmain(){inta[10];inti;printf("enter10integernumbers:\n");for(i=0;i<10;i++)scanf("%d",&a[i]);for(i=0;i<10;i++)printf("%d",*(a+i));printf("\n");return0;}scanf("%d",a+i);(3)用指針變量指向數(shù)組元素#include<stdio.h>intmain(){inta[10];int*p,i;printf("enter10integernumbers:\n");for(i=0;i<10;i++)scanf("%d",&a[i]);for(p=a;p<(a+10);p++)printf("%d",*p);printf("\n");return0;}3種方法的比較:①第(1)和第(2)種方法執(zhí)行效率相同②第(3)種方法比第(1)、第(2)種方法快③用下標法比較直觀,能直接知道是第幾個元素。
例8.7通過指針變量輸出整型數(shù)組a的10個元素。解題思路:
用指針變量p指向數(shù)組元素,通過改變指針變量的值,使p先后指向a[0]到a[9]各元素。#include<stdio.h>intmain(){int*p,i,a[10];p=a;printf("enter10integernumbers:\n");for(i=0;i<10;i++)scanf("%d",p++);for(i=0;i<10;i++,p++)printf("%d",*p);printf("\n");return0;}退出循環(huán)時p指向a[9]后面的存儲單元因此執(zhí)行此循環(huán)出問題重新執(zhí)行p=a;8.3.4用數(shù)組名作函數(shù)參數(shù)用數(shù)組名作函數(shù)參數(shù)時,實參與形參都可以是數(shù)組名或指向數(shù)組的指針變量。所以實參向形參傳遞數(shù)據(jù)時,會有四種不同的傳遞方式。實參形參數(shù)組名數(shù)組名指針指針例8.8將數(shù)組a中n個整數(shù)按相反順序存放解題思路:將a[0]與a[n-1]對換,……將a[4]與a[5]對換。ji#include<stdio.h>intmain(){voidinv(intx[],intn);inti,a[10]={3,7,9,11,0,6,7,5,4,2};for(i=0;i<10;i++)printf("%d",a[i]);printf("\n");inv(a,10);for(i=0;i<10;i++)printf("%d",a[i]);printf("\n");return0;}voidinv(intx[],intn){inttemp,i,j,m=(n-1)/2;for(i=0;i<=m;i++){j=n-1-i;temp=x[i];x[i]=x[j];x[j]=temp; }}voidinv(intx[],intn){inttemp,*i,*j;i=x;j=x+n-1;for(;i<j;i++,j--){temp=*i;*i=*j;*j=temp;}}優(yōu)化例8.9改寫例8.8,用指針變量作實參。#include<stdio.h>intmain(){voidinv(int*x,intn);inti,arr[10],*p=arr;for(i=0;i<10;i++,p++)scanf(“%d”,p);inv(p,10);for(p=arr;p<arr+10;p++)printf("%d",*p);printf("\n");return0;}不可少?。?!
例8.10用指針方法對10個整數(shù)按由大到小順序排序。解題思路:在主函數(shù)中定義數(shù)組a存放10個整數(shù),定義int*型指針變量p指向a[0]。定義函數(shù)sort使數(shù)組a中的元素按由大到小的順序排列。在主函數(shù)中調(diào)用sort函數(shù),用指針p作實參。用選擇法進行排序。#include<stdio.h>intmain(){voidsort(intx[],intn);inti,*p,a[10];p=a;for(i=0;i<10;i++)scanf("%d",p++);
p=a;
sort(p,10);for(p=a,i=0;i<10;i++){printf("%d",*p);p++;}printf("\n");return0;}voidsort(intx[],intn){inti,j,k,t;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(x[j]>x[k])k=j;if(k!=i) {t=x[i];x[i]=x[k];x[k]=t;}}}voidsort(int*x,intn)if(*(x+j)>*(x+k))k=j;{t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;}1.多維數(shù)組元素的地址
inta[3][4]={{1,3,5,7},
{9,11,13,15},{17,19,21,23}};1357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指針列指針8.3.5通過指針引用多維數(shù)組a+i代表行號為i的行首地址(按行變化)*(a+i)代表什么?1357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指針列指針相當于a[i]a[0]代表a[0][0]的地址a[0]+1代表a[0][1]的地址a[0]+2代表a[0][2]的地址a[0]+3代表a[0][3]的地址1357911131517192123a[0]a[1]a[2]aa+1a+2a[0]a[0]+1a[0]+2a[0]+3行指針列指針列指針每加1,走一列1.
三行首地址分別為:a[0]→a→*(a+0)→&a[0]→&a[0][0]a[1]→a+1→*(a+1)→&a[1]→&a[1][0]a[2]→a+2→*(a+2)→&a[2]→&a[2][0]2.列地址的訪問:a[][0]a[][1]a[][2]↓↓↓*(a+0)+0、a[0]+0*(a+0)+1、a[0]+1*(a+0)+2、a[0]+2*(a+1)+0、a[1]+0*(a+1)+1、a[1]+1*(a+1)+2、a[1]+2*(a+2)+0、a[2]+0*(a+2)+1、a[2]+1*(a+2)+2、a[2]+23.元素值訪問方法(以a[i][j]為例)(1)*(a[i]+j)(2)a[i][j](3)*(*(a+i)+j)二維數(shù)組各元素地址及訪問方法2.指向多維數(shù)組元素的指針變量(1)指向數(shù)組元素的指針變量順序訪問方法:指針變量指向二維數(shù)組中首行的起始地址,通過指針的增、減運算來依次訪問數(shù)組中的元素。隨機訪問方法:指針變量指向二維數(shù)組中首行的起始地址,可計算出數(shù)組元素在數(shù)組中的相對位置,再利用指針p指向該元素即可進行訪問。
a[i][j]的地址為:p+i*m+j
例8.12有一個3×4的二維數(shù)組,要求用指向元素的指針變量輸出二維數(shù)組各元素的值。#include<stdio.h>intmain(){inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};int*p;for(p=a[0];p<a[0]+12;p++){if((p-a[0])%4==0)printf("\n");printf("%4d",*p);}printf("\n");return0;}控制換行逐個訪問各元素時常用此類指針(2)指向由m個元素組成的一維數(shù)組的指針變量
數(shù)據(jù)類型(*指針變量名)[下標];此時,可認為二維數(shù)組是由n行組成的,只需將指針定義為(*p)[m]即可通過指針運算來訪問數(shù)組元素。特別要注意的是以下兩種表示方法的不同:(*p)[m]:包含m個元素的一維數(shù)組的指針變量;*p[m]:指針數(shù)組,一個由m個指針元素組成的指針數(shù)組;
a[i][j]訪問方法:*(*(p+i)+j)例8.13輸出二維數(shù)組任一行任一列元素的值。解題思路:假設(shè)仍然用例8.12程序中的二維數(shù)組,例8.12中定義的指針變量是指向變量或數(shù)組元素的,現(xiàn)在改用指向一維數(shù)組的指針變量。#include<stdio.h>intmain(){inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int(*p)[4],i,j;p=a;printf("enterrowandcolum:");scanf("%d,%d",&i,&j);printf("a[%d,%d]=%d\n",i,j,*(*(p+i)+j));return0;}行指針a[i][j]3.多維數(shù)組作函數(shù)參數(shù)與一維數(shù)組的相同點:可用指向變量的指針變量進行參數(shù)傳遞(一級指針方式);與一維數(shù)組的不同點:可用指向一維數(shù)組的指針變量進行參數(shù)傳遞(二級指針方式);其它要求相同。例8.14有一個班,3個學(xué)生,各學(xué)4門課,計算總平均分數(shù)以及第n個學(xué)生的成績。
解題思路:用指向數(shù)組的指針作函數(shù)參數(shù)。用函數(shù)average求總平均成績,用函數(shù)search找出并輸出第i個學(xué)生的成績。#include<stdio.h>intmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};average(*score,12);search(score,2);return0;}score[0][0]的地址voidaverage(float*p,intn){float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("av
溫馨提示
- 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)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 電磁波的基本知識與應(yīng)用試題及答案
- 初中物理考試浮力相關(guān)題目及解答及答案
- 《4 給植物畫張“像”》(教學(xué)設(shè)計)-2024-2025學(xué)年教科版科學(xué)一年級上冊
- 2024年小自考行政管理試題總覽及答案
- 公共事業(yè)管理重點考點試題及答案
- 調(diào)酒師職業(yè)生涯中的心理素質(zhì)訓(xùn)練試題及答案
- 商業(yè)分析師考試方法論試題及答案
- 小自考公共事業(yè)管理復(fù)習(xí)重點試題及答案
- 2024年CPBA考試資料準備清單試題及答案
- 視覺傳播設(shè)計與制作課程試題及答案
- 2024年供應(yīng)鏈管理師(二級)資格考試復(fù)習(xí)題庫(含答案)
- 低空經(jīng)濟產(chǎn)業(yè)園項目可行性研究報告
- 樹木轉(zhuǎn)讓合同范例
- 湖北省十一校2024-2025學(xué)年高三上學(xué)期第一次聯(lián)考化學(xué)試題 含解析
- 3D打?。簭脑淼絼?chuàng)新應(yīng)用知到智慧樹期末考試答案題庫2024年秋浙江大學(xué)
- 2024年經(jīng)典實習(xí)期勞動合同范本
- 無人機租賃的合同范本
- 《中國急性腎損傷臨床實踐指南(2023版)》解讀
- GB 21258-2024燃煤發(fā)電機組單位產(chǎn)品能源消耗限額
- 建筑CAD賽項樣題-繪圖樣題
- 《鋼鐵是怎樣煉成的》讀書分享 課件
評論
0/150
提交評論