指针C语言大学实用教程课件苏小红.ppt
《指针C语言大学实用教程课件苏小红.ppt》由会员分享,可在线阅读,更多相关《指针C语言大学实用教程课件苏小红.ppt(82页珍藏版)》请在三一办公上搜索。
1、第7章 指针,哈尔滨工业大学计算机科学与技术学院苏小红,C语言大学实用教程,内容提要,指针的概念;难点:对指针数据类型的理解 用指针做函数参数;利用字符指针存取字符串;字符数组和字符指针的区别与联系 指针数组应用;指向数组的指针与指针数组的区别 带参数的main函数;动态内存分配函数及其应用;一维、二维动态数组的实现,为什么引入指针的概念,铁杆C/C+程序员最挚爱的武器:指针C/C+的高效、高能主要来自于指针很多不可能的任务由指针完成,为什么引入指针的概念,指针为函数提供修改变量值的手段 为C的动态内存分配系统提供支持 为动态数据结构(如例链表、队列、二叉树等)提供支持 可以改善某些子程序的效
2、率,计算机内的存储部件,所有指令和数据都保存在内存里速度快,但是掉电即失可以随机访问只要指明要访问的内存单元的地址,就可以立即访问到该单元地址是一个无符号整数,其字长一般与主机相同内存中的每个字节都有唯一的一个地址地址按字节编号,按类型分配空间,内存(Random Access Memory)地址(Address),寻址方式,如何读写内存中的数据?通过变量的地址访问变量所在的存储单元两种寻址方式直接(寻址)访问通过变量地址直接存取变量内容间接(寻址)访问通过指针变量来间接存取它所指向的变量,任何变量在存在期间总有确定存储位置,有固定地址。,指针(Pointer)的概念,指针也是一种数据类型指针
3、变量 声明为指针类型的变量,专门存放地址数据的变量,指针的主要操作指针赋值:将程序对象的地址存入指针变量。间接访问:通过指针访问被指对象。指针还能保存其他对象的地址。下面讨论以变量为例。,指针p保存着变量x地址,也说指针p指向x。图示:,在C中使用指针常能写出更简洁有效的程序。有些问题必须用指针处理。指针在大型复杂软件中使用广泛。指针使用的水平是评价人的C程序设计能力的重要方面。C指针灵活/功能强。掌握有难度,易用错,应特别注意。应特别注意使用指针的常见错误,注意!,指针是变量,可赋值,其指向可以改变。现在p指向x,以后可能指向y。通过p访问被指对象的语句目前访问x,后来就访问y。这种新的灵活
4、性很有用。,7.2 指针变量的定义和使用,指针有类型,只能保存特定类型的变量的地址指向int的指针p只能指向int变量。常说int指针p1等。,指针是变量,可赋值取值,有定义域与存在期。应赋给类型正确的指针值,取出的值是特定类型的指针值。用(int*)表示整型指针的类型,其他类似。,如何定义指针变量?,定义指针变量 定义指针需指明指向类型。int*p;定义了一个指针变量p,简称指针pp是变量,int*是类型p里保存一个地址。指针变量可以与其他变量一起定义。如:int*p,n,a10,*q,*p1,m;,指针操作取地址运算符&和间接访问操作*。都是一元运算符,取地址运算,int i,*p;p=,
5、int*p;float*q;p=q;,int i;float*p;p=,int*p;p=100;,判断是真?是假?,指针变量只存放地址!,一个指针变量不能指向与其类型不同的变量!,我是真的,你猜对了吗?,应在类型相同的指针变量之间赋值,多个指针可能同时指向同一变量。变量相等是值相等,两个指针变量相等说明它们指向程序里同一东西。,间接运算符*-用来取指针指向地址的内容*p=0;-间接运算得到被指针所指的变量,这种表达式可以像普通变量一样使用,其值是p指向的内存的内容(但寻址方式和普通变量不同)。设p指向n。间接赋值:*p=17;-这里写*p相当于直接写n。,例:int*p,n=17;另一个赋值:
6、*p=17;m=*p+*q*n;/*访问n三次*/,+*p;/*使变量n的值加1,变成18*/(*p)+;/*使变量n的值再加1,变成19。*/*p+=*q+n;/*变量n被赋以新值57*/q=/*指针q指向了数组a的元素*/,指针变量与其它类型变量的对比,共性在内存中占据一定大小的存储单元先定义,后使用特殊性 它的内容只能是地址,而不能是数据必须初始化后才能使用,否则指向不确定的存储单元,对该空间进行访问,将可能造成危险可参与的运算:加、减一个整数,自增、自减、关系、赋值只能指向同一基类型的变量,指针的指向,只能指向同一基类型的变量,否则将引起warningfloat x;int*p=TC编
7、译warning:Suspicious pointer conversion in function mainVC编译warning C4133:=:incompatible types-from float*to int*,指针运算,算术运算int*p,a10;p=a;p+;/*p的值增加多少?*/指针的加减运算是以其指向的类型的字节长度为单位的另一个例子:int n=17;*p=,6000600160026003600460056006,使变量n的值加1,变成18,先取出变量p所指向的单元中的内容赋给m,再使p指向下一个地址单元。实际上,相当于语句:m=*(p+),可分解为下面两条语句:m
8、=*p;p=p+1;,指针运算,int*p,*q,a10,k;p=a;q=指针运算不能乱算一般只进行指针和整数的加减运算,同类型指针之间的减法运算其它运算,比如乘法、除法、浮点运算、指针之间的加法等,并无意义,所以也不支持,指针运算,关系运算指向同一种数据类型的两个指针才能进行关系运算值为1或0p q p q p=q不能与非指针类型变量进行比较,但可与NULL(即0值)进行等或不等的关系运算判断p是否为空指针P=NULLp!=NULL,指针运算,赋值运算指针在使用前一定要赋值为指针变量赋的值必须是一个地址,main()int*p;scanf(%d,p);,main()int a,*p=,错!因
9、为p中没有内容,即:p不指向任何变量,所以,一定要先给指针变量一个地址,指针与函数,指针既然是数据类型,自然可以做函数参数和返回值的类型指针做函数参数的经典例子:两数的互换(也是为什么我们要学习和使用指针的理由),void Swap(int*x,int*y)int temp;temp=*x;*x=*y;*y=temp;,main()int a,b;a=15;b=8;Swap(,void Swap(int x,int y)int temp;temp=x;x=y;y=temp;,main()int a,b;a=15;b=8;Swap(a,b);printf(a=%d,b=%d,a,b);,程序 1
10、,程序 2,例7.17.2:编写函数实现两数的互换,实 参,形 参,结果有何不同?,Not Work!Why?,主调函数,被调函数,main()int a,b;a=15;b=8;Swap(a,b);printf(a=%d,b=%d,a,b);,void Swap(int x,int y)int temp;temp=x;x=y;y=temp;,5,5,a,b,实 参,形 参,9,9,程序 1,x,y,5,5,temp,9,主调函数,被调函数,main()int a,b;a=15;b=8;Swap(,void Swap(int*x,int*y)int temp;temp=*x;*x=*y;*y=t
11、emp;,&a,&a,实 参,形 参,&b,&b,程序 2,x,y,5,temp,5,a,b,9,9,5,简单变量作函数参数与指针变量作函数参数的比较,分析:要(在一函数里)通过调用函数g修改调用处的变量(如局部变量),必须在g里掌握这个变量。,用指针可以解决问题。把m的地址(也是值)通过指针参数p传给函数g,函数g内对p间接访问就能操作m,包括对m赋值(改变m)。,例,通过函数调用把变量值设置为3:void set3(int*np)*np=3;使用实例:int main()int n,m;set3(,请回忆scanf的情况。,通过参数改变调用环境的方案包括三方面:函数定义中用指针参数;函数内
12、用间接操作实际变量;调用时以被操作变量的地址作为实参。函数swap可定义为:void swap(int*p,int*q)int temp;temp=*p;*p=*q;*q=temp;交换变量m和n的值,调用形式是:swap(,swap的参数类型是(int*),实参必须是合法的整型变量的地址。,设有变量定义:int a10,k;调用swap的实例:swap(,介绍标准库函数scanf时,强调在接受输入的变量前必须写&,就是将变量的地址传给scanf。scanf采用与swap一样的技术,通过间接访问为指定变量赋值,把输入的值赋给指定变量。,swap函数的几种错误形式(1/3),参数单向传递void
13、 Swap(int x,int y)int temp;temp=x;/*x,y为内部变量*/x=y;y=temp;,swap函数的几种错误形式(2/3),参数单向传递void Swap(int*p1,int*p2)int*p;p=p1;/*p1,p2为内部变量*/p1=p2;p2=p;,swap函数的几种错误形式(3/3),指针p没有确切地址void Swap(int*p1,int*p2)int*p;/*指针p未初始化*/*p=*p1;*p1=*p2;*p2=*p;,与指针有关的一些问题空指针值:一个特殊指针值,表示指针变量闲置(未指向任何变量)。唯一对任何指针类型都合法的值空指针值用0表示,
14、标准库专门定义了符号常量 NULLp=NULL;和p=0;相同前一写法易看到是指针,用时必须包含标准头文件。,指针初始化指针变量定义时可用合法指针值初始化:int n,*p=若没有初始化,外部指针和局部静态指针自动初始化为用空;局部自动指针不自动初始化。,指针使用中的常见错误使用指针的最常见错误是非法间接访问:在指针未指向合法变量的情况下做间接。如:int f(.)int*p,n=3;*p=2;.p没有初始化,没有指向合法变量。,“悬空指针”指值不是(当时)合法的变量地址的指针变量,也常被称为“野指针”。间接访问悬空指针是严重错误,后果可能很严重。,常见错误写法(设p是悬空int指针,n是in
15、t变量):swap(p,编译程序不能发现scanf的错误。有些系统可能对第一个例子(假设p未初始化)给出警告。间接访问空指针也同样无理,是非法的。,例 7.3 试用函数编程实现打印最高分及其学号例7.5,字符串与字符数组、字符指针,C语言并没有为字符串提供任何专门的表示法,完全使用字符数组和字符指针来处理字符串一串以0结尾的字符字符数组每个元素都是字符类型的数组char string100;字符指针指向字符类型的指针char*p;数组和指针可以等同看待,上面三者本质上是一回事,字符指针变量与字符数组的区别,定义方法不同 char str10;char*ptr;初始化含义不同 char str1
16、0=“china”;/为数组中的每个 元素赋初值 char*ptr=“china”;/用字符串“china”的 首地址,给指针变量ptr赋初值。,赋值方法不同 char str10;str=”china”;/*错误*/strcpy(str,”china”);/*正确*/char*ptr;ptr=”china”;字符指针是变量,而数组名是地址常量输入字符串时略有不同,使用字符指针的注意事项,字符指针变量必须有明确的指向,否则使用是危险的例如,输入字符串时 char*a;scanf(%s,a);/*错误*/应为:char*a;char str10;a=str;scanf(%s,a);/*正确*/,
17、定义字符指针时可用字符串常量初始化,如:char*p=Programming;1)定义了指针p2)建立了一个字符串常量,内容为Programming3)令p指向该字符串常量。图(a)char a=Programming;1)定义了一个12个字符元素的数组2)用Programming各字符初始化a的元素,图(b),1)指针p可重新赋值(数组不能赋值,只能通过字符串复制的方法或者为每个元素重新赋值的方法):p=Programming Language C;2)p和a类型不同,大小不同。a占12个字符的空间。3)a的元素可以重新赋值。如:a8=e;a9=r;a10=0;a的内容现在变成“Progra
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 指针 语言 大学 实用教程 课件 苏小红

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