C语言程序设计(第8章)课件_第1页
C语言程序设计(第8章)课件_第2页
C语言程序设计(第8章)课件_第3页
C语言程序设计(第8章)课件_第4页
C语言程序设计(第8章)课件_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

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

文档简介

1、第 8 章 指 针C 语言程序设计 第1页,共55页。课前预习检查 1. 什么是指针? 2. 变量的指针和指针变量。 3. 指向数组的指针和指针数组 4. 指向函数的指针和指针函数第2页,共55页。 教学目的与要求: 1. 理解指针的概念和作用 2. 掌握指针变量和变量的指针 3. 掌握通过指针引用数组 4. 掌握指针引用字符串 5. 掌握函数指针和指针函数 6. 掌握指针数组 7. 理解内存的动态分配 8. 熟练运用指针编写程序第3页,共55页。8.1 指针的概念8.2 指针变量8.3 通过指针引用数组8.4 通过指针引用字符串8.5 指向函数的指针8.6 返回指针值的函数8.7 指针数组和

2、多重指针8.8 内存的动态分配第4页,共55页。 8.1 指针的概念 地 址第5页,共55页。 8.1 指针的概念 (1)直接访问 (2)间接访问 (3)变量的指针 (4)指针变量 (5)指针变量的值第6页,共55页。 例 82 通过指针变量访问整型变量。指针变量的定义 int *p; float *p1, *p2; char *p3, *p4; 8.2 指 针 变 量第7页,共55页。 注意事项: (1)指针变量前面的“*”表示该变量的类型为指针型变量。 (2)在定义指针变量时必须指定基类型。 (3)指针类型的表示( 例: int *)。 (4)指针变量中只能存放地址,不要将一个数赋给一个指

3、针变量。 8.2 指 针 变 量第8页,共55页。 指针变量的引用 (1)给指针变量赋值。 (2)引用指针变量指向的变量。 (3)引用指针变量的值。 运算符 & :取地址运算符 * :指针运算符 8.2 指 针 变 量第9页,共55页。 例 83 输入a和b两个数,按先大后小的顺序输出a和b。 练习1 分析程序的运行结果。 8.2 指 针 变 量第10页,共55页。 指针变量作为函数的参数 作用:将一个变量的地址传送到另一个函数中。 例 84 例 85 例 86 输入a和b两个数,按先大后小的顺序输出a和b,用函数处理,并用指针类型的数据作函数参数。 8.2 指 针 变 量第11页,共55页。

4、 例 87 输入3个数a, b, c,按先大后小的顺序输出,用函数处理,并用指针类型的数据作函数参数。 8.2 指 针 变 量第12页,共55页。数组元素的指针 int a5= 2, 4, 8, 6, 7 ; int *p; p=&a0; 或 p=a;引用数组元素时指针的运算 p+1 p-1 p+ + + +p p2 p1 8.3 通过指针引用数组第13页,共55页。通过指针引用数组元素引用数组元素的方法: 下标法 ai 指针法 *(a+i) *(p+i) 例 88 用数组名下标法引用数组元素 8.3 通过指针引用数组第14页,共55页。 例 89 用指针下标法引用数组元素 例 90 用数组名

5、法引用数组元素 例 91 用指针变量法引用数组元素 8.3 通过指针引用数组第15页,共55页。 例 92 用指针变量的自增运算引用数组元素注意:指针变量的当前值 例 93 8.3 通过指针引用数组第16页,共55页。练习2分析以下情况各式的返回值: int a5=1,2,3,4,5; int *p=a; (1) p+ *p (2) *p+ (3) *(p+) *(+p) (4) +(*p) (*p)+ 8.3 通过指针引用数组第17页,共55页。用数组名作函数参数 例 94 实参形参都是数组名 例 95 实参数组名,形参指针变量 例 96 实参指针变量,形参数组名 例 97 实参形参都是指针

