C语言程序设计 教学课件 ppt 作者 孟庆昌 陈海鹏 马鸣远 刘振英 第8章 指 针

上传人:E**** 文档编号:89344995 上传时间:2019-05-23 格式:PPT 页数:171 大小:490KB
返回 下载 相关 举报
C语言程序设计 教学课件 ppt 作者  孟庆昌 陈海鹏 马鸣远 刘振英 第8章  指    针_第1页
第1页 / 共171页
C语言程序设计 教学课件 ppt 作者  孟庆昌 陈海鹏 马鸣远 刘振英 第8章  指    针_第2页
第2页 / 共171页
C语言程序设计 教学课件 ppt 作者  孟庆昌 陈海鹏 马鸣远 刘振英 第8章  指    针_第3页
第3页 / 共171页
C语言程序设计 教学课件 ppt 作者  孟庆昌 陈海鹏 马鸣远 刘振英 第8章  指    针_第4页
第4页 / 共171页
C语言程序设计 教学课件 ppt 作者  孟庆昌 陈海鹏 马鸣远 刘振英 第8章  指    针_第5页
第5页 / 共171页
点击查看更多>>
资源描述

《C语言程序设计 教学课件 ppt 作者 孟庆昌 陈海鹏 马鸣远 刘振英 第8章 指 针》由会员分享,可在线阅读,更多相关《C语言程序设计 教学课件 ppt 作者 孟庆昌 陈海鹏 马鸣远 刘振英 第8章 指 针(171页珍藏版)》请在金锄头文库上搜索。

1、第8章 指 针,本章介绍指针的概念、指针变量的定义及引用方式、指针变量的运算、利用指针变量构成复杂的数据类型以及指针变量的典型应用等。,8.1 什么是指针,整个内存由连续的存储单元组成,每个存储单元都有惟一的地址编号。内存地址的号码是统一编排的,从0到所装内存的最大值。 在源程序中定义的变量,在编译时就为它们分配相应的内存单元。例如: int x; float t; x=10; t=0.618;,经编译后它们在内存中的存放示意情况如图8-1所示。 程序中不同类型的数据要占用的内存空间的大小是不同的。,在执行程序时,CPU并不直接识别变量的名称,但它知道各变量在内存的地址。所以,在机器内部对变量

2、值的存取是通过各自的地址进行的。 这种在编程时直接按变量名来取变量值的方式称为“直接访问”方式。对变量的访问还有“间接访问”方式。,图8-1 变量在内存中的存放情况,图8-2 间接访问,指针是C语言中的一种数据类型,它表示对应数据在内存中存储单元的地址。简言之,指针是内存地址的别名。 如果一个指针变量的值恰好是另一个变量的内存地址,那么,就说该指针变量指向相应的变量。,图8-3 指针变量指向一个变量,8.2 指针变量的定义,指针变量定义的一般形式是: 类型 *指针变量名; 例如: int *p; /* p是指向整型变量的指针变量*/ char *next; /* next是指向字符型变量的指针

3、变量*/ float *fp; /* fp是指向浮点型变量的指针变量*/ double *dp; /* dp是指向双精度型变量的指针变量*/,对指针变量的定义应注意以下几点。 指针变量名之前的“*”号意味着“指向的指针”,就是说它所修饰的变量是指针变量。 指针变量是用它们所指向的对象的类型来表征的。, 从语法上讲,指针变量可以指向任何类型的对象,包括指向数组、指向别的指针变量、指向函数或指向结构变量等等,从而可以表示复杂的数据类型。例如,有下列数据说明:,char (*ptr)5; /*ptr是指向由5个字符元素构成的数组的指针变量*/ int * ip; /*ip是一个指向“指向整型量的指针

4、变量”的指针变量*/ int * fip( ); /*fip是返回指向整数的指针的函数*/ int (*pti)( ); /*pfi是指向一个返回整数的函数的指针变量*/图8-4 定义指向字符数组的指针变量 int * (*pfpi)( ); /*pfpi是一个指向函数的指针变量,该函数返回指向整数的指针*/,指针变量的类型就是把相应数据说明中的标识符(即变量名)去掉后所余下的部分。例如: char(*ptr)5;,图8-4 定义指向字符数组的指针变量,应注意,对ptr进行上述定义之后,仅表示它“能够”指向由5个元素构成的字符数组,但并未实际指向某个数组。 指针变量也占用内存单元,而且所有指针

5、变量占用内存单元的数量都是相同的。 例如: int a,*ap; double *dp,var;,8.3 指针变量的引用,8.3.1 &运算符 &是单目运算符,其作用是取出操作对象在内存单元的地址。它所作用的操作对象必须是变量或者数组元素。,&不能作用于表达式或者常量, 例如: int a,b; double var; char name10;,那么,&a, &b, &var, &name0 &name9等表达式都是合法的。然而,表达式&(a+1),&(a+b),&5, &(var*3.14),&name都是非法的。 另外,&运算符也不能作用于寄存器类变量。,8.3.2 *运算符,运算符*也是

6、单目运算符,其作用是访问操作对象所指向的变量。它所作用的操作对象必须是指针变量或指针表达式,就是说,这些对象都已指向内存中确切的单元。例如: int *p; p= *p=99;,因此,当p指向a之后,*p就等同于a,可完全当成一个整数变量来使用。 在程序中使用指针变量进行间接访问之前,必须给它们赋初值,使它们指向相应的变量。,一个指针变量只能指向同一类型的变量。 指针变量的间接访问就是该指针变量所指向的变量。,8.4 指针变量的运算,址量并不是整数,指针变量的取值和运算始终与内存地址的表示关联在一起。 指针变量的运算可以包括以下几个方面。 (1)所有类型的指针变量都可置为NULL,其值是0。N

