《C語(yǔ)言程序設(shè)計(jì)(第2版)》第11章指針進(jìn)階_第1頁(yè)
《C語(yǔ)言程序設(shè)計(jì)(第2版)》第11章指針進(jìn)階_第2頁(yè)
《C語(yǔ)言程序設(shè)計(jì)(第2版)》第11章指針進(jìn)階_第3頁(yè)
《C語(yǔ)言程序設(shè)計(jì)(第2版)》第11章指針進(jìn)階_第4頁(yè)
《C語(yǔ)言程序設(shè)計(jì)(第2版)》第11章指針進(jìn)階_第5頁(yè)
已閱讀5頁(yè),還剩47頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

Chap

11指針進(jìn)階11.1奧運(yùn)五環(huán)色11.2字符定位11.3用鏈表構(gòu)建學(xué)生信息庫(kù)本章要點(diǎn)指針數(shù)組和指向指針的指針是如何被定義和使用的?指針如何作為函數(shù)的返回值?指向函數(shù)的指針的意義是什么?什么是結(jié)構(gòu)的遞歸定義,哪種應(yīng)用需要這種定義方法?對(duì)鏈表這種數(shù)據(jù)結(jié)構(gòu),如何使用動(dòng)態(tài)內(nèi)存分配操作?如何建立單向鏈表并實(shí)現(xiàn)插入、刪除以及查找操作?11.1奧運(yùn)五環(huán)色

11.1.1程序解析11.1.2指針數(shù)組的概念11.1.3指向指針的指針11.1.4用指針數(shù)組處理多個(gè)字符串*11.1.5命令行參數(shù)11.1.1程序解析【例11-1】已知奧運(yùn)五環(huán)的5種顏色的英文單詞按一定順序排列,輸入任意一個(gè)顏色的英文單詞,從已有顏色中查找并輸出該顏色的位置值,若沒(méi)有找到,則輸出“NotFound”。11.1.1程序解析#include<stdio.h>#include<string.h>int

main(void){inti;char*color[5]={“red”,”blue”,”yellow”,”green”,”black”};charstr[20];

printf(“Inputacolor:”);

scanf(“%s”,str);

for(i=0;i<5;i++)

if(strcmp(str,color[i])==0)/*比較顏色是否相同*/break;

if(i<5)

printf(“position:%d\n”,i+1);else

printf(“NotFound\n”);return0;}運(yùn)行結(jié)果1Inputacolor:yellowposition:3運(yùn)行結(jié)果2Inputacolor:purpleNotFound

指針數(shù)組11.1.2指針數(shù)組的概念C語(yǔ)言中的數(shù)組可以是任何類型,如果數(shù)組的各個(gè)元素都是指針類型,用于存放內(nèi)存地址,那么這個(gè)數(shù)組就是指針數(shù)組。一維指針數(shù)組定義的一般格式為:類型名*數(shù)組名[數(shù)組長(zhǎng)度]11.1.2指針數(shù)組的概念inta[10];a是一個(gè)數(shù)組,它有10個(gè)元素每個(gè)元素的類型都是整型char*color[5];color是一個(gè)數(shù)組,它有5個(gè)元素每個(gè)元素的類型都是字符指針11.1.2指針數(shù)組的概念char*color[5]={"red","blue","yellow","green","black"

};color是一個(gè)數(shù)組,它有5個(gè)元素每個(gè)元素的類型都是字符指針數(shù)組元素可以處理字符串對(duì)指針數(shù)組元素的操作:printf("%s%x\n",color[i],color[i]);對(duì)指針數(shù)組元素的操作和對(duì)同類型指針變量的操作相同

繼續(xù)執(zhí)行:char*tmp;

tmp=color[0];color[0]=color[4];color[4]=tmp;

11.1.2指針數(shù)組的概念

color[0]與color[4]交換后的情況

指針數(shù)組操作時(shí):可以直接對(duì)數(shù)組元素進(jìn)行賦值(地址值)和引用

tmp=color[0];也可以間接訪問(wèn)和操作數(shù)組元素所指向的單元內(nèi)容

