C语言与程序设计教程 教学课件 ppt 作者 胡元义 全书教案_ 第6章

上传人:E**** 文档编号:89345192 上传时间:2019-05-23 格式:PPT 页数:287 大小:1.79MB
返回 下载 相关 举报
C语言与程序设计教程 教学课件 ppt 作者 胡元义 全书教案_ 第6章_第1页
第1页 / 共287页
C语言与程序设计教程 教学课件 ppt 作者 胡元义 全书教案_ 第6章_第2页
第2页 / 共287页
C语言与程序设计教程 教学课件 ppt 作者 胡元义 全书教案_ 第6章_第3页
第3页 / 共287页
C语言与程序设计教程 教学课件 ppt 作者 胡元义 全书教案_ 第6章_第4页
第4页 / 共287页
C语言与程序设计教程 教学课件 ppt 作者 胡元义 全书教案_ 第6章_第5页
第5页 / 共287页
点击查看更多>>
资源描述

《C语言与程序设计教程 教学课件 ppt 作者 胡元义 全书教案_ 第6章》由会员分享,可在线阅读,更多相关《C语言与程序设计教程 教学课件 ppt 作者 胡元义 全书教案_ 第6章(287页珍藏版)》请在金锄头文库上搜索。

1、第6章 指针,6.1 指针和指针变量 6.2 指针变量与数组 6.3 指针变量与字符串及多级指针变量 6.4 指针变量与函数 *6.5 动态数组 6.6 典型例题精讲,6.1 指针和指针变量,6.1.1 地址和指针的概念 在计算机中,内存是一个连续的存储空间;在这个空间中每一个内存单元都对应一个唯一的内存地址;并且,内存的编址由小到大是连续的,它的基本单位是“字节”。对程序中定义的变量,编译过程中系统根据该变量定义时获得的类型信息,为其分配相应长度的连续内存单元用来存放它的值。,例如在C语言中,一个整型变量占4个字节的内存单元,而一个双精度型变量占8个字节的内存单元。并且,给每个变量分配的这连

2、续几个内存单元的起始地址就是该变量的地址;也即,编译后每一个变量都有一个确定的变量地址,对变量的访问就是通过这个变量地址进行的。当引用一个变量时,实际上就是从该变量地址开始的若干连续单元中取出数据;当给一个变量赋值时,则是将这个值按该变量的类型存入该变量地址开始的若干连续内存单元中。显然,变量地址所对应的内存单元中存放的内容即为该变量的值。,我们可以通过地址运算符“ /*输出变量a的16进制地址*/,通常把变量地址形象地称之为“指针”,意思是通过这个“指针(即地址)”可以找到该变量。在C语言中,允许使用一种特殊的变量来专门存放某个变量的地址(即该特殊变量的内存单元中存放的是某个变量的地址而不是

3、其他数据,这一点与普通变量不同),这种特殊变量就称为指针变量。,注意,指针是一个地址,且主要是指变量或数组元素的地址,它是一个常量;而指针变量本身是一个变量并且是一个存放地址的变量,主要用来存放其他变量或数组元素的地址;也即,指针变量的值即为指针。在后续章节中我们还可以看到:指针变量的值不仅可以是像int、float等简单变量的地址,也可以是数组、结构体等构造类型的变量地址,即用指针变量来指向某种构造类型的变量,这样就可以访问到该类型变量中的任一元素(成员)。这是引入指针变量的一个重要原因。,引入指针变量的另一原因是:C语言允许在程序的执行过程中生成新的变量,由于这种变量是在程序执行过程中动态

4、产生的,故无法事先在程序或函数说明部分对其进行定义。因此,这种动态生成的变量没有名字,所以只能通过指针变量去间接地访问它(即由指针变量所存放的该动态变量的地址去访问这个动态变量)。 有了指针变量,访问变量的方式也得到了扩充:一种是我们前面介绍过的按变量名直接存取变量值的访问,称为直接访问;另一种就是本章介绍的通过指针变量所存放的变量地址找到该变量后再对该变量值进行的存取访问,称为间接访问。,在第9章还可以看到,我们可以把函数的首地址(该函数所对应的程序代码段首地址)赋给一个指针变量(此时,函数名可以看做为是一个变量),使该指针变量指向这个函数,然后通过指针变量就可以找到并执行这个函数;这和上面

