




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第 8 章 指 针,课前预习检查 1. 什么是指针? 2. 变量的指针和指针变量。 3. 指向数组的指针和指针数组 4. 指向函数的指针和指针函数,教学目的与要求: 1. 理解指针的概念和作用 2. 掌握指针变量和变量的指针 3. 掌握通过指针引用数组 4. 掌握指针引用字符串 5. 掌握函数指针和指针函数 6. 掌握指针数组 7. 理解内存的动态分配 8. 熟练运用指针编写程序,8.1 指针的概念 8.2 指针变量 8.3 通过指针引用数组 8.4 通过指针引用字符串 8.5 指向函数的指针 8.6 返回指针值的函数 8.7 指针数组和多重指针 8.8 内存的动态分配,8.1 指针的概念,地
2、 址,8.1 指针的概念,(1)直接访问 (2)间接访问 (3)变量的指针 (4)指针变量 (5)指针变量的值, 例 82 通过指针变量访问整型变量。 指针变量的定义 int *p; float *p1, *p2; char *p3, *p4;,8.2 指 针 变 量,注意事项: (1)指针变量前面的“*”表示该变量的类型为指针型变量。 (2)在定义指针变量时必须指定基类型。 (3)指针类型的表示( 例: int *)。 (4)指针变量中只能存放地址,不要将一个数赋给一个指针变量。,8.2 指 针 变 量,指针变量的引用 (1)给指针变量赋值。 (2)引用指针变量指向的变量。 (3)引用指针变
3、量的值。 运算符 int *p; p= 引用数组元素时指针的运算 p+1 p-1 p+ + + +p p2 p1,8.3 通过指针引用数组,通过指针引用数组元素 引用数组元素的方法: 下标法 ai 指针法 *(a+i) *(p+i) 例 88 用数组名下标法引用数组元素,8.3 通过指针引用数组, 例 89 用指针下标法引用数组元素 例 90 用数组名法引用数组元素 例 91 用指针变量法引用数组元素,8.3 通过指针引用数组, 例 92 用指针变量的自增运算引用数组元素 注意:指针变量的当前值 例 93 ,8.3 通过指针引用数组,练习2 分析以下情况各式的返回值: int a5=1,2,3
4、,4,5; int *p=a; (1) p+ *p (2) *p+ (3) *(p+) *(+p) (4) +(*p) (*p)+,8.3 通过指针引用数组,用数组名作函数参数 例 94 实参形参都是数组名 例 95 实参数组名,形参指针变量 例 96 实参指针变量,形参数组名 例 97 实参形参都是指针变量,8.3 通过指针引用数组,通过指针引用多维数组 多维数组元素的地址 aij *(ai+j) *(*(a+i)+j),8.3 通过指针引用数组,指向多维数组元素的指针变量 (1)指向数组元素的指针变量 例 98 aij在数组中相对位置公式: i*m+j 例 99 ,8.3 通过指针引用数组
5、,(2)指向由m个元素组成的一维数组的指针变量 例 100 ,8.3 通过指针引用数组,用指向数组的指针作函数参数 例 101 有一个班3名学生,各学4门课程,输出第N个学生的成绩。,8.3 通过指针引用数组,字符串的引用方式 用字符数组处理字符串 例 102 用字符指针变量处理字符串 例 103 ,8.4 通过指针引用字符串, 例 104 例 105 将字符串a复制为字符串b,然后输出字符串b。,8.4 通过指针引用字符串,字符指针作函数参数 例 106 将字符串a复制为字符串b,然后输出字符串b。 操作函数,8.4 通过指针引用字符串,易引起缓冲区溢出攻击、不安全的函数: gets()、s
6、canf()、strcpy()等不限制字符串长度,不对数组越界进行检查和限制,导致有用的堆栈数据被覆盖,给黑客攻击以可乘之机。 对缓冲区溢出漏洞进行攻击的后果:程序运行失败、系统崩溃和重启;取得非法授权,字符指针变量和字符数组的比较 (1)char *pstr=hello/等价于 char *pstr; /存储在常量存储区 pstr= hello pstr的值(指向)可修改,但所指向的字符串常量不可修改 gets(pstr); *pstr=w;/都是错误的 但pstr = china,8.4 通过指针引用字符串,(2)char str = china char *pstr = str; 或者=
7、 char *pstr =str; gets(pstr);,8.6 返回指针值的函数,字符串str1 =“hello” 字符串str2 = “chian”, 连接后str1 = “hellochina”,程序, 例 110 有a个学生,每个学生有b门课程的成绩。要求在输入学生序号以后,能输出该学生的全部成绩。用指针函数实现。,8.6 返回指针值的函数,什么是函数指针 编译时,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址(入口地址)称为这个函数的指针。 函数指针的定义和使用: 类型名 ( *指针变量名 ) ( 函数参数表列 ); int (*f)(int a, int b);/正确
8、,8.5 指向函数的指针,int (*f)(int a, int b);/正确,常见错误: 1、忘了写前一个()int * f(int a,int b);/返回整型指针 2、忘了写后一个()int (*f)/定义整型指针变量 3、定义时后一个括号内的参数类型与指向的函数参数类型不匹配 例如:int (*f) (float a,float b); int (*f) ( );/不建议成这样, 例 107 函数指针变量调用函数 例 108 输入两个整数,根据选择1或2调用max函数或min函数,输出二者中最大或最小数。,8.5 指向函数的指针,用指向函数的指针作函数参数 例 109 输入两个整数,根
9、据选择1、2或3,输出二者中最大、最小数或二者之和。 通用函数排序,8.5 指向函数的指针,函数定义的一般形式 类型名 *函数名(参数表列) 函数体 ,8.6 返回指针值的函数,指针数组 一个数组,若其元素均为指针类型数据,称为指针数组。 类型名 *数组名 数组长度 ; 例 111 将若干字符串按由小到大输出。,8.7 指针数组和多重指针,指向指针数据的指针 类型名 * 指针变量; 例 112 输出多个字符串。,8.7 指针数组和多重指针,什么是内存的动态分配 栈(stack) 非静态局部变量分配在内存中的动态存储区中,这个存储区称为栈。 堆(heap) C语言允许建立内存动态分配区域,以存放
10、一些临时用的数据,这些数据不必在程序的声明部分定义,需要时随时开辟,不需要是随时释放。这个自由的存储区称为堆。,8.8 内存的动态分配,建立内存的动态分配 (1)malloc函数 函数原型: void *malloc ( unsigned int size ); 作用: 在内存的动态存储区中分配一个长度为size的连续空间。,8.8 内存的动态分配,指针不能与非指针类型变量进行比较 但可与NULL(0值)进行相等或者不等的关系运算 p =(int *)malloc(n*sizeof(int); if(p = NULL) /判断p是否为空指针 printf(分配失败“); exit(0); ,例
11、子:学生成绩管理,函数的返回值: 是所分配的区域的第一个字节的地址。 使用方法: int *p; p=(int *) malloc ( sizeof ( int ) );,8.8 内存的动态分配,(2)calloc函数 函数原型: void *calloc ( unsigned n, unsigned size ); 作用: 在内存的动态存储区中分配n个长度为size的连续空间。 p= calloc ( 50, 4 );,8.8 内存的动态分配,(3)free函数 函数原型: void *free ( void *p); 作用: 释放指针变量p所指向的动态空间。,8.8 内存的动态分配,(4)
12、realloc函数 函数原型: void *realloc ( void *p, unsigned int size); 作用: 改变通过malloc函数和calloc函数获得的动态空间的大小。 #include ,8.8 内存的动态分配,常见的内存错误分类 1内存分配未成功,却使用了它 2内存分配成功,但尚未初始化就引用它 3内存分配成功,且已经初始化,但操作越界 4释放了内存,却继续使用它 5没有释放内存,造成内存泄露,1内存分配未成功,却使用了它 起因:没有意识到内存分配会不成功 对策:在使用内存前检查指针是否为空指针 if(p = NULL) /判断p是否为空指针 printf(分配失
13、败“); exit(0);,2内存分配成功,但尚未初始化就引用它 起因:没有初始化概念,误认为内存的默认值都是0 对策 即使是赋0值也不可省略,不要嫌麻烦 int *p = NULL;,3内存分配成功,且已经初始化,但操作越界 例如使用数组时常发生下标”多1“,或者”少1“的操作 对策 用循环语句遍历数组元素时,注意下标从0开始。使用strcpy(),gets();mencpy()等函数时要小心,char a100, b50; memcpy(b,a,sizeof(b),char a100, b50; memcpy(b,a,sizeof(a),4释放了内存,却继续使用它 起因:指针指向的内存被释
14、放,并不表示指针会消亡。其地址仍然不变(非NULL),只是该地址对应的内存是垃圾(无效内存块) 指向垃圾内存的指针是野指针(悬空指针),free(pstr); if(pstr != NULL)/不起作用 strcpy(pstr,abc);试图修改已经释放的内存会引起程序崩溃,例子,对策:不要把局部变量的地址作为函数返回值返回,因为该内存在函数体结束时被自动释放。尽量把free集中在函数的出口处。 如不能,则指针free后立即将其置为NULL,free(p); p = NULL;,没有释放内存,造成内存泄露 void init(void) p1= (char*)malloc(256); if(N
15、ULL =p1) return ; p2 = (char*)malloc(256); if(NULL =p2) return ; p3 = (char*)malloc(256); if(NULL =p3) return ; free(p1); free(p2); free(p3);,Exit: if(p1) free(p1); if (p2) free(p2); if (p3) free(p3);,void init(void) p1= (char*)malloc(256); if(NULL =p1) goto Exit; p2 = (char*)malloc(256); if(NULL =p2) goto Exit; p3 = (char*)malloc(256); if(NULL =p3) goto Exit; ,void init(void) p1= (char*)malloc(256); if(NULL =p1) return ; p2 = (char*)malloc(256); if(NULL =p2) free(p1); return ; p3 = (char*)malloc(256); if(NULL =p3) free(p1); free(p2); ret
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025绿色建筑专利转让与实施合同范本
- 2025专业育儿嫂服务合同:婴幼儿照护与早期教育合作协议
- 2025义乌新能源产业园区设备租赁及维护服务协议
- 2025年债权与股权转让结合的综合性房地产项目合作开发协议
- 通信工程G技术测试题及答案
- 2025义乌市公共照明设施节能改造工程合同
- 2025艺术品佣金代理合作协议涵盖古董与书画交易
- 2025年智能设备维护与数据安全处理合同
- 通信工程施工企业安全生产管理人员知识考核测试题库含答案
- 2025年度生态循环农业养猪场施工及数字化养殖技术合作协议
- 萤石矿商业计划书
- 湖南省长沙市田家炳实验中学实验高一物理摸底试卷含解析
- 《自然辩证法概论》教学大纲的总体思路、基本框架及主要特点和教学重点
- 2024年住房和城乡建设部标准定额研究所招考聘用笔试历年高频考点难、易错点荟萃附答案带详解
- 武汉仓储行业趋势分析
- 机械制造企业安全生产标准化达标所需文件和资料全
- 医务人员服务态度差存在问题及整改措施
- 青海国肽生物科技有限公司牦牛骨提取小分子胶原蛋白肽生产项目及国肽大厦建设项目环评报告
- 中国医师节ppt课件(图文)
- 管理服务北京市地方标准-住宅物业服务标准
- T-BJWA 005-2022 水质17O-NMR半高峰宽测定 核磁共振法
评论
0/150
提交评论