C语言程序设计课件:chap11-指针进阶_第1页
C语言程序设计课件:chap11-指针进阶_第2页
C语言程序设计课件:chap11-指针进阶_第3页
C语言程序设计课件:chap11-指针进阶_第4页
C语言程序设计课件:chap11-指针进阶_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Chap 11 指针进阶 11.1 布袋中的彩色球11.2 解密藏头诗11.3 学生信息管理的链表实现本章要点指针数组和指向指针的指针是如何被定义和使用的?指针如何作为函数的返回值?指向函数的指针的意义是什么?什么是结构的递归定义,哪种应用需要这种定义方法?对链表这种数据结构,如何进行动态内存分配操作?如何建立单向链表并实现插入、删除以及查找操作? 11.1 布袋中的彩色球 11.1.1 程序解析11.1.2 指针数组的概念11.1.3 指向指针的指针11.1.4 用指针数组处理多个字符串11.1.5 命令行参数 11.1.1 程序解析例11-1 已知一个不透明的布袋里装有红、蓝、黄、绿、紫同

2、样大小的圆球各一个,现从中一次抓出两个,问可能抓到的是什么颜色的球?程序解析例11-1 源程序#includeint main(void) char *color5 = red, blue, yellow, green, purple; /* 初始化 */ int count = 0, i, j; for(i = 0; i = 4; i+) /* i代表第一个球对应的颜色下标 */ for(j = 0; j = 4; j+) /* j代表第二个球对应的颜色下标 */ if(i = j) continue; /* 两个球不能同色 */ count +; printf(%6d, count); p

3、rintf(%10s %10sn, colori, colorj); return 0; 1 red blue 2 red yellow 3 red green 4 red purple 5 blue yellow 6 blue green 7 blue purple 8 yellow green 9 yellow purple 10 green purple指针数组11.1.2 指针数组的概念char *color5;类型名 *数组名数组长度数组元素是指针类型,用于存放内存地址int a10;a是一个数组,它有10个元素每个元素的类型都是整型char *color5;color是一个数组,它

4、有5个元素每个元素的类型都是字符指针char *color5 = red, blue, yellow, green, purple;color是一个数组,它有5个元素每个元素的类型都是字符指针数组元素可以处理字符串对指针数组元素的操作相当于对同类型指针变量的操作printf(%10s %10sn, colori, colorj);指针数组的概念#include int main(void) int i; char *color5 = red, blue, yellow, green, purple, *tmp; for(i = 0; i 5; i+) /* 输出字符串的地址和内容*/ prin

5、tf(%x, %sn, colori, colori); tmp = color0; /* 交换color0与color4*/ color0 = color4; color4 = tmp; printf(color0:%s, color4:%sn, color0, color4); return 0;420064, red42005c, blue420054, yellow42004c, green420044, purplecolor0:purple, color4:red例11-2 使用指针数组输出5种颜色的英文名称交换color0与color4的值 例11-2 图示11.1.3 指向指针

6、的指针示例例11-3 改写例11-1,用指向指针的指针实现。 #includeint main(void) char *color5 = red, blue, yellow, green, purple; char *pc = color; int count = 0, i, j; for(i = 0; i = 4; i+) for(j = 0; j = 4; j+) if(i = j) continue; count+; printf( %6d, count ); printf( %10s %10sn, colori, colorj ); return 0;指向指针的指针*(pc + i),

7、 *(pc + j)指向指针的指针示例分析char *color5 = red, blue, yellow, green, purple;char *pc = color;printf( %10s %10sn, *(pc + i), *(pc + j) );pc: color 或者&color0*pc: color0: red*(pc+i) : colori*color0: r *pc: *color0: r 指向指针的指针定义指向指针的指针(二级指针) 类型名 *变量名int a = 10;int *p = &a;int *pp = &p; &apa10&ppp*p*pp*pp&apaa10

8、&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*paint a = 10, b = 20, t;int *pa = &a, *pb = &b, *pt;int *ppa = &pa, *ppb = &pb, *ppt;例11-4操作(1):ppt = ppb; ppb = ppa; ppa = ppt; 操作(2):pt = pb; pb =

