九章指针ppt课件.ppt
《九章指针ppt课件.ppt》由会员分享,可在线阅读,更多相关《九章指针ppt课件.ppt(111页珍藏版)》请在三一办公上搜索。
1、第九章 指 针,本章要点:了解地址与指针的概念熟练掌握指针变量的定义、初始化及指针的运算 掌握指针与数组、指针数组、二级指针等知识 熟练掌握字符串的指针与指向字符串的指针变量了解指针与函数的概念 掌握指针作为函数参数的应用了解多维数组指针的概念,指针是C语言中最重要的组成部分。利用指针可以表示 复杂的数据结构;动态分配内存;灵活处理字符串和数组;直接处理内存地址;从函数调用中获取多个值等。,对变量值的存取实质上是通过地址进行的。,示意图,9.1 指针的概念,C 语言中,任何一个变量名实质上都代表着内存中的某一个存储单元,每一个存储单元都有一个地址。C系统能自动将变量名和它的地址联系起来。,变量
2、定义及内存分配实例,对变量的两种访问方式:直接访问 和 间接访问,int i,j,k;i=3;j=6;k=9;则编译时系统分别为 i,j,k 各分配 2 个字节。如:2000,2001 i 2002,2003 j 2004,2005 k,例,图,如:int i=3;printf(“%d”,i);执行是:根据变量名 i 找到 i 的地址(如:2000),然后 从地址 2000 开始的两个字节中取出数据(即变量的值 3),再将其输出。这种据变量名按变量地址存取变量的值的 方式叫“直接访问”方式。,说明,重点,重点,指针:一个变量的地址叫该变量的“指针”。指针变量:用于存放其它变量的地址的变量。指向
3、:如 i_pointer=&i,就称i_pointer指向变量i 目标变量:指针变量所指向的变量。,有关指针的几个概念:,说明:1.类型说明符表示指针变量所指向的变量的类型,同类型变量的地址才能放到指向该类型变量的指针变量中。例如2.不能把一个整型量或任何其它非地址类型的数据赋给一个指针变量。例如,示例一 实例二,9.2 变量的指针和指向变量的指针变量一、指针变量的定义,格式:类型说明符*标识符,如:int*pointer_1,*pointer_2;float*fp1,*fp2;,例,例,flaot f1;int*p;p=(不正确),例,如:int*p;p=100;(不合法)但:p=NULL
4、或 p=0 或 p=0 则是合法 的,都表示为指针赋了“空值”。这并不意味着 p 指向 地址为0 的单元,而是不指向任何单元,但 p 中有确定的值。,例,二、指针变量的引用 例 9.1 main()int a,b;int*p1,*p2;a=100;b=10;p1=结果:100,10 100,10,“直接访问”方式,“间接访问”方式,关于&与*运算符的说明:1:&是取地址运算符。例如 2.&,*,+,同优先级,按从右至左方向结合。,示例1 示例2 示例3,如:int a,*p1,*p2;p1=则:p2 也指向变量 a,例子,如:&a,&b 等。*是指针运算符。用于定义时表示其后的标识符是指针变量
5、。而在程序中*p 则表示指针变量 p 所指向的变量,即目标变量。,例子,例子,如:int a,*p1;p1=则:(*p1)+等价于 a+但注意*p1+不等价于(*p1)+因为*p1+等价于*(p1+)即先得 p1 所指向变量的值,再使指针变量 p1的值自增。,例子,例 9.2 main()int*p1,*p2,*p,a,b;scanf(“%d,%d”,如输入:5,9 输出:a=5,b=9 max=9,min=5 数据指针交换示意图 注意事项,进行地址交换,本程序是采用交换变量 a 和 b 的地址来实现两个数的比较的。且比较前后 a,b 的值并未发生变化,重点,重点,三、指针变量作为函数的参数
6、函数调用时,把实际参数的值传递给形式参数。指针变量可以作实际参数,其作用也是将实际参数的值传递给形式参数,这个时候的值代表是将一个变量的地址,把地址传送给被调函数的形式参数。,例 9.3 swap(int*p1,int*p2)int p;p=*p1;*p1=*p2;*p2=p;main()int a,b,*pointer_1,*pointer_2;scanf(“%d,%d”,交换目标变量,即值的交换,若输入:5,9 输出为:9,5,&a,&b,5,9,a,b,pointer_1,pointer_2,&a,&b,&a,&b,5,9,a,b,p1,p2,pointer_1,pointer_2,&a
7、,&a,&b,&b,9,5,p1,pointer_1,p2,pointer_2,a,b,&a,&b,9,5,a,b,pointer_1,pointer_2,(a),(b),(c),(d),本程序采用的是交换 a 和 b 的值,而 p1和 p2 的值不变。同例9.2相反.,如果把 swap 函数改成:swap(int*p1,int*p2)int*p;*p=*p1;*p1=*p2;*p2=*p;,此句有问题,swap(int x,int y)int t;t=x;x=y;y=t;,5,5,9,9,5,9,9,5,a,b,x,y,a,b,x,y,(a),(b),main()int a,b;scanf(
8、“%d,%d”,说明:1.如想通过函数调用得到 n 个要改变的值。(1)在主调函数中设 n 个变量,并用 n 个指针变量 指向它们。(2)将指针变量作实参,使 n 个变量的地址传给所 调用的函数形参。(3)通过形参指针变量,改变该 n 个变量的值。(4)主调函数中就可以使用这些改变了值的变量。2.不能通过改变形参指针变量本身的值而使实参指 针变量的值改变。,&a,p1,&a,q1,函数调用时,&b,q1,在被调函数中,3.可以通过改变形参指针变量所指向的变量的值来改 变实参指针变量所指向的变量的值。,5,a,&a,p1,&a,q1,补例1:void point(int*q1)q1+=2;mai
9、n()int*p1,a=4;p1=,4,a,&a,p1,&a,q1,补例2:void point(int*q1)*q1+=2;main()int*p1,a=4;p1=,swap(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;main()int a,b,*pointer_1,*pointer_2;scanf(“%d,%d”,本函数中试图通过改变形参指针变量的值来使实参指针变量的值改变,(a),exchange(int*q1,int*q2,int*q3)if(*q1*q2)swap(q1,q2);if(*q1*q3)swap(q1,q3);if(*q2*q3)swap(q
10、2,q3);,例 9.4 swap(int*pt1,int*pt2)int p;p=*pt1;*pt1=*pt2;*pt2=p;,main()int a,b,c,*p1,*p2,*p3;scanf(“%d,%d,%d”,运行如下:9,0,10 10,9,0,9,0,10,p1,a,b,c,p2,p3,9,0,10,q1,b,c,q2,q3,a,exchange,9,0,pt1,b,pt2,a,swap,p1,q1,p1,9.3 数组的指针和指向数组的指针变量 C 语言中,指针变量可以指向变量,也可以指向数组和数组元素。,数组的指针:数组的起始地址(首地址)数组元素的指针:数组元素的地址,一、指
11、向一维数组的指针变量的定义与赋值 指向数组的指针变量的定义同指向变量的指针变量的 定义相同。如:int a10;int*p;若:p=的含义是将数组的首地址赋给指针变量 p,而不是赋给(*p)。,二、通过指针引用数组元素 如:int a10,*p;p=a;则:(1)p a0的地址 p+1 a1的地址 p+i ai的地址(2)*p=a0,*(p+1)=a1,*(p+i)=ai说明:1.数组元素在内存中是连续存放的,C 语言规定,指针变量 p+1 指向下一个元素(不是简单的加 1)如数组元素为实型,则 p+1 所表示的实际地址是 p+1 d=p+1 4(d 为一个数组元素所占的字节数),2.(p+i
12、)表示指向 ai 的地址,而 a+i 也表示 ai 的地址,故 程序中(p+i)等价于 a+i。如:p+2;a+2;3.指向数组的指针变量可以带下标。如:pi*(p+i)综上所述:数组元素的引用可以:(1)下标法:数组名下标 或 指针变量名下标(2)指针法:*(p+i)或*(a+i)(假定:int a10,*p=a;),例 9.5 用三种方法输出数组各元素。(1)下标法 main()int a10,i;for(i=0;i 10;i+)scanf(“%d”,(2)用数组名计算元素地址 main()int a10,i;for(i=0;i 10;i+)scanf(“%d”,(3)用指针变量指向数组元
13、素 main()int a10,i,*p;for(i=0;i 10;i+)scanf(“%d”,注意几点:(1)指针变量可以作自增,自减运算。如:+p,p 而数组名不能作自增,自减运算。如:a+,a 等均不合法。因为数组名是常量。(2)注意指针变量的当前值。如:例 9.6,main()int a10,i,*p;p=a;for(i=0;i 10;i+)scanf(“%d”,p+);printf(“n”);for(i=0;i 10;i+,p+)printf(“%d”,*p);,(3)注意指针变量的运算 如:int a10,i,*p;p=a;则:a.p+(或 p+=1)表示 p 指向 a1,此时若执
14、行*p 则取出 a1 元素的值。b.“*”与“+”同优先级,自右往左结合。如:*p+等效于*(p+),即先取 p 所指向变量的值,再使 p+1。而*(p+)与*(+p)的作用不同。前 者先取*p 的值,后使p+1;后者是先使 p+1,再 取*p 的值。c.(*p)+表示使目标变量的值加 1。而不是指针变 量的值加 1d.*(p+)等价于 ai+*(+p)等价于 a+i 即先使 p 自增,再作*运算。,如:main()int a100,*p;p=a;while(p a+100)printf(“%d”,*p+);,main()int a100,*p;p=a;while(p a+100)printf
15、(“%d”,*p);p+;,三、数组名作函数参数 数组名作函数参数时,实际上是将实参数组的首地址 传给形参。这样实参数组与形参数组共占同一段内存。使得在调用函数过程中,形参数组中元素值发生变化也 就使实参数组的元素值随之而发生变化。,main()f(int arr,int n)int array10;f(array,10);,void inv(int x,int n)int t,i,j,m=(n 1)/2;for(i=0;i=m;i+)j=n 1 i;t=xi;xi=xj;xj=t;return;,可去掉,例 9.7 将数组 a 中 n 个整数按相反顺序存放。即将第一个元素和最后一个元素对换,
16、将第二个同倒 数第二个对换.即两两对换,直到:a(n 1)/2 与 a n(n 1)/2 1 对换为止。,void main()static int i,a10=3,7,9,11,0,6,7,5,4,2;printf(“The original array:n”);for(i=0;i 10;i+)printf(“%d,”,ai);printf(“n”);inv(a,10);printf(“The array has been inverted:n”);for(i=0;i 10;i+)printf(“%d,”,ai);printf(“n”);,运行结果:The original array:3,
17、7,9,11,0,6,7,5,4,2 The array has been inverted:2,4,5,7,6,0,11,9,7,3,以上程序也可以改为如下:void inv(int*x,int n)int*p,t,*i,*j,m=(n 1)/2;i=x;j=x+n 1;p=x+m;for(;i=p;i+,j)t=*i;*i=*j;*j=t;return;,main()static int i,a10=3,7,9,11,0,6,7,5,4,2;printf(“The original array:n”);for(i=0;i 10;i+)printf(“%d”,ai);printf(“n”);
18、inv(a,10);printf(“The array has been inverted:n”);for(i=0;i 10;i+)printf(“%d”,ai);printf(“n”);,int max,min;void max_min_value(int array,int n)int*p,*array_end;array_end=array+n;max=min=*array;for(p=array+1;p max)max=*p;else if(*p min)min=*p;return;,等价于*(array+0)即 array0,例 9.8 从 10 个数中找出其中最大值和最小值,voi
19、d main()int i,number10;printf(“enter 10 data n”);for(i=0;i 10;i+)scanf(“%d”,运行结果:enter 10 data 2 4 6 8 0 3 45 67 89 100 max=100,min=3,此例也可改用指针变量来传送地址,程序可改为:int max,min;void max_min_value(int*array,int n)int*p,*array_end;array_end=array+n;max=min=*array;for(p=array+1;p max)max=*p;else if(*p min)min=*
20、p;return;,void main()int i,number10,*p;p=number;printf(“enter 10 data n”);for(i=0;i 10;i+,p+)scanf(“%d”,p);printf(“the 10 data:n”);for(p=number,i=0;i 10;i+,p+)printf(“%d”,*p);p=number;max_min_value(p,10);printf(“n max=%d,min=%d n”,max,min);,for(p=number;p(number+10);p+),综上所述,对于实参数组想在被调函数中改变此数组元素的值,实
21、参与形参的对应关系可以如下:,(1)二者都用数组名 main()f(int x,int n)int a10;f(a,10);特点:a 和 x 数组共用同一段内存单元。(2)实参为数组名,形参用指针变量 main()f(int*x,int n)int a10;f(a,10);,(2)实参为数组名,形参用指针变量 main()f(int*x,int n)int a10;f(a,10);特点:实参将数组的首地址传给形参指针变量,通过指 针变量指向数组中的任一元素,进而作相应的处理。,(3)二者都用指针变量 main()f(int*x,int n)int a10,*p;p=a;f(p,10);特点:先
22、使 p 指向 a 数组,再将 p 传给 x,使 x 也指向 a 数组,从而进行处理。,(4)实参为指针变量,而形参为数组名 main()f(int x,int n)int a10,*p;p=a;f(p,10);特点:利用指针变量将 a 数组的首地址传给 x 数组。使 两数组共用同一段内存单元。利用xi值的变化,使ai的值也发生变化。注意:在上述四种处理方式中,当用指针变量作实参时,必须先使指针变量有确定的值,即指向一个已定 义的数组。,四、二维数组的指针和指向二维数组的指针变量 1.二维数组和数组元素的地址 C 语言中二维数组实际上是由若干个按行存放的一维数组构成的。如:int a34;a0
23、a00 a01 a02 a03 a1 a10 a11 a12 a13 a2 a20 a21 a22 a23 a 代表首元素的地址,而此时首元素a0又是一个包含有 4个元素的一维数组。所以 a(或 a+0)表示二维数组第0 行的地址。同理:a+1,a+2 分别表示二维数组第 1 行和第 2 行的地址。所以,二维数组名是一个行指针。a0,a1,a2分别表示一维数组名,所以a0代表 一维数组a0中第0列元素的地址,即&a00。,a,同理:a1的值为,如:p=a0;或 p=因为尽管 a0 和 a 都表示地址且 值相同,但二者的地址基类型不同。即 a0 是一个列地址,而 a 是一个 行地址。,#incl
24、ude“stdio.h”void main()int a34=1,2,3,4,9,8,7,6,10,11,5,2;int*p=a0;(或 int*p=(2)指向二维数组的行指针变量 由于二维数组是由按行存放的一维数组构成,C 语 言中可以用行指针变量来引用二维数组元素。,定义格式:数据类型(*标示符)常量 如:int(*p)4;表示 p 所指的对象是有 4 个整型元素的数组。int a34,(*p)4;若:p=a;则 p 是指向 a 数组第 0 行的指针变量,即 p 是一个行指针变量。此时,p+1则指向 a 数组第 1 行,p+i 则指向 a 数组第 i 行。所以,*(p+i)+j 表示 a
25、数组 中第 i 行 j 列元素的地址。而*(*(p+i)+j)则表示表示 a 数组中第 i 行 j 列元素的值。注意不能写成 p=a0。,1 3 5 7,2 4 6 8,11 12 13 14,p,p+1,例:输出二维数组任意行任意例元素的值。void main()int a34=1,2,3,4,9,8,7,6,10,11,5,2;int(*p)4,i,j;p=a;scnaf(“i=%d,j=%d”,3.二维数组名和指向二维数组的指针变量作函数参数 补充例:用函数调用方式编写程序找出二维数组a 中每 行的最小值并输出。要求:(1)二维数组元素的值用随机函数产生(0 50)之间(2)每行中元素的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 指针 ppt 课件
链接地址:https://www.31ppt.com/p-5310551.html