strcpy(color[0],“purple");11.1.3指向指針的指針C語(yǔ)言中,指向指針的指針(二級(jí)指針)一般定義為:

類型名**變量名

inta=10;

int*p=&a;

int**pp=&p;&apa10&ppp*p*pp**pp&apaa10&pappa**ppa*pa&bpbb20&pbppb**ppb*pbpaappa&a10&pb**ppb*pa&bpbb20&pappb**ppa*pbpaappa&b10&pb**ppa*pb&apbb20&pappb**ppb*papaappa&b20&pb**ppa*pb&apbb10&pappb**ppb*painta=10,b=20,t;int*pa=&a,*pb=&b,*pt;int**ppa=&pa,**ppb=&pb,**ppt;【例11-2】操作(1):ppt=ppb;ppb=ppa;ppa=ppt;操作(2):pt=pb;pb=pa;pa=pt;操作(3):t=b;b=a;a=t;【例11-3】改寫例11-1,用指向指針的指針實(shí)現(xiàn)。

#include<stdio.h>#include<string.h>int

main(void){inti;char*color[5]={“red”,”blue”,”yellow”,”green”,”black”};/char**pc;/*定義二級(jí)指針變量*/charstr[20];

pc=color;/*二級(jí)指針賦值*/

printf(“Inputacolor:”);

scanf(“%s”,str);

for(i=0;i<5;i++)

if(strcmp(str,*(pc+i))==0)/*比較顏色是否相同*/break;

if(i<5)

printf(“position:%d\n”,i+1);else

printf(“NotFound\n”);return0;}11.1.3指向指針的指針指向指針的指針使用指向指針的指針操作數(shù)據(jù)11.1.3指向指針的指針【例11-3】改寫例11-1,用指向指針的指針實(shí)現(xiàn)。

pccolor&color[0]*pccolor[0]*(pc+i)color[i]**pc*(*pc)*color[0]:‘r’1.指針數(shù)組與二維數(shù)組二維字符數(shù)組charccolor[][7]={"red","blue","yellow","green",“black"};11.1.4用指針數(shù)組處理多個(gè)字符串使用指針數(shù)組更節(jié)省內(nèi)存空間指針數(shù)組char*pcolor[]={"red","blue","yellow","green",“black"};11.1.4用指針數(shù)組處理多個(gè)字符串2.用指針數(shù)組操作多個(gè)字符串【例11-4】將5個(gè)字符串從小到大排序后輸出。voidmain(){inti;

int

a[5]={6,5,2,8,1};

voidfsort(inta[],intn);

fsort(a,5);

for(i=0;i<5;i++)

printf("%d",a[i]);}#include<string.h>voidmain(){inti;char

*pcolor[]={“red”,”blue”,”yellow”,”green”,”black”};

voidfsort(char*color[],intn);

fsort(pcolor,5);

for(i=0;i<5;i++)

printf("%s",pcolor[i]);}11.1.4用指針數(shù)組處理多個(gè)字符串voidfsort(inta[],intn){intk,j;

inttemp;

for(k=1;k<n;k++)

for(j=0;j<n-k;j++)

if(a[j]>a[j+1]){temp=a[j];

a[j]=a[j+1];a[j+1]=temp;}}voidfsort(char*color[],intn){intk,j;char*temp;

for(k=1;k<n;k++)

for(j=0;j<n-k;j++)

if(strcmp(color[j],color[j+1])>0){temp=color[j];

color[j]=color[j+1];color[j+1]=temp;}}排序前排序后11.1.4用指針數(shù)組處理多個(gè)字符串11.1.4用指針數(shù)組處理多個(gè)字符串3.動(dòng)態(tài)輸入多個(gè)字符串例11-5輸入一些有關(guān)顏色的單詞,每行一個(gè),以#作為輸入結(jié)束標(biāo)志,再按輸入的相反次序輸出這些單詞。其中單詞數(shù)小于20,每個(gè)單詞不超過(guò)15個(gè)字母(用動(dòng)態(tài)分配內(nèi)存的方法處理多個(gè)字符串的輸入)。#include<stdio.h>#include<stdlib.h>#include<string.h>int

main(void){

inti,n=0;char*color[20],str[15];

scanf("%s",str);while(str[0]!='#'){

color[n]=(char*)malloc(sizeof(char)*(strlen(str)+1));/*動(dòng)態(tài)分配*/

strcpy(color[n],str);/*將輸入的字符串賦值給動(dòng)態(tài)內(nèi)存單元*/ n++;

scanf("%s",str);}

for(i=n-1;i>=0;i--)

printf("%s",color[i]);return0;}運(yùn)行結(jié)果:redblueyellow#yellow

bluered