5、通过指针变量来存取某个变量值的概念是完全不同的。,6.1.2 指针变量的定义和初始化 1. 指针变量的定义 指针变量是用来存放其他变量地址的变量,所以和普通变量一样必须先定义、后使用。指针变量定义的一般形式如下: 类型标识符 *变量名;,注意: (1) 在指针变量的定义中,变量名前的“*”号仅是一个符号,它表示该变量名为一个指针变量而不是指针运算符;如果定义时变量名前无“*”则为一普通变量而不是指针变量。 (2) 类型标识符表示该指针变量所指向那个变量的数据类型;也即,一旦定义了一个指针变量,则它只能指向由类型标识符所规定的这种类型变量,而不允许指向其他类型的变量。注意,类型标识符并不是指针变

6、量自身的数据类型,因为所有的指针变量都是用来存放地址值的,其数据类型必然为整型,故无需再进行说明。例如:,int *p1,*p2; char *q; 则指针变量p1、p2只能指向整型变量,而指针变量q则只能指向字符型变量。注意,指针变量p1、p2不能如下定义: int *p1,p2; 这种定义方式则定义了p1为指针变量,而p2为整型变量;也即在定义中以“ * ”开头的变量是指针变量,否则不是指针变量。,2. 指针变量的初始化 指针变量的初始化有两种方法:一种是先定义再赋初值,另一种是在定义的同时赋初值。需要注意以下两点: (1) 不要引用未经赋值的指针变量,未经赋值的指针变量是不能使用的,否则

7、将造成系统混乱。 (2) 给指针变量赋值只能赋给地址值,而不能是其他任何类型的数据,否则会引起错误。,下面我们通过例子来看一下两种初始化的方法: int a; int *p1; p1= 这是先定义再赋初值的方法。即先定义一个整型变量a和一个指向整型变量的指针变量p1,然后再把a的内存地址赋给p1,此时指针变量p1就指向了整型变量a。由于C语言中提供了地址运算符“&”来表示变量的地址,因此我们可以通过变量名a前面加上地址运算符“&”来得到变量a的地址。,char b; char *p2=,赋给指针变量的值其类型必须和指针变量定义时的指向类型一致。由于指针变量p1只能指向float类型的变量,而a

8、是一个整型变量,因此出错;指针变量p2出错的原因是赋给它的是一个没有定义的变量c地址值,既然没有定义,也就不存在该变量的内存地址;指针变量p3的错误是接受了一个非法地址值,变量的地址是在该变量定义时由系统分配确定的,它只能通过“&”运算符来获得该变量的地址,而不能随便将一个地址之外的值赋给指针变量,这样会引起严重的后果。,6.1.3 指针变量的引用和运算 1. 指针变量的引用 引用指针变量的值(即所指向的变量地址)与引用其他类型的变量一样,直接用指针变量的变量名即可(变量名前不加“ * ”)。但是,我们主要关心的是指针变量所指向的那个变量的值,C语言采用指针变量的变量名前面加上“ * ”来表示

9、该指针变量所指向的那个变量的值。例如: int a=10; int *p= 指针变量p与它所指的变量a之间的关系示意如图6-1所示。,图6-1 指针变量p与它所指变量a之间关系示意,由图6-1可知,指针变量p的值是它所指向变量a的地址(p等于,则将得到同一个结果:10。由此可知,引入了指针变量后,对于变量的访问,除了原有可供访问的变量名外,又多了一个可由指针变量间接访问的“别名”。,注意,指针变量定义时出现的“ * ”和指针变量引用中出现的“ * ”其含义是不同的。在指针变量定义中出现的“ * ”应理解为指针类型的定义,即表示“ * ”后的变量是一个指针变量;而引用中,在指针变量名前出现的“

10、* ”则为取值运算符,即通过“ * ”来对指针变量进行“间接访问”,也就是访问指针变量所指向的那个变量的值。,在C语言中有两个与指针有关的运算符,一个是“&”,即取其右边变量的地址,如“&a”表示取变量a的地址;另一个就是“ * ”,即访问其右边指针变量所指向的变量(值),如上面的“*p”就代表着p所指向的变量a。 “&”和“ * ”都是单目运算符,它们的优先级相同,并按从右向左的方向结合。例如:,int a; int *p= 则 &*p &a p 即“&*p”等价于“p”,并且“*&a”等价于a (同样也有:*&a *p a)。,例6.1 输入a和b两个整数,按由大到小的顺序输出a和b的值。

11、 #include void main() int a,b,*p,*p1,*p2; printf(“Input two data:“); scanf(“%d%d“, if(ab), p=p1; p1=p2; p2=p; printf(“a=%d,b=%dn“,a,b); printf(“max=%d,min=%dn“,*p1,*p2); 运行结果: Input two data:2 8 a=2,b=8 max=8,min=2,程序执行过程中,指针变量p1、p2和p的变化情况如图6-2所示。 图6-2 指针变量p1、p2和p随程序执行的变化情况,由图6-2可以看出,变量a和变量b的值始终没有改变

12、,而是通过交换p1和p2的指针值(即交换各自所指的变量地址)来实现将a值和b值由大到小输出的。从图6-2(b)可以看出,变量a同时又可用别名“*p1”或“*p”替代;而到了图6-2(d),变量a又变为可用别名“*p”或“*p2”替代。也即,指针变量的值(即所指的变量)不是固定不变的,而是在程序执行过程中不断变化的。,2. 指针变量的运算 1) 指针变量的赋值运算 给指针变量赋值时,所赋之值只能是变量的地址或地址常量(如数组名、字符串起始地址等),不能是其他数据。指针变量赋值运算的常见形式如下: float x,*f; f= /*将一个指针变量的值(地址)赋给另一个指针变量*/, char a1