6、变量 8.3 通过指针引用数组第18页,共55页。通过指针引用多维数组 多维数组元素的地址 aij *(ai+j) *(*(a+i)+j) 8.3 通过指针引用数组第19页,共55页。指向多维数组元素的指针变量(1)指向数组元素的指针变量 例 98 aij在数组中相对位置公式: i*m+j 例 99 8.3 通过指针引用数组第20页,共55页。(2)指向由m个元素组成的一维数组的指针变量 例 100 8.3 通过指针引用数组第21页,共55页。用指向数组的指针作函数参数 例 101 有一个班3名学生,各学4门课程,输出第N个学生的成绩。 8.3 通过指针引用数组第22页,共55页。字符串的引用

7、方式用字符数组处理字符串 例 102 用字符指针变量处理字符串 例 103 8.4 通过指针引用字符串第23页,共55页。 例 104 例 105 将字符串a复制为字符串b,然后输出字符串b。 8.4 通过指针引用字符串第24页,共55页。 字符指针作函数参数 例 106 将字符串a复制为字符串b,然后输出字符串b。 操作函数 8.4 通过指针引用字符串第25页,共55页。易引起缓冲区溢出攻击、不安全的函数: gets()、scanf()、strcpy()等不限制字符串长度,不对数组越界进行检查和限制,导致有用的堆栈数据被覆盖,给黑客攻击以可乘之机。对缓冲区溢出漏洞进行攻击的后果:程序运行失败

8、、系统崩溃和重启;取得非法授权第26页,共55页。 字符指针变量和字符数组的比较 (1)char *pstr=hello/等价于 char *pstr; /存储在常量存储区 pstr= hello pstr的值(指向)可修改,但所指向的字符串常量不可修改 gets(pstr); *pstr=w;/都是错误的 但pstr = china 8.4 通过指针引用字符串第27页,共55页。(2)char str = china char *pstr = str; 或者= &str0 *pstr=w/可以的 str0=w,pstr0= w/等价的数组名str的值不可修改,是地址常量str=“hello”

9、/错误但数组中存储的字符可修改 第28页,共55页。字符指针要牢记的几个原则:明确字符串被保存到了哪里?字符指针指向了哪里?char *pstr =“china”;gets(pstr);/不可修改,常量char str = china;char *pstr =str;gets(pstr);第29页,共55页。8.6 返回指针值的函数字符串str1 =“hello”字符串str2 = “chian”,连接后str1 = “hellochina”程序第30页,共55页。 例 110 有a个学生,每个学生有b门课程的成绩。要求在输入学生序号以后,能输出该学生的全部成绩。用指针函数实现。 8.6 返回

10、指针值的函数第31页,共55页。 什么是函数指针 编译时,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址(入口地址)称为这个函数的指针。函数指针的定义和使用: 类型名 ( *指针变量名 ) ( 函数参数表列 ); int (*f)(int a, int b);/正确 8.5 指向函数的指针第32页,共55页。int (*f)(int a, int b);/正确常见错误:1、忘了写前一个()int * f(int a,int b);/返回整型指针2、忘了写后一个()int (*f)/定义整型指针变量3、定义时后一个括号内的参数类型与指向的函数参数类型不匹配 例如:int (*f) (

11、float a,float b); int (*f) ( );/不建议成这样第33页,共55页。 例 107 函数指针变量调用函数 例 108 输入两个整数,根据选择1或2调用max函数或min函数,输出二者中最大或最小数。 8.5 指向函数的指针第34页,共55页。 用指向函数的指针作函数参数 例 109 输入两个整数,根据选择1、2或3,输出二者中最大、最小数或二者之和。 通用函数排序 8.5 指向函数的指针第35页,共55页。函数定义的一般形式 类型名 *函数名(参数表列) 函数体 8.6 返回指针值的函数第36页,共55页。 指针数组 一个数组,若其元素均为指针类型数据,称为指针数组。

