c语言程序设计第08章善于使用指针

上传人:san****019 文档编号:70778590 上传时间:2019-01-18 格式:PPT 页数:23 大小:631.81KB
返回 下载 相关 举报
c语言程序设计第08章善于使用指针_第1页
第1页 / 共23页
c语言程序设计第08章善于使用指针_第2页
第2页 / 共23页
c语言程序设计第08章善于使用指针_第3页
第3页 / 共23页
c语言程序设计第08章善于使用指针_第4页
第4页 / 共23页
c语言程序设计第08章善于使用指针_第5页
第5页 / 共23页
点击查看更多>>
资源描述

《c语言程序设计第08章善于使用指针》由会员分享,可在线阅读,更多相关《c语言程序设计第08章善于使用指针(23页珍藏版)》请在金锄头文库上搜索。

1、第8章 善于使用指针,8.1 什么是指针 8.2 指针变量 8.3 通过指针引用数组 8.4 通过指针引用字符串,8.1 什么是指针,1 指针是C语言的精华(灵魂) 掌握指针的应用,可以使程序简洁、紧凑、高效。 指针是内存单元的地址 (1) 定义变量分配存储单元。 (2) 存储单元包含若干字节。 (3) 每个字节都有一个编号,即地址。 (4) 单元的地址是首字节的地址,即变量的地址。 (5) 地址形象化地成为“指针”,指针即地址。 (6) 变量的地址即变量的指针,指针指向该变量单元。 (7) 将变量的地址存放到一个变量中,此变量称指针变量。,8.2 指针变量,8.2.1 指针变量的定义、初始化

2、和引用 1 定义:int a,b,*p,*q; char ch,*r; 一般式:基类型 *指针变量名; 2 定义指针变量时,可同时初始化: int a,b,*p= 注:指针变量只能存放地址,并且必须是与指针基类型相同 类型的变量的地址,不能将一个整数赋给指针变量。,(2) 通过指针变量引用指针变量所指的变量 例如: int a ,b,*p,*q; p= 以八进制的数的形式输出指针变量p、q的值。,例8.2 (p214) 输入a,b两个整数,按先大后小顺序输出。 设计算法:使用指针,不交换两个整型变量的值,而是 交换指针变量的值。 编程序: #include void main( ) int a

3、 ,b,*p,*p1,*p2; p1= ,8.2.2 指针变量作为函数参数 同其他变量一样,指针变量也可以作函数的参数,作用是将一个变量的地址传送到另一个函数中。 例8.3 (p215) 用函数实现将两个整数交换,然后在main函 数中输出交换后的变量值。 #include void swap(int *p1,int *p2) int temp; temp=*p1;*p1=*p2;*p2=temp; void main( ) int a ,b,*q1= ,讨论:下列3个函数是否能完成交换两个变量的值?为什么? (1) void swap(int x ,int y) int temp; temp

4、=x ; x=y ; y=temp; (2) void swap(int *p1,int *p2) int *temp; *temp=*p1;*p1=*p2;*p2=temp; (3) void swap(int *p1,int *p2) int *temp; temp=p1; p1=p2; p2=temp; 结论:用指针作函数的参数,可以将多个值带回到主 调函数,相当有多个返回值。,8.3 通过指针引用数组,8.3.1 数组元素的指针 数组中的每个元素同变量一样,都有相应的地址,即为数组元素的指针,也可以将此地址放到一个指针变量中。 例如:int a10,*p; p= *p=20; /*同a

5、3=20*/ 注意:数组名是地址常量,是数组的首地址,亦是 数组中首元素的地址,即元素a0的地址。,8.3.2 通过指针引用数组元素 引进指针概念后,引用一个数组元素可以有2种方法: (1) 下标法 :即数组名加下标,如ai形式。 (2) 指针法:即地址法,如*(a+i) 同ai一样。 例8.6 (p221) 用不同的方法输出整数数组的元素值。 #include void main() int i,j,t,a20,*p=a; for(i=0;i10;i+) scanf(“%d”,for(i=0;i=0;p-) printf(“%4d”, *p); printf(“n”); /*分析下列方法正确

