第6章指针电子课件 C语言程序设计.pptx
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《第6章指针电子课件 C语言程序设计.pptx》由会员分享,可在线阅读,更多相关《第6章指针电子课件 C语言程序设计.pptx(91页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第6章指针第6章 指针在前面章节的学习中,我们通过普通变量来直接访问程序内存空间,本章将要学习的指针,提供了另外一种间接访问内存的独特方式。指针是C语言中一种比较特殊的数据类型,存储的是变量的地址,变量能做的事情,指针都能做,正确运用指针,可使程序变得简洁而高效。本章涉及的案例与知识要点如图6-1所示。第6章 指针(1)理解地址的概念。(2)熟练掌握指针的定义和指针的基本操作方法。(3)掌握指针变量作函数参数的方法。(4)理解数组与指针的关系并能使用指针处理数组元素。(5)能够使用指针对字符串进行输入、输出。学习目标CONTENTS案例1:上课教室在哪里案例2:数据交换了吗案例3:冒泡排序再认
2、识案例4:禁用strcpy库函数案例5:指针挑大小案例1:上课教室在哪里某大学计算机应用专业2019年共招收4个班(1901班1904班),上课地点分别在1号教学楼的14341437教室。同学们根据教室地址准确地找到了各自的上课地点。若将教学楼看作计算机的内存,将教室看作一个个内存单元,请编程求出这4个上课教室对应的内存地址。案例1:上课教室在哪里案例描述案例1:上课教室在哪里相关知识地址与指针指针变量的定义与使用1)内存地址2)变量、变量名、变量的地址和变量的值3)指针、变量的指针和指针变量4)数据访问的两种方式1)指针变量的定义2)指针变量的使用1.地址与指针1)内存地址在计算机中,数据是
3、按二进制编码形式(0、1组合)存放在存储器中的。8位二进制数组成一个字节,存储器中一个字节称为一个存储单元,不同的数据类型占用的存储单元个数不等。例如,在VisualC+2010编译器下,字符型数据占用1个内存单元,单精度实数占用4个内存单元。为了能正确访问这些内存单元,系统会为每个内存单元进行统一编号,由于编号是唯一的,可以根据编号找到所需的内存单元。通常把内存单元的编号称为内存地址,简称地址。CPU就是通过内存地址来访问内存单元并进行数据存取(读/写)的。2)变量、变量名、变量的地址和变量的值变量即对应的内存单元。在C语言中,变量必须遵循“先定义,后使用”的原则。变量定义后,编译器为变量分
4、配相应的内存单元,用于存放数据,并将变量名和内存地址对应起来。(1)变量名。变量所占内存单元的名字,是一个合法的C语言标识符。案例1:上课教室在哪里案例1:上课教室在哪里(2)变量的地址。变量占用的内存单元的地址。(3)变量的值。在变量所对应的内存单元中存放的数据。3)指针、变量的指针和指针变量(1)指针。由于通过内存地址能够访问到所需内存单元,所以在C语言中,将内存地址称为指针,可理解为指针“指向”一个内存单元。(2)变量的指针。指向一个变量对应的内存单元,即“变量的地址”。(3)指针变量。在C语言中,用于保存内存单元的地址的变量。通常情况下,把指针变量简称指针,把地址常量简称地址。4)数据
5、访问的两种方式(1)直接访问。一般情况下,可直接通过变量名来获取变量的值,而无须知道每个变量在内存中的具体地址,变量名与具体内存地址的联系由C编译器自动完成。在程序中对变量进行的存取操作,实际上也就是对某个地址的内存单元进行的读/写操作。这种直接按变量的地址存取变量的值的方式,就称为直接访问。例如,存储了数据50的整型变量a(假如编译器为其分配了起始地址为2000的连续4个内存单元),则在直接访问时,就是先找到整型变量a的内存单元起始地址2000,再从2000开始往后连续访问四个内存单元,从而存取数据50,如图6-2(a)所示。(2)间接访问。先定义一个指针,然后将变量的地址赋给指针,再通过指
6、针存取它所指向的内存单元中的数据,这种数据访问方式就称为间接访问。如上例中,需先定义一个指向整型变量a的指针p,将a的起始地址赋给指针p(指针变量里存放地址2000),然后通过指针p来存取变量a的值,如图6-2(b)所示。案例1:上课教室在哪里2.指针变量的定义与使用1)指针变量的定义指针变量是用来存放内存地址的,通常用于存放一个变量的地址,故又称指向变量的指针。定义指针变量与定义普通变量类似,在变量名前加“*”即可,定义格式为:类型名*指针变量名1,*指针变量名2,;例如:int*p1,*p2;/*定义两个指针变量p1、p2,所指向的内存单元中存放的是整型数据*/案例1:上课教室在哪里类型名
7、表示指针所指向的内存单元中存放的数据的类型,“*”是指针的标志,表示该变量是一个指针变量。注意2)指针变量的使用定义指针变量后,要对它进行初始化或赋值后才可以使用。未初始化或未赋值的指针所指向的内存单元是随机的、无法确定的,此时使用它可能导致系统崩溃。为安全起见,一般定义指针变量时就将其初始化为NULL或某个变量的地址。NULL是在头文件stdio.h中预定义的常量,其值为0或0,赋给指针变量后,该指针变量为空指针。注意,此时该指针并不是指向地址为0的内存单元,而是指它是一个确定的值“空”,试图用空指针访问一个存储单元,会得到出错信息。(1)初始化指针变量。有两种方法初始化指针变量,一种是获取
8、变量的地址为指针赋值。需要用到取地址运算符“&”来获取变量的内存地址,使用格式为:&变量名案例1:上课教室在哪里例如:inta=50,*p=NULL;/定义一个int型的变量a,定义一个指向int型数据的指针变量p并初始化为NULL*/p=&a;/将变量a的地址赋给指针p,使p指向变量a所对应的内存单元/另一种是将同类型的其他指针的值赋给该指针变量,两个指针将指向同一片内存单元。例如:int*p=NULL;/定义一个指向int型数据的指针变量p并初始化为NULL/p=q;/q是一个已知且有值的同类型指针变量,赋值后两个指针指向同一片内存/(2)用指针获取数据。用指针获取数据指根据指针变量中存放
9、的地址,访问该地址对应的内存单元,存取其中的数据。需要用到取值运算符“*”,即在指针变量名之前添加“*”,使用格式为:指针变量名案例1:上课教室在哪里例如:inta=50,*p=&a;/定义变量a和指向int型数据的指针变量p并初始化为a的地址/printf(“用指针取值:%dn”,*p);/输出指针变量p所指向的内存单元中存放的数据/(3)指针变量的移动(加减法运算)。当指针指向一串连续的存储单元(如数组)时,指针变量可以通过加减法运算来移动指针,即改变指针的指向,如p+将指针移动到下一个数组元素,p-将指针移动到前一个数组元素。两个指针变量相减,得到两个指针相差的数组元素个数。这里的加1或
10、减1不是指地址加1或减1,而是加上或减去1个数组元素对应的数据类型的字节数,如图6-3所示。案例1:上课教室在哪里综上所述,使用指针变量间接访问数据的步骤可简单归纳为三步:定义指针变量、初始化指针变量和用指针获取数据。间接访问比直接访问麻烦,但在某些场合下只能使用指针间接访问,如用户使用malloc函数、calloc函数和realloc函数申请一块内存空间时,因为没有变量名,所以只能通过首地址(指针)对其进行操作。再如,通过被调用函数改变主调用函数变量的值时,也只能通过指针来实现。案例1:上课教室在哪里案例1:上课教室在哪里案例实现算法分析流程图表达代码实现运行结果1.算法分析将教室看作内存单
11、元,将每个班级看作变量,在编程实现时,可将教室地址设置为指针,它们分别指向1901班1904班各自上课的教室。2.流程图表达程序算法流程如图6-4所示。案例1:上课教室在哪里3.代码实现#include/标准输入/输出函数头文件#include/system()函数头文件intmain()/主程序开始intclass_1901=1434;/定义班级变量,并初始化为教室号intclass_1902=1435;intclass_1903=1436;intclass_1904=1437;int*address1,*address2,*address3,*address4;/定义各班级指针变量以存储/
12、内存地址指针初始化(&),获取各班级的内存地址并赋给相应指针变量(&为取地址运算符)address1=&class_1901;address2=&class_1902;address3=&class_1903;address4=&class_1904;案例1:上课教室在哪里/引用指针(*),输出指针变量所指单元的值及对应的内存地址,%x表示按十六进制输出printf(计应1901班上课地点%d教室的内存地址是:%xn,*address1,address1);printf(计应1902班上课地点%d教室的内存地址是:%xn,*address2,address2);printf(计应1903班上课
13、地点%d教室的内存地址是:%xn,*address3,address3);printf(计应1904班上课地点%d教室的内存地址是:%xn,*address4,address4);system(pause);/暂停屏幕,便于观察,按任意键退出return(0);案例1:上课教室在哪里4.运行结果程序运行结果如图6-5所示。案例1:上课教室在哪里案例2:数据交换了吗使用两种方式用函数实现数据交换功能,一种是普通变量为形参,另一种是指针变量为形参,下面看看这两种方式哪一种真正实现了数据交换。案例2:数据交换了吗案例描述案例2:数据交换了吗相关知识指针作为函数参数指针及其数据的交换1.指针作为函数参
14、数在C语言中,函数调用时实参和形参之间数据的传递原则是单向值传递,即只能由实参传递给形参,而不能由形参传递给实参。指针(地址)作为参数传递,也是单向值传递的,即形参指针不能改变实参指针值(地址)。但由于把实参指针值(地址)传递给了形参指针,形参指针与实参指针具有相同的地址,此时当形参指针改变其所指向的内存单元中存放的数据时,显然就是改变了实参指针所指向的内存单元中的数据,因为二者指向同一片内存单元,数据改变是同步的。使用指针作为函数的形参,通过传递地址的方式,可以达到在被调函数中对主调函数中的数据进行操作的目的。而使用普通变量作为函数的形参,不能在被调用函数中对主调函数的数据进行操作,即无法改
15、变实参的值。案例2:数据交换了吗2.指针及其数据的交换使用指针既可得到变量的地址,又可得到变量的值。因此,指针的交换既包含指针指向的交换,又包含指针指向的内存单元中存放的数据的交换。1)指针指向的交换指针指向的交换同数据的交换类似,要借助一个临时性的辅助指针变量来实现,即先定义一个同类型的辅助指针(temp)记录其中一个指针(p1)原来的指向,然后让该指针(p1)指向另外一个指针(p2),最后另外一个指针(p2)再指向原来的指针(p1)。假设p1、p2都是int型指针,交换两个指针指向的代码如下所示,示意如图6-6所示。int*temp;/*定义辅助指针*temp*/temp=p1;/*辅助指
16、针记录p1的指向(赋值)*/p1=p2;/*指针p1记录指针p2的指向(赋值)*/p2=temp;/*指针p2再指向p1原来的指向(赋值)*/printf(用指针取值:%dn,*p);/输出指针变量p所指向的内存单元中存放的数据案例2:数据交换了吗案例2:数据交换了吗2)数据的交换如果要交换指针所指向的内存单元中的数据,可用之前学习的取值运算符“*”取出指针所指向内存单元中的数据。假设p1、p2都是int型指针,则所指向的数据交换的代码如下,示意图如图67所示。inttemp;/*定义辅助变量temp*/temp=*p1;/*辅助变量记录p1指向的内存单元中的数据*/*p1=*p2;/*取出指
17、针p2指向的内存单元中的数据,并放到指针p1指向的内存单元中*/*p2=temp;/*将p1指向的原来的数据再放回到p2指向的内存单元中*/printf(用指针取值:%dn,*p);/输出指针变量p所指向的内存单元中存放的数据案例2:数据交换了吗案例2:数据交换了吗案例实现算法分析流程图表达代码实现运行结果1.算法分析第一步:根据案例描述,设计3个函数,一个是主函数main、一个是普通变量作形参函数swap_var(intnum1,intnum2)、一个是指针变量作形参函数swap_pointer(int*s,int*t)。第二步:两数交换要借助第三个变量(设为temp),然后依次循环赋值;如
18、果采用指针变量,则须用指针*s、*t取数据,然后依次循环赋值。第三步:在主函数中分别调用两个交换函数,看一看到底哪一个真正交换了数据。2.流程图表达程序算法流程如图6-8所示。案例2:数据交换了吗3.代码实现#include/标准输入/输出函数头文件/#include/system函数头文件/voidswap_var(intnum1,intnum2);/函数声明/voidswap_pointer(int*s,int*t);/函数声明/intmain()/主程序/inta,b;/定义整型变量/int*p1=NULL,*p2=NULL;/定义整型指针,并初始化为NULL/printf(输入两个整数
19、(以空格隔开、以回车结束):);scanf(“%d%d”,&a,&b);/输入两个整数/printf(两数交换位置前:a=%db=%dn,a,b);swap_var(a,b);/调用形参是普通变量的函数,验证两数是否交换位置/printf(普通变量作形参,两数交换位置后:a=%db=%dn,a,b);p1=&a;p2=&b;/获取a、b两数指针并赋值给指针变量/案例2:数据交换了吗swap_pointer(p1,p2);/*调用形参是指针变量的函数,验证两数是否交换位置*/printf(指针变量作形参,两数交换位置后:a=%db=%dn,a,b);system(pause);/*暂停屏幕,便于
20、观察结果,按任意键退出*/return0;/以下是函数定义voidswap_var(intnum1,intnum2)/*普通变量作形参,交换两数位置(此方式不能实现交换)*/inttemp;/*借助中间变量循环赋值*/temp=num1;num1=num2;num2=temp;案例2:数据交换了吗voidswap_pointer(int*s,int*t)/*指针作形参,交换两数位置(此方式可以实现交换)*/inttemp;/*借助中间变量循环赋值*/temp=*s;/*“*”表示取地址中存储的数值(取值运算符)*/s=t;t=temp;案例2:数据交换了吗4.运行结果程序运行结果如图6-9所示
21、。案例2:数据交换了吗案例3:冒泡排序再认识运用函数与指针,重新实现冒泡排序。案例3:冒泡排序再认识案例描述相关知识指针和一维数组数组名与指向一维数组的指针充当函数参数指针与二维数组1.指针和一维数组C语言中数组名代表数组的起始地址,即第一个元素的地址,其地址值是固定不变的。由于数组在内存中占用一片连续的存储空间,因此,用指针变量代替数组名,通过指针的移动来操作数组元素,更加方便执行,效率也更高。1)指向一维数组元素的指针指向一维数组元素的指针的定义方法与指向变量的指针的定义方法相同,在使用上略有不同。指向变量的指针仅仅指向一个变量,由于变量的地址不会被改变,故指针的值也不会改变。而指向一维数
22、组元素的指针可以指向数组中的每一个元素,虽然某一时刻只能指向某一个元素,但是可通过指针的自加或自减运算来移动指针,从而代替数组名来访问数组元素。指向一维数组元素的指针定义方法为:inta10,p=NULL;/定义一个整型数组a与指针p/p=a;/让指针p指向数组(将数组名a,也就是数组的起始地址赋给指针p)/案例3:冒泡排序再认识数组元素ai的地址可以用&ai表示,也可以用a+i表示,还可以用p+i表示。指针与一维数组的关系如图6-10所示。由图610可知,p的值、a的值、&a0的值相等,p+1的值、a+1的值、&a1的值相等,p+i的值、a+i的值、&ai的值相等。需要注意的是,加1不是加1
23、个字节,而是加1个数组元素所占内存单元的数目,如对整型数据就是加4个字节。案例3:冒泡排序再认识2)通过指针引用数组元素通过指针引用数组元素可采用“不移动指针”和“移动指针”两种方法。示例如下。inta10,p=NULL,i;/定义一个整型数组a与指针p及循环控制变量I/p=a;/*让指针p指向数组a,或使用p=&a0;*/案例3:冒泡排序再认识(1)p+是正确的,而a+是错误的。因为a是数组名,是个常量,不能改变;而p是指针变量,值可变,这称为指针的移动,指向下一个数组元素。(2)*p+等价于*(p+)。因为自加+与取值*优先级相同,结合方向自右向左,表示先取值再移动指针。(3)*p+表示先
24、取值再移动指针,而(*p)+则表示指针p所指向的数组元素值加1。注意(1)不移动指针。示例如下。for(i=0;i10;i+)/*输入数组元素,不移动指针*/scanf(%d,p+i);for(i=0;i10;i+)/输出数组元素,不移动指针/printf(%d,*(p+i);printf(%dn,*p);/输出指针变量p所指向的内存单元中存放的数据(2)移动指针。示例如下。for(p=a;pa+10;p+)/*输入数组元素,移动指针*/scanf(%d,p);for(p=a;pa+10;p+)/输出数组元素,移动指针(注意p需要重新初始化为数组名)/printf(%d,*p);案例3:冒泡排
25、序再认识(3)使用带下标的指针来访问数组元素,同数组名加下标方式一样。示例如下。for(i=0;i10;i+)scanf(“%d”,p+i);/输入数组元素/for(i=0;i10;i+)printf(%d,pi);/*使用p下标格式输出数组元素*/2.数组名与指向一维数组的指针充当函数参数数组名是地址,可与指向一维数组元素的指针相配合充当函数的参数,具体使用方式有如下几种。(1)实参是数组名,形参是指针。示例如下。voidfun(int*p)/*函数定义,指针p充当形参*/函数体案例3:冒泡排序再认识main()inta=1,2,3,4,5;fun(a);/函数调用,数组名充当实参/(2)实
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第6章指针电子课件 C语言程序设计 指针 电子 课件 语言程序设计
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内