采用動(dòng)態(tài)分配內(nèi)存的方法處理多個(gè)字符串的輸入的優(yōu)點(diǎn)在于,能夠根據(jù)實(shí)際輸入數(shù)據(jù)的多少來(lái)申請(qǐng)和分配內(nèi)存空間,從而提高了內(nèi)存的使用率。11.1.4用指針數(shù)組處理多個(gè)字符串4.對(duì)指針數(shù)組的進(jìn)一步討論char*color[]={“red”,”blue”,”yellow”,”green”,”black”};數(shù)組名color代表數(shù)組首元素color[0]的地址,是指向指針的指針(二級(jí)指針)color+2指向color[2],*(color+2)和color[2]等價(jià)color[0]指向字符串"red"的首字符r,color[0]+2指向首字符r后的第2個(gè)字符d11.1.4用指針數(shù)組處理多個(gè)字符串4.對(duì)指針數(shù)組的進(jìn)一步討論

color[k]*(color+k)

printf("%s",color[2]);

printf("%s",*(color+2));*(color[k]+j)

*(*(color+k)+j)

color[k][j]

printf("%c%c",*(color[2]),*(color[2]+2));

printf("%c%c",color[2][0],color[2][2]);

例11-6解密藏頭詩(shī)。所謂藏頭詩(shī),就是將一首詩(shī)每一句的第一個(gè)字連起來(lái),所組成的內(nèi)容就是該詩(shī)的真正含義。編寫程序,輸出一首藏頭詩(shī)的真實(shí)含義。

一葉輕舟向東流,

帆梢輕握楊柳手,

風(fēng)纖碧波微起舞,

順?biāo)螐难趴陀啤?1.1.4用指針數(shù)組處理多個(gè)字符串#include<stdio.h>char*change(chars[][20]);int

main(void){inti;char*poem[4]={"一葉輕舟向東流,","帆梢輕握楊柳手,","風(fēng)纖碧波微起舞,","順?biāo)螐难趴陀啤?};/*指針數(shù)組初始化*/charmean[10];for(i=0;i<4;i++){/*每行取第1個(gè)漢字存入mean*/

mean[2*i]=*(poem[i]);mean[2*i+1]=*(poem[i]+1);}

mean[2*i]=’\0’;

printf("%s\n",mean);/*輸出結(jié)果*/return0;}11.1.4用指針數(shù)組處理多個(gè)字符串*11.1.5命令行參數(shù)C語(yǔ)言源程序經(jīng)編譯和連接處理,生成可執(zhí)行程序(例如test.exe)后,才能運(yùn)行。在DOS環(huán)境的命令窗口中,輸入可執(zhí)行文件名,就以命令方式運(yùn)行該程序。輸入命令時(shí),在可執(zhí)行文件(命令)名的后面可以跟一些參數(shù),這些參數(shù)被稱為命令行參數(shù)

testworld

(test是命令名,world是命令行參數(shù))*11.1.5命令行參數(shù)命令行的一般形式為:

命令名參數(shù)1參數(shù)2

…參數(shù)n使用命令行的程序不能在編譯器中執(zhí)行,需要將源程序經(jīng)編譯、鏈接為相應(yīng)的命令文件(一般以.exe為后綴),然后回到命令行狀態(tài),再在該狀態(tài)下直接輸入命令文件名。命令名和各個(gè)參數(shù)之間用空格分隔,也可以沒(méi)有參數(shù)*11.1.5命令行參數(shù)帶參數(shù)的main()函數(shù)格式:

int

main(int

argc,char*argv[]){......}第1個(gè)參數(shù)argc接收命令行參數(shù)(包括命令名)的個(gè)數(shù);第2個(gè)參數(shù)argv接收以字符串常量形式存放的命令行參數(shù)(包括命令名本身也作為一個(gè)參數(shù))。*11.1.5命令行參數(shù)【例11-7】編寫C程序echo,它的功能是將所有命令行參數(shù)在同一行上輸出。#include<stdio.h>int

main(int

argc,char*argv[]){

intk;

for(k=1;k<argc;k++) /*從第1個(gè)命令行參數(shù)開始*/

printf("%s",argv[k]); /*打印命令行參數(shù)*/

printf("\n");return0;}運(yùn)行結(jié)果在命令行狀態(tài)下輸入:echoHowareyou?輸出:Howareyou?11.2字符定位

11.2.1程序解析11.2.2指針作為函數(shù)的返回值*11.2.3指向函數(shù)的指針11.2.1程序解析例11-8輸入一個(gè)字符串和一個(gè)字符,如果該字符在字符串中,就從該字符首次出現(xiàn)的位置開始輸出字符串中的字符。例如,輸入字符r和字符串program后,輸出rogram。要求定義函數(shù)match(s,ch),在字符串s中查找字符ch,如果找到,返回第一次找到的該字符在字符串中的位置(地址);否則,返回空指針NULL。#include<stdio.h>char*match(char*s,charch) /*函數(shù)返回值的類型是字符指針*/{while(*s!='\0')if(*s==ch)return(s);/*若找到字符ch,返回相應(yīng)的地址*/elses++;