9、pa; pa = pt; 操作(3):t = b; b = a; a = t; 11.1.4 用指针数组处理多个字符串处理多个字符串二维字符数组char ccolor 7 = red, blue, yellow, green, purple;指针数组char *pcolor = red, blue, yellow, green, purple;使用指针数组更节省内存空间1. 用指针数组处理多个字符串排序例11-5 将5个字符串从小到大排序后输出。#include int main(void) int i; int a5 = 6, 5, 2, 8, 1; void fsort( int a ,

10、int n ); fsort( a, 5 ); for(i = 0; i 5; i+) printf(%d , ai); return 0; #include int main(void) int i; char *pcolor5= red, blue, yellow, green, purple ; void fsort(char *color , int n); fsort( pcolor, 5 ); for(i = 0; i 5; i+) printf(%s , pcolori); return 0; 例11-5 字符串排序void fsort(int a , int n) int k,

11、 j; int temp; for(k = 1; k n; k+) for(j = 0; j aj+1) temp = aj; aj = aj+1; aj+1 = temp; void fsort(char *color , int n) int k, j; char *temp; for(k = 1; k n; k+) for(j = 0; j 0) temp = colorj; colorj = colorj+1; colorj+1 = temp; pcolor0pcolor1pcolor2pcolor3pcolorred0blue0yellow0green0purple0pcolor4排

12、序前pcolor0pcolor1pcolor2pcolor3pcolorpcolor4排序后red0blue0yellow0green0purple02. 动态输入多个字符串示例用动态分配内存的方法处理多个字符串的输入示例例11-6 输入一些球的颜色,以#作为输入结束标志,再输出这些颜色。其中颜色数小于20,颜色的英文名称不超过10个字符。#include #include#includeint main(void) int i, n = 0; char *color20, str10; printf(请输入颜色名称,每行一个,#结束输入:n); scanf(%s, str); while(s

13、tr0 != #) colorn = (char *) malloc ( sizeof (char) * ( strlen(str) + 1 ) ); strcpy(colorn, str); n+; scanf(%s, str); printf(你输入的颜色是:); for(i = 0; i n; i+) printf(%s , colori); return 0;请输入颜色名称,每行一个,#结束输入:redblue yellow#你输入的颜色是:red blue yellow3. 对指针数组的进一步讨论char *color = red, blue, yellow, green, purp