6、否?*/ for(i=0;i10;i+) printf(“%4d”, *(a+); printf(“n”); 总结: 元素: ai、 *(a+i) 、* (p+i)、 pi 指针: &ai、 a+i、 p+i、 思考:如何用同样的方法完成输入?,当指针变量p指向数组元素时,可以进行下列运算: p与整数做“加、减”运算 如:p=&a2; p=p+1:即p指向了下一个元素,即是元素a3的地址; p=p-1:即p指向了上一个元素,即是元素a1的地址; 注:运算p=p+1并不是简单的将p的值加1,而是加上一 个数据元素所占的字节数:p=p+1*d。一般情况下, p=p+i,实际是计算p=p+i*d。减

7、运算也一样。 (2) 两个数组元素的指针可以进行“关系”运算 如:p=&a0;q=&a2;则p=0,使用指向数组元素的指针变量p时,要注意: p可以指向不同的元素 如:p=&a0;p+即指向元素a1;但a+是错误的,因 为a是数组名,数组名是指针常量,不能改变它的值。 (2) 注意指针变量的当前值,尤其注意其起始值。 请看例8.7 (p223) 当指针变量值超出数组范围时,编译系统并不认为非法 只有使用时保证不超出范围,否则会出现意想不到的错误。 (3) 指针变量p也可以带下标,如pi,系统解释为*(p+i),此 时要注意p的当前值,若p=a,则pi相当ai,若p=a+2,则 pi相当ai+2

8、,即p3相当时a5。建议初学者少用这种容易 出错的方法。,8.3.3 用数组名作函数参数 在第7章中介绍过数组名做形参,如: void sqrt(int a ,int n) void main() int array10,*p=array; sqrt(array,10); /*也可以写成sqrt(p,10); */ 定义函数中,a是形参数组名,相当是指针变量,所以将函数首部写成:void sqrt(int *a ,int n) 是一样的。 调用函数时,把实参数组名array(指针常量)传递给a,此时a和array指向同一个数组,因此在对形参a数组排序时,等于直接在实参数组array上完成。直接

9、改变了数组元素值。 用数组名作参数可以有4种不同的形式,用数组名作参数可以有4种不同的形式: 形参 实参 数组名 数组名 指针变量 数组名 数组名 指针变量 指针变量 指针变量 注意: 前面介绍过,用指针作函数的参数,可以将多个值带回到主调函数,相当有多个返回值。 数组名是指针,因此在对形参数组进行改变时,等于直接在实参数组上完成,相当形参数组的所有值都返回给实参数组。 例8.9 (p228) 用指针和函数完成选择法排序。,8.4 通过指针引用字符串,数组元素可以作为函数的参数,其用法与变量相同;数组名也可以作为函数的参数,传递的是数组首元素的地址。 8.4.1 数组元素作函数参数 数组元素可

10、以作为调用函数时的实参,传值给形参。数组元素不能作为函数的形参。 例如: int a10; x=max(a1,a2); /*求元素a1、a2中大的*/ int max(int x,int y) 不能写成: int max(int a1,int a2) 例7.6 (P185),7.4.2 数组名作函数参数 数组名也可以作为函数调用时的实参,传递的是数组首元素的地址(即数组的首地址),不是将数组中的所有元素传递给形参。此时,对应的形参应当是数组名或指针变量(见第8章)。 例7.7 (P186) 例7.8 (P188) #include void main( ) float average(floa

11、t array ); /*函数原型*/ float scroe10,aver); aver=average(score ); /*调用函数,数组名为实参*/ float average(float array ) /*数组名为形参*/ ,例7.9 (P189)用一个函数实现选择法对10个数排序。 #include void sort(int a ,int n) /*定义函数,数组名为形参*/ int i,j,k,t; for(i=0;in-1;i+) k=i; for(j=i+1;jn;j+) if(ajak) k=j; t=ai;ai=ak;ak=t; void main( ) int a1

12、0 =12,6,3,7,4,9,13,2,10,8; sort(a,10 ); /*调用函数,数组名为实参*/ ,7.5 变量的作用域和生存期,7.5.1 变量的作用域局部变量和全局变量 变量的作用域亦称有效范围。若程序中只包含一个main函数,则在函数中定义的变量在整个函数中都有效。当一个程序中包含多个函数时,在A函数中定义的变量在B函数中能否使用?这就是作用域问题。 1 局部变量 在函数中定义的变量,只在本函数中有效,成为局部变量或内部变量。作用域只为本函数内。 注:(1) 不同函数中的局部变量可以使用相同的名字,他们 有各自的有效范围,互不影响。 (2) main函数中定义的变量也是局部

13、变量。 (3) 函数的形参也是局部变量,函数外不能引用。 (2) 复合语句中可以定义变量,只在本语句中有效。,2 全局变量 一个程序包含多个文件,一个文件可以包含多个函数。在函数外定义的变量是外部变量或全局变量。有效范围为从定义的位置开始,到文件的结束。 当一个文件中全局变量与局部变量重名时,在局部变量的有效范围内,全局变量被“屏蔽”起来,即不起作用。当局部变量出了有效范围后,全局变量继续有效。 例7.10 请看下列程序的输出结果。 int m=13; int fun2(int x ,int y) int m=3 ; return(x*y-m); void main() int a=7 ,b=

14、5; printf(“%dn“,fun2(a,b)/m); ,7.5.2 变量的存储方式和生存期 除了作用域以外,变量还有一个重要的属性:生存期,即变量的存在时间。有些变量在程序运行的 整个过程中都存在,而有些变量只在调用函数时才临时分配存储单元,函数调用结束马上就释放了,变量不再存在。即变量分为:静态存储方式和动态存储方式两种,亦称存储类别。 由此可知,变量有两个属性:数据类型和存储类别。 C语言中有4种存储类别: 1 auto自动变量 前面用过的函数中,定义的形参和局部变量都是自动变量,存储类别定义的关键字auto省略,属于动态存储方式。有效范围和生存期均为本函数。 2 static静态变

15、量 函数中定义的局部变量静态变量,属于静态存储方式。有效范围为本函数,生存期为整个程序。,例7.12 分别求出15的阶乘值,并输出。(p196) #include int fac(int n) static int f=1 ; /*f为静态局部变量*/ f=f*n; return(f); void main() int i; for(i=1;i=5;i+) printf(“%d!=%dn”,i,fac(i); 注: 静态局部变量“f”的有效范围只限于函数fac,但是生 存期是整个程序,即在fac函数外,它的值仍然存在。再次调用函数时,继续在前一个值上累乘。 若静态局部变量在定义时未初始化,系统自动赋值为0。,3 registc寄存器变量 一般变量都存储在内存中,而寄存器变量存储在CPU的寄存器中,从而提高存取速度。 现代的计算机,系统可以自动完成此功能。 extern外部变量的作用域 扩展外部变量的作用域。,习 题,P208: 1、2、3、4、6、7、8、10,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号