return(NULL); /*沒(méi)有找到ch,返回空指針*/}int

main(void){charch,str[80],*p=NULL;

printf(“PleaseInputthestring:\n”); /*提示輸入字符串*/

scanf("%s",str);

getchar();/*跳過(guò)輸入字符串和輸入字符之間的分隔符*/

ch=getchar(); /*輸入一個(gè)字符*/

if((p=match(str,ch))!=NULL)/*調(diào)用函數(shù)match()*/

printf("%s\n",p);else

printf("NotFound\n");return0;}運(yùn)行結(jié)果1PleaseInputthestring:Universityvversity運(yùn)行結(jié)果2PleaseInputthestring:schoolaNotFound函數(shù)match()返回一個(gè)地址(指針)。在主函數(shù)中,用字符指針p接收match()返回的地址,從p指向的存儲(chǔ)單元開始,連續(xù)輸出其中的內(nèi)容,直至'\0'為止。

11.2.1程序解析11.2.2指針作為函數(shù)的返回值函數(shù)返回值的類型整型浮點(diǎn)型字符型結(jié)構(gòu)類型指針(返回一個(gè)地址)在C語(yǔ)言中,函數(shù)返回值也可以是指針,定義和調(diào)用這類函數(shù)的方法與其他函數(shù)是一樣的。思考:在例11-8中,如果將str的定義及相應(yīng)的數(shù)據(jù)輸入都放在函數(shù)match()中,結(jié)果會(huì)如何?char*match(){charch,str[80],*s=str;/*定義局部字符數(shù)組*/

printf("PleaseInputthestring:\n"); /*輸入*/

scanf("%s",str);

getchar();

ch=getchar();while(*s!='\0') if(*s==ch)returns;/*返回局部字符數(shù)組地址*/elses++;

return(NULL);}不能返回在函數(shù)內(nèi)部定義的局部數(shù)據(jù)對(duì)象的地址,這是因?yàn)樗械木植繑?shù)據(jù)對(duì)象在函數(shù)返回時(shí)就會(huì)消亡,其值不再有效11.2.2指針作為函數(shù)的返回值返回指針的函數(shù)一般都返回全局?jǐn)?shù)據(jù)對(duì)象或主調(diào)函數(shù)中數(shù)據(jù)對(duì)象的地址*11.2.3指向函數(shù)的指針每個(gè)函數(shù)都占用一段內(nèi)存單元,它們有一個(gè)入口地址(起始地址)在C語(yǔ)言中,函數(shù)名代表函數(shù)的入口地址。我們可以定義一個(gè)指針變量,接收函數(shù)的入口地址,讓它指向函數(shù),這就是指向函數(shù)的指針,也稱為函數(shù)指針。通過(guò)函數(shù)指針可以調(diào)用函數(shù),它也可以作為函數(shù)的參數(shù)。指令1指令2指令3…指令n入口地址*11.2.3指向函數(shù)的指針1.函數(shù)指針的定義函數(shù)指針定義的一般格式為:

類型名(*變量名)(參數(shù)類型表);類型名指定函數(shù)返回值的類型,變量名是指向函數(shù)的指針變量的名稱。例如:int(*funptr)(int,int);定義一個(gè)函數(shù)指針funptr,它可以指向有兩個(gè)整型參數(shù)且返回值類型為int的函數(shù)。*11.2.3指向函數(shù)的指針2.通過(guò)函數(shù)指針調(diào)用函數(shù)通過(guò)函數(shù)指針調(diào)用函數(shù)的一般格式為:

(*函數(shù)指針名)(參數(shù)表)例如:int

fun(intx,inty);int(*funptr)(int,int);funptr=fun;(*funptr)(3,5);*11.2.3指向函數(shù)的指針3.函數(shù)指針作為函數(shù)的參數(shù)C語(yǔ)言的函數(shù)調(diào)用中,函數(shù)名或已賦值的函數(shù)指針也能作為實(shí)參,此時(shí),形參就是函數(shù)指針,它指向?qū)崊⑺砗瘮?shù)的入口地址。例如:f(int(*funptr)(int,int)){…}voidmain(){…

int(*funptr)(int,int);

funptr=fun;f(funptr);…}*11.2.3指向函數(shù)的指針【例11-9】編寫一個(gè)函數(shù)calc(f,a,b),用梯形公式求函數(shù)f(x)在[a,b]上的數(shù)值積分。然后調(diào)用該函數(shù)計(jì)算下列數(shù)值積分。(函數(shù)指針作為函數(shù)參數(shù)示例)