12、 类型名 *数组名 数组长度 ; 例 111 将若干字符串按由小到大输出。 8.7 指针数组和多重指针第37页,共55页。 指向指针数据的指针 类型名 * 指针变量; 例 112 输出多个字符串。 8.7 指针数组和多重指针第38页,共55页。 什么是内存的动态分配 栈(stack) 非静态局部变量分配在内存中的动态存储区中,这个存储区称为栈。 堆(heap) C语言允许建立内存动态分配区域,以存放一些临时用的数据,这些数据不必在程序的声明部分定义,需要时随时开辟,不需要是随时释放。这个自由的存储区称为堆。8.8 内存的动态分配第39页,共55页。建立内存的动态分配(1)malloc函数 函数

13、原型: void *malloc ( unsigned int size ); 作用: 在内存的动态存储区中分配一个长度为size的连续空间。8.8 内存的动态分配第40页,共55页。指针不能与非指针类型变量进行比较但可与NULL(0值)进行相等或者不等的关系运算 p =(int *)malloc(n*sizeof(int);if(p = NULL) /判断p是否为空指针printf(分配失败“); exit(0);例子:学生成绩管理第41页,共55页。函数的返回值: 是所分配的区域的第一个字节的地址。使用方法: int *p; p=(int *) malloc ( sizeof ( int

14、) );8.8 内存的动态分配第42页,共55页。(2)calloc函数 函数原型: void *calloc ( unsigned n, unsigned size ); 作用: 在内存的动态存储区中分配n个长度为size的连续空间。 p= calloc ( 50, 4 );8.8 内存的动态分配第43页,共55页。(3)free函数 函数原型: void *free ( void *p); 作用: 释放指针变量p所指向的动态空间。8.8 内存的动态分配第44页,共55页。(4)realloc函数 函数原型: void *realloc ( void *p, unsigned int siz

15、e); 作用: 改变通过malloc函数和calloc函数获得的动态空间的大小。 #include 8.8 内存的动态分配第45页,共55页。常见的内存错误分类1内存分配未成功,却使用了它2内存分配成功,但尚未初始化就引用它3内存分配成功,且已经初始化,但操作越界4释放了内存,却继续使用它5没有释放内存,造成内存泄露第46页,共55页。1内存分配未成功,却使用了它起因:没有意识到内存分配会不成功对策:在使用内存前检查指针是否为空指针 if(p = NULL) /判断p是否为空指针 printf(分配失败“); exit(0);第47页,共55页。2内存分配成功,但尚未初始化就引用它起因:没有初

16、始化概念,误认为内存的默认值都是0对策 即使是赋0值也不可省略,不要嫌麻烦 int *p = NULL;第48页,共55页。3内存分配成功,且已经初始化,但操作越界例如使用数组时常发生下标”多1“,或者”少1“的操作对策用循环语句遍历数组元素时,注意下标从0开始。使用strcpy(),gets();mencpy()等函数时要小心char a100, b50;memcpy(b,a,sizeof(b)char a100, b50;memcpy(b,a,sizeof(a)第49页,共55页。4释放了内存,却继续使用它起因:指针指向的内存被释放,并不表示指针会消亡。其地址仍然不变(非NULL),只是该

17、地址对应的内存是垃圾(无效内存块)指向垃圾内存的指针是野指针(悬空指针)free(pstr);if(pstr != NULL)/不起作用strcpy(pstr,abc);试图修改已经释放的内存会引起程序崩溃例子第50页,共55页。对策:不要把局部变量的地址作为函数返回值返回,因为该内存在函数体结束时被自动释放。尽量把free集中在函数的出口处。如不能,则指针free后立即将其置为NULLfree(p);p = NULL;第51页,共55页。没有释放内存,造成内存泄露void init(void)p1= (char*)malloc(256); if(NULL =p1) return ; p2 =

18、 (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)

温馨提示

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

评论

0/150

提交评论