C语言第8章的课件.ppt
《C语言第8章的课件.ppt》由会员分享,可在线阅读,更多相关《C语言第8章的课件.ppt(91页珍藏版)》请在三一办公上搜索。
1、1,第8章 指针,2,本章要求,掌握地址与指针的概念;掌握各类型指针变量的定义、赋值、指针运算符、指针运算;掌握一维数组的指针、二维数组的指针、字符串的指针的定义与应用;了解函数的指针和指向函数的指针变量;了解指针数组的概念与定义,多级指针的概念与定义。,3,8.1 地址和指针的概念,4,指针是C语言的一个重要概念,也是C语言的一个特色。它可以有效地表示复杂的数据结构;动态分配内存;能方便地使用字符串;有效而方便地使用数组;在函数调用时能返回得到多于一个的值;能直接处理内存地址等。掌握指针的应用,可以使程序简洁、紧凑、高效。每一个学习和使用C语言的人,都应当深入地学习和掌握指针。可以说,不掌握
2、指针就是没有掌握C的精华。,5,程序中每个实体,如变量、数组、函数等都要在内存中占有一个可标识的存储区域。每个存储区域由若干个字节的存储单元组成。内存中每个字节的存储单元都有一个“地址”。一个存储区域的“地址”是指该区域中第一个字节的地址。指针实际上是对存储单元地址的一种形象化描述。指针即地址。,6,程序中的变量表示命名了的存储区域。不同类型变量其存储区域字节单元数不一样。变量名表示该存储区域的别名。变量值是该存储区域中存储的数据。变量地址是该存储区域的首地址。变量地址可通过对变量名进行取地址运算得到。如:&a得到变量a的地址。,7,int a=3,b=4;float c=4.5,d=8.6;
3、char e=x,f=y;,变量地址(变量指针)是由操作系统自动分配,8,8.2 变量的指针和指向变量的指针变量,9,指针与指针变量,程序中通过地址或变量访问存储单元的方法称为直接访问。把一个变量的地址存储到另一个变量中,而通过另一个变量来访问该变量的方法称为间接访问。专门存放指针(地址)的变量称为指针(地址)变量。,10,11,变量的指针就是变量的地址。存放变量地址的变量则是指针变量,用来指向另一个变量。为了表示指针变量和它所指向的变量之间的联系,在程序中用“*”符号表示“指向”,例如,i_pointer代表指针变量,而*i_pointer是i_pointer所指向的变量,见图。,12,可以
4、看到,*i_pointer也代表一个变量,它和变量i是同一回事。下面两个语句作用相同:i=3;*i_pointer=3;第个语句的含意是将3赋给指针变量i_pointer所指向的变量。,13,8.2.1 定义指针变量,C语言规定所有变量在使用前必须定义,指定其类型,并按此分配内存单元。指针变量不同于整型变量和其他类型的变量,它是用来专门存放地址的。必须将它定义为“指针类型”。C语言中指针变量也有类型。指针变量的类型是指指针变量指向对象的类型,即指针变量存储的指针所表示的对象的类型。指针变量定义格式:类型标识符*指针变量名;,14,定义格式中类型标识符规定指针变量的类型。如:int*pa;指针变
5、量pa是一个整型指针变量,它指向一个整型变量。即pa可用来存放一个整型变量的地址(指针)。,15,float*pb,b;/*定义实型指针变量pb和实型变量b*/pb=/*将实型变量b的地址赋值给指针变量pb,这样指针变量pb就指向了实型变量b,通过pb可以间接对b进行访问*/,16,8.2.2 指针变量的引用,指针即地址,它实际上是整型数,因此指针变量有时可以象整型数一样进行引用。char*pc;printf(%x,pc);/*输出指针变量的值*/但请牢记,指针变量中只能存放地址(指针),不要将一个整型量(或任何其他非地址类型的数据)赋给一个指针变量。下面的赋值是不合法的:pointer_1=
6、100;(pointer_1为指针变量,100为整数),17,有关指针的运算符,&取地址运算符。单目运算符,作用是取操作数地址。*指针运算符。单目运算符,作用是对操作数作指向运算。其操作数必需是一个指针。如:*p=1表达式表示根据变量p的值,找到其对应的存储单元,给该单元赋值1。*(&a)表达式等价于a,18,int*pa,a;pa=,输出pa指向对象的值(间接访问),直接访问,19,例通过指针变量访问整型变量。main()int a,b;int*pointer_1,*pointer_2;a=100;b=10;pointer_1=,运行,20,main()int*p1,*p2,i1,i2;sc
7、anf(%d,%d,运行,几个指针应用的例子,21,main()int*p1,*p2,*p,i1=10,i2=20;p1=,运行,22,main()int*p1,*p2,i1,i2,i;i1=10;i2=20;p1=,运行,23,注意,*p1表达式表示指针变量p1指向的对象。在访问指针变量指向对象前,指针变量必需已指向明确。如:float*pa,a;*pa=3.14;/*错误,因为pa尚未指向任何变量*/pa=/*给pa指向变量赋值*/(*pointer_1)+相当于a+。注意括号是必要的,如果没有括号,就成为了*pointer_1+,和*为同一优先级别,而结合方向为自右而左,因此它相当于*(
8、pointer_1+)。由于+在pointer_1的右侧,是“后加”,因此先对pointer_1的原值进行*运算,得到a的值,然后使pointer_1的值改变,这样pointer_1不再指向a了。,24,8.2.3 用指针作为函数参数,用指针作函数参数,可将一个变量的地址传递到另一个函数中。从而在函数中,通过变量地址对作用域不在本函数的变量进行操作。,25,main()void sub(int*px,int*py);int x,y;sub(,x,y,&x,&y,px,py,函数调用时的值传递,运行,26,main()void swap1(int*p1,int*p2);int a=3,b=5;p
9、rintf(a=%d,b=%dn,a,b);swap1(,3,5,a,b,&a,&b,p1,p2,函数调用时的值传递,交换,运行,27,main()void swap2(int p1,int p2);int a=3,b=5;printf(a=%d,b=%dn,a,b);swap2(a,b);printf(a=%d,b=%dn,a,b);void swap2(int p1,int p2)int t;t=p1;p1=p2;p2=t;,3,5,a,b,3,5,p1,p2,函数调用时的值传递,交换,运行,28,main()void swap3(int*p1,int*p2);int a=3,b=5;pr
10、intf(a=%d,b=%dn,a,b);swap3(,3,5,a,b,&a,&b,p1,p2,函数调用时的值传递,交换,运行,29,8.3 通过指针引用数组,30,数组名代表数组的首地址,这个地址是在程序编译时由编译程序确定,程序运行时由操作系统具体分配。数组名因此也是一个指针。但它不是一个指针变量,因此其值是不能通过程序修改的。不同维数的数组名表示不同级别的指针。一维数组名是一级指针,二维数组名是二级指针,以此类推。,31,如:int a5=1,2,3,4,5,*pa,i;a=*/,a,a,pa,32,指针的加减运算含义,指针可作加减运算。C语言规定:指针加一表示其指向的下一对象的地址,减
11、一表示其指向的上一对象的地址。为实现该规定,C在处理有关指针的加碱运算时,会进行 特别处理。如指针变量p,加上n实际加的数值是:nsizeof(p指向的对象类型),33,a,a,pa,数组元素ai的实际地址可用公式:a+i2计算。类似pa+n实际是:pa+n2。即pa指向对象之后的第n个对象的地址。,34,数组元素访问的方法,下标法:如 a0,ai地址法:如*(a),*(a+i),35,main()int a5=1,3,5,7,9,i,*p;for(i=0;i5;i+)printf(%4d,ai);printf(n);for(i=0;i5;i+)printf(%4d,*(a+i);printf
12、(n);for(p=a;pa+5;p+)printf(%4d,*p);printf(n);for(p=a,i=0;i5;i+)printf(%4d,*(p+i);printf(n);for(p=a,i=0;i5;i+)printf(%4d,pi);,下标法,地址法,指针法,运行,访问数组元素的几种方法,36,int a10,*p,i;for(i=0;i10;i+)scanf(%d,a+);/*错误,数组名a不是指针变量,不能作自加运算,a+=1也是*/for(i=0;i10;i+)scanf(%d,a+i);/*正确,a+i表示ai的地址,即/*正确*/,37,main()int i,fib2
13、0=1,1,*pf;for(pf=fib+2;pffib+20;pf+)*pf=*(pf-1)+*(pf-2);for(pf=fib,i=0;pffib+20;pf+,i+)if(i%5=0)printf(n);printf(%12d,*pf);,fib,pf,运行,利用数组计算斐波拉齐数列,38,用数组名作函数参数,用数组名也可作函数的实参或形参,可将一个数组的首地址传递到另一个函数中。从而在函数中,通过该地址对作用域不在本函数的数组进行操作。这是因为,实参数组和形参数组共占同一段内存单元。如:main()void f(int arr,int n)int array10;arr0=0;f(a
14、rray,10);array为实参数组名,arr为形参数组名。,39,array,array,arr,函数调用时,数组array的首地址传递给形参数组arr(变量),在被调用函数中借助arr可以操作数组array,所谓形参数组arr实际和数组array是同一内存位置。,40,形参数组,实参数组名代表该数组首地址。而形参是用来接收从实参传递过来的数组首地址的。因此,形参应该是一个指针变量(只有指针变量才能存放地址)。实际上,C编译都是将形参数组作为指针变量来处理的。如:void fun(int a 10);等价于:void fun(int*a);因此形参数组的长度在定义时可以省略。float f
15、un(char str);等价于:float fun(char*str);常用这种方法通过调用一个函数来改变实参数组的值。,41,需要说明的是:C语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组起始地址,因此传递的值是数组首地址,所以要求形参为指针变量。,42,数组名作参数的几种情况,43,例将数组a中n个整数按相反顺序存放。void inv(int x,int n)/*形参x是数组名*/int temp,i,j,m=(n-1)/2;for(i=0;i=m;i+)j=n-1-i;temp=xi;xi=
16、xj;xj=temp;return;main()int i,a10=3,7,9,11,0,6,7,5,4,2;printf(The original array:n);for(i=0;i10;i+)printf(%d,ai);printf(n);inv(a,10);printf(The array has been inverted:n);for(i=0;i10;i+)printf(%d,ai);printf(n);,运行,44,最后数组a的内容,45,二维数组指针表示*,和一维数组一样,二维数组名也表示数组的首地址。二维数组名表示二级指针。对于二维数组,可以理解为由一维数组作数组元素组成的一
17、维数组。,46,如:int a34;,a,“一维数组”a有3个元素,每个元素又是由有4个元素的一维数组组成,47,a,a+0 表示&a0*a 表示 a0a+1 表示&a1*(a+1)表示 a1a+2 表示&a2*(a+2)表示 a2,二级指针指向行,一级指针指向元素列,a+1,a+2,a0+0 表示&a00*a0或*a 表示 a00a0+1 表示&a01*(a0+1)或*(*(a)+1)表示 a01a1+2 表示&a12*(a1+2)或*(*(a+1)+2)表示a12a2+3 表示&a23*(a2+3)或*(*(a+2)+3)表示a23,一级指针指向元素列,数组元素,48,a,a+1,a+2,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 课件

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