模块5 指针及应用ppt课件.ppt
《模块5 指针及应用ppt课件.ppt》由会员分享,可在线阅读,更多相关《模块5 指针及应用ppt课件.ppt(183页珍藏版)》请在三一办公上搜索。
1、实用C语言程序设计教程李金祥 顾小晶 主编,Visual C+,模块5 指针及应用,任务1 地址与指针 学习目标 了解指针与地址的概念、掌握指针变量的定义、初始化及指针的运算。,案例一 指针与地址 1.问题描述 程序在计算机中运行的时候,所有数据都存放在内存中。而内存以字节为存储单元存放数据,不同的数据类型所占用的单元数不等。如整型占用2个单元,字符占用1个单元等。请编程验证计算机是如何存取需要的数据的。,5.1.1案例讲解,2. 编程分析 为了正确访问内存单元,计算机系统为每个内存单元进行编号,然后根据一个内存单元的编号准确地找到该内存单元。内存单元的编号也叫做地址。既然根据内存单元的地址就
2、可以找到所需的内存单元,因此通常也把这个地址称为指针。 要解决上面的问题,最好的办法是定义一组连续存储的变量,然后列出各变量的存储地址和值,从而得到它们的存储空间。,程序描述如下: main( ) 定义字符型变量charA 定义整型变量intB 定义长整型变量longC,longD 输出charA的地址和值 输出intB的地址和值 输出longC、longD的地址和值 ,3. 编写源程序 /* EX5_1.C */ #include main( ) char charA=A; int intB=1; long longC=2, longD =4; printf(charA的地址:%X , /*
3、以十六进制形式输出charA的地址*/,rintf(charA的值:%cn, charA); printf(intB的地址:%X , ,4. 运行结果如图5-1所示。 图5-1案例1运行结果,5.归纳分析 (1)系统根据变量的数据类型,分别为charA、intB、longC和longD分配1个、2个、4个和4个字节的存储单元,此时变量所占存储单元的第一个字节的地址就是该变量的地址。在图5-1中,变量charA的地址是12FF7C,intB的地址是12FF78,longC的地址是12FF74,longD的地址是12FF70。图5-2给出了案例1一次运行的内存存储示意。,图5-2 案例1内存存储示
4、意图,(2)在C语言中通过“&”获得数据的地址,“&”称为取地址运算符。因此,案例1中的语句,rintf(charA的地址:%x ,的作用就是输出变量charA的地址。 (3)通过变量名访问数据时,系统自动完成变量名与存储地址的转换,这种访问形式称为“直接访问”。此外,C语言中还有一种称为“间接访问”的形式。它首先将变量的存储地址存入另一个变量中,这个存放地址的变量称为指针变量,然后通过指针变量去访问先前的变量。这时,我们可以说指针变量指向那个变量。这种访问形式类似于打电话时的呼叫转移。,案例二 指针变量 1问题描述 从键盘输入a和b两个整数,按先大后小的顺序输出a和b。,2编程分析 从键盘输
5、入a和b两个整数后最好不要改变它们本身的值,因为其它程序中可能还会使用到这些原始数据。比较好的做法是根据我们的需要给原始数据做上“标志”:将较大的数标识为pMax,较小的数标识为pMin。这样在输出时可以根据做好的标志来输出。这种形式类似于给别人取外号。程序描述如下:,main( ) 定义变量a、b 定义指针变量pMax、pMin、pTemp 从键盘输入两个整数给a、b 令pMax指向a、pMin指向b 如果pMax指向的值小于pMin指向的值,利用pTemp将pMax、pMin交换 输出a、b的值 输出pMax指向的值、pMin指向的值 ,3编写源程序 /* EX5_2.C */ #incl
6、ude main( ) int a,b; int *pMax, *pMin, *pTemp; printf(请输入两个整数a,b:); scanf(%d,%d, if(*pMax *pMin) ,pTemp=pMax; pMax= pMin; pMin =pTemp; printf(na=%d,b=%dn,a,b); printf(max=%d,min=%dn,*pMax, *pMin); ,4运行结果如图5-3所示。图5-3案例2运行结果,5归纳分析 (1)严格地说,指针是一个地址,是一个常量。而用来存放地址的指针变量却可以被赋予不同的指针值,是变量。但有时也会把指针变量简称为指针。为了避免
7、混淆,本书约定:“指针”是指地址,是常量,“指针变量”是指取值为地址的变量。定义指针变量的目的是为了通过指针变量去访问它所指向的内存单元。,(2)定义指针变量包括三个内容:类型说明符、指针表识符和指针变量名。其中,类型说明符表示指针变量所指向数据的数据类型,指针表识符用“*”表示。其一般形式为: 类型说明符 * 变量名; 例如,案例2中语句“int *pMax,*pMin,*pTemp;”就表示定义三个指针:pMax, pMin和pTemp,它们的类型都是int类型,也就是说它们可以指向其他int类型的变量。,再如: int *p1; /*p1是指向整型变量的指针变量*/ float *p2;
8、 /*p2是指向浮点变量的指针变量*/ char *p3; /*p3是指向字符变量的指针变量*/ 应该注意的是,一个指针变量只能指向同类型的变量,如p2 只能指向浮点变量,不能时而指向一个浮点型变量,时而又指向一个字符型变量。,(3)指针变量定义后要给它们赋值,使其指向某个变量。赋值的方式有两种:一种是通过取地址符将变量的地址赋给指针变量,如语句“pMax = ”表示把pMax的值赋值给pTemp。此后,pMax、pTemp指向同一个存储地址。,(4)当一个指针变量指向某变量时,指针变量的值和指针变量的内容是两个不同的含义。指针变量的值表示它所指向的变量的地址,而指针变量的内容则表示所指向的变
9、量的值。例如语句“pMax = ”执行后,pMax的值就是变量a的存储地址,pMax的内容就是变量a本身。 C语言中通过“*”指针运算符来获得指针变量的内容。因此,要获得pMax的内容可以使用* pMax来得到。案例2中的“*pMax * pMin”语句就是判断pMax的内容是否小于pMin的内容。,同样,程序最后的输出语句“printf(max=%d,min=%dn,* pMax, * pMin);”表示输出pMax和pMin的内容(指向的变量)。 案例2执行时的内存存储示意图如图5-4所示。 (a)程序初始化 (b)输入3,6后,(c)执行完pMax=语句后图5-4 案例2执行时内存存储示
10、意图,(5)ANSI新标准增加了一种“void”指针类型,即可以定义一个指针变量,但不指定它是指向哪一种类型数据。 (6)当一个指针变量的值为0(或记为NULL)时,表示所指向的是空指针。,1基本概念 变量的指针就是变量的地址。存放变量地址的变量是指针变量。即在语言中,允许用一个变量来存放指针,这种变量称为指针变量。因此,一个指针变量的值就是某个变量的地址或称为某变量的指针。 定义5.1:数据所占存储单元的第一个字节的地址称为指针。,5.1.2 基础理论,定义5.2:用来存放数据存储首地址的变量称为指针变量,指针变量的类型决定了每次存取的字节数 定义5.3:指针变量的值就是它所指向的变量的地址
11、。 定义5.4:指针变量的内容表示它所指向的变量。 定义指针变量的一般形式为: 类型说明符*变量名;,2. 指针、指针变量的运算 指针变量可以进行某些运算,但其运算的种类是有限的。它只能进行赋值运算和部分算术运算及关系运算。 (1)指针运算符 取地址运算符& 取地址运算符&是单目运算符,其结合性为自右至左,功能是取变量的地址。在scanf函数及前面介绍指针变量赋值中,我们已经了解并使用了&运算符。,取内容运算符* 取内容运算符*是单目运算符,其结合性为自右至左,用来表示指针变量所指的变量。在*运算符之后跟的变量必须是指针变量。 需要注意的是指针运算符“*”和指针变量说明中的指针说明符“*”不是
12、一回事。在指针变量说明中,“*”是类型说明符,表示其后的变量是指针类型。而表达式中出现的“*”则是一个运算符用以表示指针变量所指向的变量。,(2)指针变量的赋值运算 通过取地址符将变量的地址赋给指针变量。例如: int a,*pA; pA=,B=pA; /*把a的地址赋予指针变量pB*/ 由于pA、pB均为指向整型变量的指针变量,因此可以相互赋值。 把数组的首地址赋予指向数组的指针变量。例如: int a5,*pA; pA=a; 数组名表示数组的首地址,故可赋予指向数组的指针变量pA。由于数组第一个元素的地址也是整个数组的首地址,因此,也可写为:,A= /*f为函数名*/,(3)指针变量的加减
13、算术运算 对于指向数组的指针变量,可以加上或减去一个整数n。设pA是指向数组a的指针变量(即pA指向a0),则pA+n表示把指针指向的当前位置(指向某数组元素)向后移动n个位置(即指向an)。指针变量的加减运算只能对数组指针变量进行,对指向其它类型变量的指针变量作加减运算是毫无意义的。 注意: 不能把一个数字直接赋值给指针变量。,例如下面的语句是错误的: int *p=2000; 程序中给指针变量赋值时,前面不要加上“*”说明符。例如下面的语句是错误的: int a=1; int *p; *p= 取地址运算符&和取内容运算符*是一对逆操作,同时出现时可以相互抵消。例如: &*p就等同于p。因为
14、p是指针变量,*p表示其指向的变量,&*p表示其指向的变量的地址,也就是p的值。,【实验5.1.1】阅读下面的程序,然后思考问题。 /*EX5_3.C*/ #include main( ) int a,b; int *pointer_1,*pointer_2; a=100;b=10; pointer_1=,5.1.3 技能训练,rintf(%d,%dn,a,b); printf(%d,%dn,* pointer_1,* pointer_2); 问题1:程序中有两处出现* pointer_1和* pointer_2,请区分它们的不同含义。 问题2:程序第5、6行的“pointer_1=”语句,那
15、么“&* pointer_1”的含义是什么? 问题4:*&a的含义是什么?,问题3: &* pointer_1可以写为&(*pointer_1),即取指针变量pointer_1指向变量的地址,等同于pointer_1。 问题4:*&a可以写为*(&a),&a表示取变量a的地址,*(&a)表示取该地址中变量的值,等同于a。,(2)在VC+集成环境中输入上述程序,文件存成EX5_3.C,如图5-5所示。图5-5 运行结果,【实验5.1.2】执行以下程序,写出运行结果。 /*EX5_4.C*/ #include main( ) int a,b,k=4,m=6,*p1= ,(1)编程分析 程序执行完“
16、int a,b,k=4,m=6,*p1=”语句后,为变量a、b、k、m,指针变量p1、p2分配内存空间,并赋初值4、6给变量k、m,使p1指向k,p2指向m。如图5-6。,图5-6 内存存储示意图,语句“a=p1=”,因此B的值为7。,(2)在VC+集成环境中输入上述程序,文件存成EX5_4.C,如图5-7所示。图5-7 运行结果,1编程规范 (1)定义指针变量时,* 号既可以紧接类型,也可以在变量名之前。例如:int*pnsize; 或 int*pnsize; 但不要写做:int*pnSize; 建议采用第二种形式。,5.1.5 编程规范与常见错误,(2)指针变量名必须具有一定的实际意义,形
17、式为pxAbcFgh。p表示指针变量,x表示指针变量类型,Abc、Fgh表示连续有意义字符串,如int*pnSize;p表示是指针变量,n表示该指针变量可以指向整型数据,Size表示该指针变量的含义。 (3)一般一次只声明一个变量和指针变量,否则就会让人混淆。比如:int* a, b;看起来b好像也是个指针,其实不是。,2. 常见错误 (1)使用未初始化的指针 指针是C 语言中的一个重要概念,也是比较难掌握的一个概念。C 语言中指针是用于存放变量地址的。指针变量是C 语言中的一个特殊类型的变量。指针变量定义后应确定其指向。在没有确定指针的具体指向前,指针变量的内容是随机的地址,盲目地引用将十分
18、危险。,(2)指针变量所指向的变量类型与其定义的类型不符 定义指针变量的一般格式为:类型说明符 *指针变量名;其中类型说明符规定的是指针变量所指向的变量的类型。C 语言规定一个指针变量只能指向同一类型的变量。 (3)指针的错误赋值 指针变量的值是某个数据对象的地址,只允许取正的整数值。然而,千万不能将它与整数类型变量相混淆。指针赋值,在赋值号右边的应是变量地址且是所指变量的地址。,任务2 指针与数组 学习目标 掌握指针访问数组的方法,领会指针处理字符串的方法,了解指针数组、多级指针等概念。,案例一 通过指针变量访问数组元素1.问题描述 已知2010年1月至12月的星期因子分别是4、0、0、3、
19、5、1、3、6、2、4、0、2。通过2010年的日期与相应星期因子计算后可以得到当天是星期几。计算方法如下:week=(monthSet+day)%7,其中week表示星期数:0表示星期天、1表示星期一,;monthSet表示该月的星期因子;day表示第几天。,5.2.1 案例讲解,例如,要知道2010年4月5日是星期几,只要将4月的星期因子3加上日期5,再与7取模,得1,表示该天是星期一。要求编写C语言程序,从键盘输入2010年的月份和日期,输出星期几。,2. 编程分析 对于十二个月的星期因子,我们可以存放在一个一维数组中,然后根据用户输入的月份到数组中取出相应的星期因子进行计算。 在C语言
20、中,指针和数组之间的关系非常密切。如果使用数组下标形式访问数组元素,每次都要进行地址计算。例如,要访问a3,就要通过数组地址a加上3倍的数组元素大小得到a3地址才能访问。因此,可以考虑使用指针变量的形式来提高数组访问效率和程序灵活性。,程序描述如下: int main( ) 定义数组保存12个月的星期因子 定义指针变量,并使指针变量指向数组 从键盘输入月份和日期,分别存入变量month和day 通过公式week=(monthSet+day)%7计算星期数 ,3. 编写源程序 /*文件名:Ex5_5.C 根据星期因子计算2010年某天的星期数 程序暂不考虑用户输入日期的有效性*/ #includ
21、e main( ) int monthSet12=4,0,0,3,5,1,3,6,2,4,0,2; int month=0,day=0,week=0; int *pMonthSet=monthSet;,rintf(请输入月份1-12:); scanf(%d, ,4. 运行结果如图5-8所示。图5-8 案例1运行结果,图5-9 案例1数组存储示意图,图5-10 指针变量指向数组,案例二 指向数组元素的指针变量 1问题描述 要求使用指针实现将键盘输入的一维数组的元素打印出来。,2. 编程分析 定义数组后用一个指针变量指向数组首元素,然后通过循环接收键盘输入,存放在指针变量表示的地址中,每次循环指针
22、变量下移一格。待输入完成后,再利用指针变量循环输出数组元素。程序描述如下: int main( ) 定义数组及计数器 定义指针变量,并使指针变量指向数组,通过记数器控制循环: 输入数据到指针变量 指向下一个数组元素 恢复指针变量使其重新指向数组 通过记数器控制循环: 输出指针变量指向的元素 指向下一个数组元素 ,3. 编写源程序 /*文件名:Ex5_6.C*/ #include main( ) int a10, i; int *p=a; printf(请输入十个整数:n); for(i=0;i10;i+) scanf(%d,p+); printf(输出:n);,=a; for(i=0;i10;
23、i+) printf(%2d,*p+); printf(n);4. 运行结果如图5-11所示。图5-11 案例2运行结果,5. 归纳分析 (1)由于p是指针变量,本身就表示地址,因此在使用scanf输入时可以直接使用。例如: “scanf(%d,p);”。案例2中采用了“scanf(%d,p+);”语句,表示将输入的数据存入p表示的地址中,然后将p指向下一个数组元素。 在这里,“scanf(%d,p+);”语句也可以使用“scanf(%d,”代替。,(2)使用指针变量时要注意它的当前值。例如,通过“scanf(%d,p+);”语句循环为数组赋值后,p已经超出了数组的存储范围,因此再次使用p输出
24、数组元素时需要再次执行“p=a;”,使其重新指向数组首地址。,案例三 使用指针变量访问二维数组 1问题描述 如果已知2010年至2015年的星期因子,同样可以利用公式week = ( monthSet + day ) % 7求解。请编程实现。,表5-2 2010年至2015年的星期因子,2. 编程分析 在案例1中,对于2010年一年的星期因子,我们使用了一维数组来存储。在本例中我们可以使用二维数组来表示数据:每年的星期因子占一行,每行12列,共6行。这样,我们可以在程序中定义一个6行12列的数组monthSets612,对其初始化后,由用户输入年份数据转入相应行查找对应的星期因子,进行计算。程
25、序描述如下:,main( ) 定义数组monthSets612保存每年的星期因子 定义指针变量pMonthSets 从键盘输入年份、月份和日期,分别存入变量year、month和day 根据year移动指针 通过公式week=(monthSet+day)%7计算星期数 ,3. 编写源程序 /*文件名:Ex5_7.C 根据星期因子计算2010-2015年某天的星期数 程序暂不考虑用户输入日期的有效性*/ #include main( ) int monthSets612=4,0,0,3,5,1,3,6,2,4,0,2,/*2010年星期因子*/ 5,1,1,4,6,2,4,0,3,5,1,3,/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 模块5 指针及应用ppt课件 模块 指针 应用 ppt 课件

链接地址:https://www.31ppt.com/p-1425014.html