14、le;color:二级指针(char *),&color0 color+2:指向color2 *(color+2)和color2等价 color0:指向字符串red的首字符rcolor0+2:指向首字符r后的第2个字符d对指针数组的进一步讨论(1) colork*(color+k) printf(%s, color2); printf(%s, *(color+2); (2) *(colork+j) *(*(color+k)+j) colorkj printf(%c %c, *(color2), *(color2+2); printf(%c %c, color20, color22); 11.1

15、.5 命令行参数C语言源程序经编译和连接处理,生成可执行程序后,才能运行。在DOS环境的命令窗口中,输入可执行文件名,就以命令方式运行该程序。 输入命令时,在可执行文件(命令)名的后面可以跟一些参数,这些参数被称为命令行参数。 test world 命令名命令行参数#include /* test.c */int main( ) printf(Hello World!); return 0;命令行参数命令名 参数1 参数2参数n命令名和各个参数之间用空格分隔,也可以没有参数使用命令行的程序不能在编译器中执行,需要将源程序经编译、链接为相应的命令文件(一般以.exe为后缀),然后回到命令行状态,

16、再在该状态下直接输入命令文件名。 带参数的main()函数int main( int argc, char *argv ) .第1个参数 argc 接收命令行参数(包括命令名)的个数第2个参数 argv 接收以字符串常量形式存放的命令行参数(命令名本身也作为一个参数) #include /* test.c */int main(int argc, char *argv ) printf(Hello ); printf(%s, argv1); return 0;test world!Hello world!argc: 2*argv : test, world!例11-7 输出命令行参数例11-7

17、 编写C程序echo,它的功能是将所有命令行参数在同一行上输出。 #include int main(int argc, char *argv ) int k; for(k = 1; k argc; k+) /* 从第1个命令行参数开始 */ printf(%s , argvk); /* 打印命令行参数 */ printf(n); return 0;在命令行状态下输入:echo How are you?How are you?练习11-1输入月份,输出对应的英文名称。要求用指针数组表示12个月的英文名称。#includeint main(void ) int n; char *name12=J

18、anuary,February,March,April,May,June,July,August,September,October,November,December; printf(请输入月份:);scanf(%d,&n); printf(%sn,namen+1); return 0; 练习11-3输入5个字符串,输出其中最长的字符串,要求使用指针数组实现。#include #include #define N 5#define M 20void sort_str(char *pp, int n);int main(void) char strNM, *pN; char *pp; int

19、i; printf(请输入5个字符串:n); for (i = 0; i N; i+) scanf(%s, stri); /输入字符串放入二维数组中 pi = stri; /是指针数组指向输入的字符串 pp = p; /将指针数组名赋值给指针变量pp就是是pp指向p sort_str(pp, N); for (i = 0; i N; i+) pp = p + i;printf(请输入5个字符串:n);printf(%sn, *pp); return 0;/*冒泡排序法,参数pp为指针向指针的指针,n为指针数组*/void sort_str(char *pp, int n) char *temp

20、; int i, j; for(i=0; i n-1; i+) for(j=0; j strlen(*(pp+j+1) temp = *(pp+j); *(pp+j) = *(pp+j+1); *(pp+j+1) = temp; 11.2 解密藏头诗 11.2.1 程序解析11.2.2 指针作为函数的返回值11.2.3 指向函数的指针11.2.1 程序解析解密藏头诗 例11-8 输入一首藏头诗(假设只有4句),输出其真实含义。藏头诗:将这首诗每一句的第一个字连起来,所组成的内容就是该诗的真正含义。11.2.1 程序解析#include char *change(char s 20, char

21、t );int main(void) int i; char s420, t10, *p; printf(“请输入藏头诗:n”); for(i = 0; i 4; i+) scanf(%s, si); p = change(s, t); printf(%sn, p); return 0;请输入藏头诗:一叶轻舟向东流,帆梢轻握杨柳手,风纤碧波微起舞,顺水任从雅客悠。一帆风顺char * change(char s 20, char t ) int i; for(i= 0; i 4; i+) t2*i = si0; t2*i+1 = si1; t2*i = 0; return t;函数的返回值是字

22、符指针printf(%sn, change(s, t) );或change(s, t);printf(%sn, t);11.2.2 指针作为函数的返回值函数返回值的类型整型、字符型、浮点型、结构类型指针(返回一个地址)函数的定义、调用方法与其他函数一样指针作为函数的返回值例11-9输入一个字符串和一个字符,如果该字符在字符串中,就从该字符首次出现的位置开始输出字符串中的字符。要求定义函数match(s, ch),在字符串s中查找字符ch,如果找到,返回第一次找到的该字符在字符串中的位置(地址);否则,返回空指针NULL。 例如,输入字符r和字符串program后,输出rogram。例11-9

23、源程序#include char *match(char *s, char ch) while(*s != 0) if(*s = ch) return(s); /* 若找到字符ch,返回相应的地址 */ else s+; return(NULL); /* 没有找到ch,返回空指针 */int main(void ) char ch, str80, *p = NULL; printf(“Please Input the string:n”); scanf(%s, str); getchar( ); ch = getchar( ); if( ( p = match(str, ch) ) != NU

24、LL ) printf(%sn, p); else printf(Not Foundn); return 0;Please Input the string:University vversity字符指针p接收match返回的地址,从p指向的存储单元开始,连续输出其中的内容,直至0为止。 Please Input the string:school aNot Found指针作为函数的返回值的进一步讨论函数返回值的类型整型、字符型、浮点型、结构类型指针(返回一个地址)函数的定义、调用方法与其他函数一样进一步讨论定义函数时,可以:动态分配内存操作这些新分配的单元返回新分配单元的地址 例11.8 修

25、改动态分配内存例11.8 修改动态分配内存#include #include char *change_d(char s 20);int main(void) int i; char s420, *p = NULL; printf(请输入藏头诗:n); for(i = 0; i 4; i+) scanf(%s, si); p = change_d(s); printf(%sn, p); return 0;char * change_d(char s 20) int i; char *head, *p; p = (char *) calloc(8, sizeof(char); head = p;

26、 for(i= 0; i y ? x : y;通过函数指针调用函数int (*funptr)( );funptr = fun;调用函数函数名z = fun(3, 5);函数指针(*funptr)(3, 5); (*函数指针名)(参数表)int fun(x ,y) return x y ? x : y;函数指针做为函数的参数实参:函数名或已赋值的函数指针形参:函数指针,指向实参所代表函数的入口地址例11-10 编写一个函数calc(f, a, b),用梯形公式求函数f(x)在a, b上的数值积分。 然后调用calc(f, a, b)计算下列数值积分。 分析:函数定义时,形参:函数指针f、积分区间

27、上下限参数a,b函数调用时,实参:被积函数的名称(或函数指针)和积分区间的上下限例11-10 源程序double f1 ( double x ) return (x*x); double f2 ( double x ) return (sin(x)/x); double calc ( double (*f)(double), double a, double b ) double z; z = (b-a)/2 * ( (*f)(a) + (*f)(b) ); /* 调用 f 指向的函数 */ return ( z );int main ( void ) double result; resul

28、t = calc(f1, 0.0, 1.0); /* 函数名f1作为函数calc的实参 */ printf(1: resule=%.4fn, result); funp = f2; result = calc(funp, 1.0, 2.0); /* 函数指针funp作为函数calc的实参 */ printf(2: resule=%.4fn, result); return 0;1: resule=0.50002: resule=0.6481简化:求任意函数在任意区间上的定积分#include#includedouble fun(double x)return(x*x);double integ

29、ral(int a,int b,double (*f)(double)double sum=0.0,x;for(x=a;xnum = num; strcpy(p-name, name); p-score = score; p-next = NULL; if(head = NULL) head = p; else tail-next = p; tail = p; scanf(%d%s%d, &num, name, &score); 2. 链表的遍历ptr-numptr-scoreptrptrfor(ptr = head; ptr != NULL; ptr = ptr - next) printf

30、(%ld, %d, ptr - num, ptr - score);ptr=ptr-nexthead9905 Qian 80 NULL9901 Wang 809902 Li 90链表的遍历函数void Print_Stu_Doc(struct stud_node * head) struct stud_node * ptr; if(head = NULL) printf(nNo Recordsn); return; printf(nThe Students Records Are: n); printf( Num Name Scoren); for(ptr = head; ptr!=NULL;

31、 ptr = ptr-next) printf(%8d %20s %6d n, ptr-num, ptr-name, ptr-score);s-next = ptr-nextptr-next = s先连后断headptrs3. 插入结点ptr2=ptr1-nextptr1-next=ptr2-nextheadptr1ptr2free(ptr2)先接后删4. 删除结点ptr2headptr1程序举例:程序L11_10.C功能:输入学生序号后,输出该学生的全部成绩。#include float *search(float (*p)4, int n ) float *pt; pt=*(p+n); r

32、eturn pt; void main() static float score 4=62,70.5,87,77,57,89,65,83,72,78,60,91; float *p; int i,m; printf(Enter the number of student:); scanf(%d,&m); printf(The scores of No.%d are:n,m); p=search(score,m); for(i=0;i4;i+) printf(%5.2ft,*(p+i);程序L11_6.C功能:比较指向数组元素的指针变量和指向数组的指针变量的不同。 #include void main() int a23=1,2,3,4,5,6; int *p1,(*p2)3; /* p1指向数组元素,p2指向包含3个元素的一维数组 */ /* 用指向数组元素的指针变量输出二维数组元素 */ p1=a0; for(;p1a0+6;p1+) printf(%4d,*p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论