




已阅读5页,还剩55页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Chap 11 指针进阶,11.1 布袋中的彩色球11.2 解密藏头诗11.3 学生信息管理的链表实现,1,本章要点,指针数组和指向指针的指针是如何被定义和使用的?指针如何作为函数的返回值?指向函数的指针的意义是什么?什么是结构的递归定义,哪种应用需要这种定义方法?对链表这种数据结构,如何进行动态内存分配操作?如何建立单向链表并实现插入、删除以及查找操作?,2,11.1 布袋中的彩色球,11.1.1 程序解析11.1.2 指针数组的概念11.1.3 指向指针的指针11.1.4 用指针数组处理多个字符串11.1.5 命令行参数,3,11.1.1 程序解析,例11-1 已知一个不透明的布袋里装有红、蓝、黄、绿、紫同样大小的圆球各一个,现从中一次抓出两个,问可能抓到的是什么颜色的球?,4,程序解析例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 = i+1; j = 4; j+) /* j代表第二个球对应的颜色下标 */ /* 两个球不能同色 */ count +; printf(%6d, count); printf(%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,指针数组,char *color5;color0 = “red”; color1 = “blue”; ,5,11.1.2 指针数组的概念,char *color5;类型名 *数组名数组长度数组元素是指针类型,用于存放内存地址int a5;a是一个数组,它有5个元素每个元素的类型都是整型char *color5;color是一个数组,它有5个元素每个元素的类型都是字符指针,6,char *color5 = red, blue, yellow, green, purple;color是一个数组,它有5个元素每个元素的类型都是字符指针数组元素可以处理字符串对指针数组元素的操作相当于对同类型指针变量的操作printf(%10s %10sn, colori, colorj);,指针数组的概念,7,#include int main(void) int i; char *color5 = red, blue, yellow, green, purple, *tmp; for(i = 0; i 5; i+) /* 输出字符串的地址和内容*/ printf(%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, purple,例11-2 使用指针数组输出5种颜色的英文名称,color0:purple, color4:red,8,交换color0与color4的值,例11-2 图示,9,11.1.3 指向指针的指针示例,例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 = i+1; j = 4; j+) count+; printf( %6d, count ); printf( %10s %10sn, colori, colorj ); return 0;,指向指针的指针,pci, pcj );或*(pc + i), *(pc + j),10,指向指针的指针示例分析,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,11,指向指针的指针定义,指向指针的指针(二级指针) 类型名 *变量名int a = 10;int *pa = ,12,int a = 10, b = 20, t;int *pa = ,例11-4,操作(1):ppt = ppb; ppb = ppa; ppa = ppt;,13,int a = 10, b = 20, t;int *pa = ,例11-4,操作(1):ppt = ppb; ppb = ppa; ppa = ppt;,操作(2):pt = pb; pb = pa; pa = pt; ?,14,int a = 10, b = 20, t;int *pa = ,例11-4,操作(1):ppt = ppb; ppb = ppa; ppa = ppt;,操作(2):pt = pb; pb = pa; pa = pt;,操作(3):t = b; b = a; a = t;,15,int a = 10, b = 20, t;int *pa = ,例11-4,操作(1):ppt = ppb; ppb = ppa; ppa = ppt;,操作(2):pt = pb; pb = pa; pa = pt;,操作(3):t = b; b = a; a = t;,16,11.1.4 用指针数组处理多个字符串,处理多个字符串二维字符数组char ccolor 7 = red, blue, yellow, green, purple;指针数组char *pcolor = red, blue, yellow, green, purple;,使用指针数组更节省内存空间,17,1. 用指针数组处理多个字符串排序,例11-5 将5个字符串从小到大排序后输出。,#include int main(void) int i; int a5 = 6, 5, 2, 8, 1; void fsort( int a , 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;,18,例11-5 字符串排序,void fsort(int a , int n) int k, j; int temp; for(k = 1; k 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 0) temp = colorj; colorj = colorj+1; colorj+1 = temp; ,19,pcolor0,pcolor1,pcolor2,pcolor3,pcolor,pcolor4,排序前,pcolor0,pcolor1,pcolor2,pcolor3,pcolor,pcolor4,排序后,20,2. 动态输入多个字符串示例,用动态分配内存的方法处理多个字符串的输入示例例11-6 输入一些球的颜色,以#作为输入结束标志,再输出这些颜色。其中颜色数小于20,颜色的英文名称不超过10个字符。,21,#include #include#includeint main(void) int i, n = 0; char *color20, str10; printf(请输入颜色名称,每行一个,#结束输入:n); scanf(%s, str); while(str0 != #) 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 yellow,for( i=0; i20; i+) colori = NULL;,for( i=0; in; i+) free( colori );,22,3. 对指针数组的进一步讨论,char *color = red, blue, yellow, green, purple;color:二级指针(char *),等于&color0 color+2:指向color2 *(color+2)和color2等价 color0:指向字符串red的首字符rcolor0+2:指向首字符r后的第2个字符d,23,对指针数组的进一步讨论,(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);,24,11.1.5 命令行参数,C语言源程序经编译和连接处理,生成可执行程序后,才能运行。在DOS环境的命令窗口中,输入可执行文件名,就以命令方式运行该程序。 输入命令时,在可执行文件(命令)名的后面可以跟一些参数,这些参数被称为命令行参数。 test world,命令名,命令行参数,25,命令行参数,命令名 参数1 参数2参数n命令名和各个参数之间用空格分隔,也可以没有参数使用命令行的程序不能在编译器中执行,需要将源程序经编译、链接为相应的命令文件(一般以.exe为后缀),然后回到命令行状态,再在该状态下直接输入命令文件名。,26,带参数的main()函数,第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!,27,例10-7 输出命令行参数,例11-7 编写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?,28,11.2 解密藏头诗,11.2.1 程序解析11.2.2 指针作为函数的返回值11.2.3 指向函数的指针,29,11.2.1 程序解析解密藏头诗,例11-8 输入一首藏头诗(假设只有4句),输出其真实含义。藏头诗:将这首诗每一句的第一个字连起来,所组成的内容就是该诗的真正含义。,30,11.2.1 程序解析,#include char *change(char s 20, char 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;,printf(%sn, change(s, t) );或change(s, t);printf(%sn, t);,31,11.2.2 指针作为函数的返回值,函数返回值的类型整型、字符型、浮点型、结构类型指针(返回一个地址)函数的定义、调用方法与其他函数一样,32,指针作为函数的返回值例11-9,输入一个字符串和一个字符,如果该字符在字符串中,就从该字符首次出现的位置开始输出字符串中的字符。要求定义函数match(s, ch),在字符串s中查找字符ch,如果找到,返回第一次找到的该字符在字符串中的位置(地址);否则,返回空指针NULL。 例如,输入字符r和字符串program后,输出rogram。,33,例11-9 源程序,#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) ) != NULL ) 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,34,指针作为函数的返回值的进一步讨论,函数返回值的类型整型、字符型、浮点型、结构类型指针(返回一个地址)函数的定义、调用方法与其他函数一样进一步讨论定义函数时,可以:动态分配内存操作这些新分配的单元返回新分配单元的地址,修改例11-8,采用动态分配内存的方法,35,例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); free(p); return 0;,char * change_d(char s 20) int i; char *head, *p; p = (char *) calloc(8, sizeof(char); head = p; for(i= 0; i y ? x : y;,38,通过函数指针调用函数,int (*funptr)( );funptr = fun;调用函数函数名z = fun(3, 5);函数指针(*funptr)(3, 5); (*函数指针名)(参数表),int fun(x ,y) return x y ? x : y;,39,函数指针做为函数的参数,实参:函数名或已赋值的函数指针形参:函数指针,指向实参所代表函数的入口地址例11-10 编写一个函数calc(f, a, b),用梯形公式求函数f(x)在a, b上的数值积分。 然后调用calc(f, a, b)计算下列数值积分。 分析:函数定义时,形参:函数指针f、积分区间上下限参数a,b函数调用时,实参:被积函数的名称(或函数指针)和积分区间的上下限,40,例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; result = 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,41,11.3 学生信息管理的链表实现,11.3.1 程序解析11.3.2 链表的概念11.3.3 单向链表的常用操作,42,11.3.1 程序解析,例11-11 建立一个学生成绩信息(包括学号、姓名、成绩)的单向链表,学生记录按学号由小到大顺序排列,要求实现对成绩信息的插入、修改、删除和遍历操作。,43,例11-11 数据定义与函数声明,struct stud_node /*链表结点类型*/ int num; char name20; int score; 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, int num); /* 删除 */void Print_Stu_Doc(struct stud_node * head); /* 遍历 */,44,11.3.2 链表的概念,一种动态存储分布的数据结构若干个同一结构类型的“结点”依次串接而成单向链表、双向链表,头指针,结点,尾结点,45,链表的概念结点定义,struct stud_node int num; char name20; int score; struct stud_node *next; 结构的递归定义,46,链表的概念与数组比较,数组事先定义固定长度的数组在数组元素个数不确定时,可能会发生浪费内存空间的情况 链表动态存储分配的数据结构根据需要动态开辟内存空间,比较方便地插入新元素(结点)使用链表可以节省内存,提高操作效率,47,动态存储分配函数malloc(),void *malloc(unsigned size) 在内存的动态存储区中分配一连续空间,其长度为size若申请成功,则返回一个指向所分配内存空间的起始地址的指针若申请不成功,则返回NULL(值为0)返回值类型:(void *)通用指针的一个重要用途将malloc的返回值转换到特定指针类型,赋给一个指针,48,malloc()示例,int *ip = (int *) malloc( sizeof(int) )struct student * p;p = (struct student *) malloc(sizeof(struct student);调用malloc时,用 sizeof 计算存储块大小虽然存储块是动态分配的,但它的大小在分配后也是确定的,不要越界使用。,49,动态存储释放函
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 激光成像技术原理与应用试题及答案
- 激光技术工程师考试考生的必知试题及答案
- 公证管理考试题及答案
- 公共卫生执业医师考试问题应对试题及答案探讨
- 护士资格证经典试题及答案
- 药品包装与信息传播考题试题及答案
- 职业生涯与光电工程考试的重要性试题及答案
- 审计专业知识试题及答案
- 2025年云南建筑安全员-B证考试题库附答案
- 2025-2030宠物美容产品行业市场现状供需分析及重点企业投资评估规划分析研究报告
- 2024年江苏事业单位真题下载
- 房地产行业未来走势与机遇分析
- ISO27001:2022信息安全管理体系全套文件+表单
- 系统本地部署协议合同
- 2025年中国色度仪行业发展运行现状及投资策略研究报告
- 路基排水工程首件施工方案
- 上海市黄浦区2025届高三高考二模地理试卷(含答案)
- 2025年淄博市光明电力服务有限责任公司招聘笔试参考题库含答案解析
- 游乐场区块链数据共享-全面剖析
- 2024年陕西省县以下医疗卫生机构定向招聘考试真题
- 槽轮机构槽轮机构包头课件
评论
0/150
提交评论