13、0,*p; p=a; /*将一个数组的起 始地址赋给指针变量*/ char *s; s=“program“; /*将一个字符串的起始地址赋给指针变量*/ 对于,也可在定义时直接赋初值如下: char *s=“program“;,2) 指针变量与整数的加减运算 C语言的地址运算规则规定:一个地址加上或减去一个整数n,其运算结果仍然是一个地址。这个地址是以运算对象的地址作为基点后的第n个数据的地址或者是基点前的第n个数据的地址。这种运算适合于数组运算,因为一个数组在内存的存储是连续的,并且每个数组元素占用的内存单元的大小都相同(因为每个数组元素的类型相同);,所以一个指针变量指向数组时,给其加上整

14、数i则意味着该指针变量由当前位置向后移动i个数组元素位置。因此,指针变量加减一个整数n,并不是用它的地址值直接与n进行加减运算,而是使该指针变量由当前位置向后或者向前移动n个数组元素位置。例如: Int a10,*p=a; p=p+3; 其p指针的移动示意见图6-3。,图6-3 执行“p=p+3;”语句前后p指针位置示意,指针变量“+”、“-”运算也是如此,指针变量“+”运算后指向下一个数组元素地址,而指针变量“-”运算则指向前一个数组元素地址。 此外,还可以给指针变量赋空值“NULL”或0值,即该指针变量不指向任何变量(实际上NULL和转义字符 0 都是整数0,即NULL和 0 的ASCII

15、码值均为0)。例如: int *p; p=NULL;,当两个指针变量指向同一数组时,两个指针变量相减才有意义;相减结果的绝对值表示这两个指针变量之间数组元素的个数。注意,两个指针变量不能做加法运算,因为没有任何实际意义。,3) 指针变量的关系运算 两个指针变量(必须指向相同类型的变量)之间的关系运算,表示它们指向的变量其地址在内存中的位置关系,即存放地址值大的指针变量大于存放地址值小的指针变量。因此,两个指针变量之间可以进行、=、=、=和!=这6种关系的比较运算。,例6.2 求出下面程序的运行结果。 #include void main() int i=10,j=20,k=30; int *a

16、= ,解 需要注意的是,a表示它所指向的那个变量的地址,而 *a(引用时)则表示它所指向的那个变量的值。我们可以从程序中看出:*a等于 *c,其值为30;而 *b不变,其值为20。条件语句中的表达式“a=c”判断的是两个地址值,而a为i的地址、c为k的地址,这两个地址值必然不等,因此赋值语句“a=b;”没有执行。由此得到输出结果如下: a=30,b=20,c=30,我们也可以用动态图的方法进行分析。由于a、b、c为指针变量,它们都是指向其他变量的,因此我们画一个由指针变量到它指向的那个变量的箭头,此后,凡是遇到*a这种形式,都是从a开始依据箭头找到所指的那个变量,然后对那个变量进行操作。本题程序执行的动态图见图6-4,由图6-4可以很容易的得到运行结果为: a=30,b=20,c=30,图6-4 程序执行的动态图,6.2 指针变量与数组,6.2.1 指针变量与一维数组 一个数组在内存中的存储是由一段连续的内存单元组成的,数组名就是这段连续内存单元的首地址。

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


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

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