7、ULL指针也称作空指针,在程序中通常用它作为某种标志(如链表的末尾、函数调用失败等)。,(2)可以把一个地址值赋给同类型的指针变量。为指针变量赋值的方式有以下几种。 利用单目运算符&取出运算对象的地址,然后赋给相应的指针变量。 将一个变量的地址赋给指针变量时,要求二者的基本类型必须相同。, 同类型的指针变量间可进行赋值运算,使二者指向同一对象。例如: int a,*pi,*pj; pi=,图8-5 两个指针变量都指向a, 利用强制类型转换符可实现不同类型指针变量间的交叉赋值。例如: int a,*pa; float f,*pf; 那么, pa=(int *), 对指向字符的指针变量赋初值可采用

8、特殊形式用字符串赋值。例如: char *ptr1; ptr1=“How are you!“;,在使用指向字符的指针变量时还要注意,不能利用下述方式对它赋初值: char *ptr; scanf(“%s”, ptr); (3)指针变量的引用可以像简单变量一样出现在表达式中。,例8-1 指针简单应用示例。 int a = 0,1,2,3,4; main( ) int i,*p1,*p2; for(i=0; i=4; i+) printf(“%d“, ai);,printf(“n“); for(i=0; i=4; i+) p1= ,printf(“n“); for(i=4;i=0; i ) p1=

9、 ,运行结果是: 0 1 2 3 4 0*1*2*3*4* 4!3!2!1!0! (4)指向同一数组的两个指针变量可以进行比较。,同一数组的元素所占的内存空间是连续分配的,而不同数组所占空间的分配情况是不固定的。 例8-2 用指针变量方式编写函数reverse(s),实现将字符串s的字符全部首尾颠倒。如图8-6所示。,图8-6 字符串首尾颠倒,#include stdio.h #define N 50 void reverse(char *s); int strlen(char *a); main( ) ,char bufN; printf(“Input a stringn“ ); scanf

10、(“%s“, buf ); reverse(buf); printf(“%s“, buf); return(0); ,void reverse(char *s) int c, k; char *p; k=strlen(s); for(p=s+k1; sp; s+,p ) c=*s; *s=*p; *p=c; , int strlen(char *a) int n=0; while(*a+ != 0) n+; return(n); ,(5)指针变量可以执行增量运算。例如: char *s=“Programming languages“; while (*s) putchar (*s+);,需注意

11、指针变量增1减1的含义:指针变量每执行一次增1操作,就指向后面一个数组元素。 另外,要注意*和+、 连用时的结合性。如*s+等价于* (s+) 。,*+s等价于* (+s),+*s等价于+(*s),而(*s)+是取出s所指单元的内容,然后该内容增1。 对于 和*连用时也有类似情况。 (6)指向同一数组的两个指针变量可以相减 。,(7)指针变量可以加上或减去一个整数。 注意,这里的整数是表示相对指针变量所指当前位置的位移。例如: int a10,*p; p= 那么表达式 p+n 就表示数组a第n个元素的地址,即&an。,图8-7 指针变量加减整数,另外,p+1与p+有区别。 指针变量的计算始终是

12、一致的,所有指针变量操作都自动考虑到指针变量所指对象的类型,在程序中不需要做什么改动。,8.5 指针变量和数组,指针和数组有着特殊的关系。当你利用下标形式存取一个数组元素时,实际上是在使用指针进行操作。 数组在内存的起始地址就称作数组的指针,而数组元素在内存单元的地址称作数组元素的指针。,8.5.1 数组的指针和数组元素的指针变量,不带方括号的数组名就是该数组的指针,它指向其第0个元素。这样,如果我们有如下定义: int data5; 那么,data就是第0个数组元素的地址。,但必须注意,数组名是常量,对数组名不能当作指针变量使用。例如:像data+,&data,data=&a之类的表达式都是

13、非法的。,例8-4 显示有效数组元素的地址。 /* Demonstrates the relationship between addresses and */ /* elements of arrays of different data types. */ #include main( ) ,short s10, *sp; int a10, *ap,i; float f10; double d10; sp=s; ap=a;,/*Print the table heading */ printf(“%19s%12s%12s%12s“,“Short“,“Integer“,“Float“,“Do

14、uble“); printf(“n=“); printf(“=“);,/*Print the addresses of each array element. */ for(i=0;i10;i+) printf(“nElement %d:%lu*%lu*%lu*%lu“,i,(unsigned long)sp+, (unsigned long)(ap+i),(unsigned long) ,8.5.2 利用指针变量引用数组元素,数组名就表示该数组的首地址。在程序中通过下标引用数组元素,经过C编译之后,下标值的计算就变为“基址+位移”的计算,而引用元素的值就变为间接存取对应单元的内容。,图8-8

15、 引用数组元素的内部实现,如果定义p为指向数组data的指针变量: int *p=data; 那么,p的值就表示数组data的基址,而(p+i)实现“基址+位移”的运算,其值恰好是数组data第i个元素的地址,即&datai。,一个指向数组的指针变量在程序中也能够以数组名的形式出现。 p0就等价于data0,p1等价于data1,p4等价于data4。 例8-5 函数strcpy( s , t ) , 它把字符串t复写到字符串s中。, 用数组方案实现: void strcpy(char s , char t ) /* copy t to s */ int i; i=0; while(si=ti)! = 0 ) i+; ,为了进一步对比,写一个strcpy( )的指针方案: void strcpy(char *s , char *t ) /* copy t to s; pointer version 1 */ while(*s = *t) != 0 ) s+; t+; ,在函数定义中形式参数的定义 char s ; 和 char *s; 完全等价, 事实上,当主调函数把一个数组名传给被调函数时,并不是把整个数组都传过去C语

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

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

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