分析:calc()是一個(gè)通用函數(shù),用梯形公式求解數(shù)值積分。它和被積函數(shù)f(x)以及積分區(qū)間[a,b]有關(guān),相應(yīng)的形參包括函數(shù)指針、積分區(qū)間上下限參數(shù)。在函數(shù)調(diào)用時(shí),把被積函數(shù)的名稱(或函數(shù)指針)和積分區(qū)間的上下限作為實(shí)參。*11.2.3指向函數(shù)的指針/*計(jì)算數(shù)值積分(函數(shù)指針作為函數(shù)參數(shù)示例)*/int

main(void){doubleresult;

double(*funp)(double);result=calc(f1,0.0,1.0);/*函數(shù)名f1作為函數(shù)calc的實(shí)參*/printf("1:resule=%.4f\n",result);

funp=f2; /*對(duì)函數(shù)指針funp賦值*/

result=calc(funp,1.0,2.0);/*函數(shù)指針funp作為函數(shù)calc的實(shí)參*/printf("2:resule=%.4f\n",result);return0;}/*函數(shù)指針funp作為函數(shù)的形參*/doublecalc(double(*funp)(double),doublea,doubleb){doublez;z=(b-a)/2*((*funp)(a)+(*funp)(b));/*調(diào)用funp指向的函數(shù)*/

return(z);}運(yùn)行結(jié)果1:resule=0.50002:resule=0.648111.3用鏈表構(gòu)建學(xué)生信息庫(kù)

11.3.1程序解析11.3.2鏈表的概念11.3.3單向鏈表的常用操作11.3.1程序解析例11-10建立一個(gè)學(xué)生成績(jī)信息(包括學(xué)號(hào)、姓名、成績(jī))的單向鏈表,學(xué)生記錄按學(xué)號(hào)由小到大順序排列,要求實(shí)現(xiàn)對(duì)成績(jī)信息的插入、修改、刪除和遍歷操作。mainCreate_Stu_DocInsertDoc

DeleteDoc

Print_Stu_Doc

InsertDoc

11.3.1程序解析struct

stud_node{/*鏈表結(jié)點(diǎn)類型*/

intnum;charname[20];

intscore;

struct

stud_node*next;};struct

stud_node*Create_Stu_Doc();/*新建鏈表*/struct

stud_node*InsertDoc(struct

stud_node*head,struct

stud_node*stud);/*插入*/struct

stud_node*DeleteDoc(struct

stud_node*head,intnum);/*刪除*/voidPrint_Stu_Doc(struct

stud_node*head);/*遍歷*/11.3.2鏈表的概念鏈表是一種常見而重要的動(dòng)態(tài)存儲(chǔ)分布的數(shù)據(jù)結(jié)構(gòu)。它由若干個(gè)同一結(jié)構(gòu)類型的“結(jié)點(diǎn)”依次串接而成。鏈表分單向鏈表和雙向鏈表。頭指針結(jié)點(diǎn)尾結(jié)點(diǎn)頭結(jié)點(diǎn)11.3.2鏈表的概念通常使用結(jié)構(gòu)來(lái)定義單向鏈表結(jié)點(diǎn)的數(shù)據(jù)類型:struct

stud_node{

intnum;charname[20];

intscore;

struct

stud_node*next;};結(jié)構(gòu)的遞歸定義

11.3.2鏈表的概念與數(shù)組比較在用數(shù)組存放數(shù)據(jù)時(shí),一般需要事先定義好固定長(zhǎng)度的數(shù)組,在數(shù)組元素個(gè)數(shù)不確定時(shí),可能會(huì)發(fā)生浪費(fèi)內(nèi)存空間的情況。鏈表是動(dòng)態(tài)存儲(chǔ)分布的數(shù)據(jù)結(jié)構(gòu)。根據(jù)需要?jiǎng)討B(tài)地開辟內(nèi)存空間,可以比較自由方便地插入新元素(結(jié)點(diǎn)),故使用鏈表可以節(jié)省內(nèi)存,操作效率高。11.3.2鏈表的概念動(dòng)態(tài)分配相關(guān)函數(shù)void*malloc(unsignedsize)

功能:在內(nèi)存的動(dòng)態(tài)存貯區(qū)中分配一塊長(zhǎng)度為size的連續(xù)空間。返回值:指針,存放被分配內(nèi)存的起始地址。若未申請(qǐng)到空

溫馨提示

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

評(píng)論

0/150

提交評(píng)論