C语言第十章指针的课件.ppt
《C语言第十章指针的课件.ppt》由会员分享,可在线阅读,更多相关《C语言第十章指针的课件.ppt(128页珍藏版)》请在三一办公上搜索。
1、第十章,指针,10.1地址和指针的概念10.2变量的指针和指向变量的指针变量10.3数组与指针10.4字符串与指针10.5指向函数的指针10.6返回指针值的函数10.7指针数组和指向指针的指针10.8有关指针的数据类型和指针运算的小结,10.1地址和指针的概念,为了说清楚什么是指针,必须弄清楚数据在内存中是如何存储的,又是如何读取的。,内存区的每一个字节有一个编号,这就是“地址”。如果在程序中定义了一个变量,系统就会给这个变量分配内存单元。,、按变量地址(即变量名)存取变量值的方式称为“直接访问”方式。,2、另一种存取变量值的方式称为“间接访问”的方式。将变量的地址放在另一个内存单元中,先到另
2、一个内存单元中取得变量的地址,再由变量的地址找到变量并进行数据存取。,在语言中,指针是一种特殊的变量,它是存放地址的。假设我们定义了一个指针变量i_pointer用来存放整型变量的地址,它被分配地址为(3010)、(3011)的两个字节。可以通过语句:i_pointer;将的地址(2000)存放到i_pointer中。这时,i_pointer的值就是(2000),即变量所占用单元的起始地址。要存取变量的值,可以采用间接方式:先找到存放“的地址”的变量i_pointer,从中取出的地址(2000),然后到2000、2001字节取出的值()。,一个变量的地址称为该变量的“指针”。例如,地址2000
3、是变量的指针。如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量”。上述的i_pointer就是一个指针变量。,指针和指针变量的定义:,指针变量的值(即指针变量中存放的值)是地址(即指针)。请区分“指针”和“指针变量”这两个概念。,10.2 变量的指针和指向变量的指针变量,变量的指针:就是变量的地址。指针变量:存放变量地址的变量,用来指向另一个变量。为了表示指针变量和它所指向的变量之间的联系,在程序中用“*”符号表示“指向”。例如:,i-pointer 代表指针变量*i-pointer是i-pointer所指向的变量,见下图。可以看到,*i-pointer也代表一个变量,它
4、和变量i是同一回事。下面两个语句作用相同:i=3;*i-pointer=3;,例如:int i,j;int*pointer_1,*pointer_2;可以用赋值语句使一个指针变量得到另一个变量的地址,从而使它指向一个该变量。如:pointer_;pointer_;,10.1 定义一个指针变量,定义指针变量的一般形式为:基类型*指针变量名;,在定义指针变量时要注意两点:,10.指针变量的引用,请牢记,指针变量中只能存放地址(指针),不要将一个整数(或任何其他非地址类型的数据)赋给一个指针变量。下面的赋值是非法的:pointer-1=100;(pointer-1为指针变量,100为整数),两个相关
5、的运算符:(1)&:取地址运算符。(2)*:指针运算符。例如:&a为变量a的地址,*p为指针变量p所指向的存储单元的内容(即p所指向的变量的值)。,例10.通过指针变量访问整型变量,#include voidmain()int,;int*pointer_,*pointer_;pointer_1=a;/*把变量的地址赋给pointer_1*/pointer_2=b;/*把变量的地址赋给pointer_2*/printf(%,%,);printf(%,%,*pointer_1,*pointer_2);,对“”和“*”运算符说明:如果已执行了语句 pointer_;(1)*pointer_的含义是什
6、么?,(2)*的含义是什么?,(3)(*pointer_)相当于什么?,相当于a,即变量a的地址。,相当于a。,相当于。,例10.2 输入和两个整数,按先大后小的顺序输出 和。,#include void main()int*1,*2,*,;scanf(,);1;2;if();printf(=,=,);printf(max=,min=,*1,*2);,运行情况如下:,,交换前 交换后,10.2.3 指针变量作为函数参数,例10.3 对输入的两个整数按大小顺序输出,#include void main()void swap(int*,int*);int,;int*pointer_,*pointe
7、r_;scanf(,);pointer_;pointer_2;if()swap(pointer_,pointer_2);printf(,);,void swap(int*,int*)int temp;temp*1;*1*2;*2temp;,运行情况如下:5,99,5,void swap(int*,int*)int temp;temp*1;*1*2;*2temp;,int*temp;*temp*1;*1*2;*2*temp;,void swap(int*,int*)int temp;temp*1;*1*2;*2temp;,int*p;pp1;p1p2;p2p;,调用函数不可能改变实参指针变量的值
8、,但可以改变实参指针变量所指变量的值。,例10.输入、3个整数,按大小顺序输出,#include void main()void exchange(int*1,int*2,int*3);int,*,*,*;scanf(%,%,%,&,&,&);exchange(,);printf(,);,void exchange(int*,int*,int*)void swap(int*,int*);if(*)swap(,);if(*)swap(,);if(*)swap(,);void swap(int*pt1,int*pt2)int temp;temp*pt1;*pt1*pt2;*pt2temp;,10.
9、3 数组与指针,指针变量可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。,定义一个指向数组元素的指针变量的方法,与以前介绍的指向变量的指针变量相同。例如:int 10;int*;,10.3.1 指向数组元素的指针,对该指针变量赋值:;把元素的地址赋给指针变量。也就是使指向数组的第号元素,如图:,p=,10.通过指针引用数组元素,C规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素(而不是将p值简单地加1)。p+1所代表的地址实际上是p+1d,d是一个数组元素所占的字节数(对整型,d=2;对实型,d=4
10、;对字符型,d=1)。,图10.13,如果p的初值为&a0,则:(1)p+i和a+i就是ai的地址,指向a数组的第i个元素,见图10.13。a代表数组首地址,a+i也是地址,它的计算方法同p+i,即它的实际地址为a+id。例如,p+9和a+9的值是&a9,指向a9。(2)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即ai。实际上,在编译时,对数组元素ai就是处理成*(a+i),即按数组首地址加上相对位移量得到要找的元素的地址,然后找出该单元中的内容。,(3)指向数组的指针变量也可以带下标,如pi与*(p+i)等价。引用一个数组元素,可以用:()下标法,如形式;()指针法,如*(
11、)或*()。其中是数组名,是指向数组元素的指针变量,其初值。,例10.5 输出数组中的全部元素,假设有一个数组,整型,有个元素。要输出各元素的值有三种方法:,(1)下标法#include void main()int;int;for(;)scanf(,);printf();for(;)printf(,);,(2)通过数组名计算数组元素地址,找出元素的值。#include voidmain()int;int;for(;)scanf(,);printf();for(;)printf(,*();,(3)用指针变量指向数组元素。#include void main()int;int*,;for(;)s
12、canf(,);printf();for(;();)printf(,*);,注意:(1)可以改变指针变量的值。例如,上述第(3)种方法是用指针变量p来指向元素,用p+使p的值不断改变,这是合法的。如果不用p而使a变化(例如,用a+)for(p=a;a(p+10);a+)printf(%d,*a);是不行的。因为a是数组名,它是数组首地址,它的值在程序运行期间是固定不变的,是常量。a+是无法实现的。(2)要注意指针变量的当前值。请看下面的程序。,例10.通过指针变量输出数组的个元素。,#include void main()int*,;for(;)scanf(,);printf();for(;,
13、)printf(,*);printf();,我们先看一下运行情况:1 2 3 4 5 6 7 8 9 022153 234 0 0 30036 25202 11631 8259 8237 28483显然输出的数值并不是数组中各元素的值,解决这个问题的办法,只要在第二个循环之前加一个赋值语句:;,#include void main()int*,;for(;)scanf(,);printf();p=a;for(;,)printf(,*);printf();,(3)指针变量的运算。先使p指向数组a(即p=a),则:p+(或p+=1),使p指向下一元素a1。*p+:等价于*(p+)。先得到p指向的变
14、量的值(即*p,即a0),再使p+1=p。*(p+):先取*p,即a0,再使p+1=p。*(+p):先使p+1=p,再取*p,即a1。(*p)+:表示p所指向的元素值加1,即(a0)+。,10.3.3 用数组名作函数参数,在第8章8.7节中介绍过可以用数组名作函数的参数如:void main()void f(int arr,int n);int array 10;f(array,10);,void(int arr,int n),void f(int arr,int n)在编译时是将arr按指针变量处理的,相当于将函数f的首部写成void f(int*arr,int n)因此,arri和*(ar
15、r+i)等价。,实参数组名代表该数组首元素的地址,而形参是用来接收从实参传递过来的数组首元素地址的。因此,形参应该是一个指针变量。实际上,C编译都是将形参数组名作为指针变量来处理的。,例10 将数组中个整数按相反顺序存放,#include void main()void inv(int,int);int,10,;printf(The original array:);for(;)printf(,);printf();inv(,);printf(The array has been in verted:);for(;)printf(,);printf();,void inv(int,int)/*
16、形参x是数组名*/int temp,();for(;);temp;temp;return;,运行情况如下:The original array:,The array has been inverted:,,#include void main()void inv(int*,int);int,;printf(The original array:);for(;)printf(,);printf();inv(,);printf(The array has been in verted:);for(;)printf(,);printf();,对这个程序可以作一些改动。将函数inv中的形参改成指针变量
17、。,void inv(int*,int)/*形参x为指针变量*/int*,temp,*,*,()/;for(;,)temp*;*;*temp;return;,归纳起来,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参的对应关系有以下种情况:,(1)形参和实参都用数组名,如:void main()void(int,int)int;(,);,(2)实参用数组名,形参用指针变量。如:void()void(int*,int)int;(,);,(3)实参形参都用指针变量。例如:void main()void(int*,int)int,*p=a;(p,);,(4)实参为指针变量,形参为数组
18、名。如:void main()void(int x,int),*p=a;(p,);,#include void main()void inv(int*,int);int,*;printf(The original array:n);for(;,)scanf(,);printf();inv(,);/*实参为指针变量*/printf(The array has been inverted:);for(;)printf(,*);printf();,例10.8 用实参指针变量改写例10.7,void inv(int*,int)int,temp,*,*;();for(;,)temp*;*;*temp;r
19、eturn;,例109 用选择法对个整数按由大到小顺序排序,#include void main()void sort(int,int);int*,10;for(;)scanf(,);sort(,);for(,;)printf(,*);,void sort(int,int)int,;for(;);for(;)();(!);,10.3.4 多维数组与指针1.多维数组元素的地址 设 int a34=1,3,5,7,9,11,13,5,17,19,21,23;可理解为a数组包含3个元素a0,a1,a2,每一个元素又是一个包含4个元素的一维数组,如图所示,a00 a01 a02 a03,a10 a11
20、 a12 a13,a20 a21 a22 a23,二维数组名 a 是代表a的首行(即第0行)的首地址,为2000 故 a+1:代表第1行首地址 2008=2000+8 a+2:代表第2行首地址 2016=2008+8一维数组名a0表示a0的首元素(第0列)的地址,即&a00 为2000一维数组名a1表示a1的首元素(第0列)的地址,即&a10 为2008一维数组名a2表示a2的首元素(第0列)的地址,即&a20 为2016 故 a0+1:第0行第1列的地址,即&a01 为2002 a1+1:第1行第1列的地址,即&a11 为2010 a2+1:第2行第1列的地址,即&a21 为2018 如下图
21、所示。,所以,第i行第j列的元素的地址可表示为:a i+j 第i行第j列的元素可表示为:*(a i+j)a i*(a+i)a i+j*(a+i)+j&a i j*(a i+j)*(*(a+i)+j)a i j,a与a0的区别:a:二维数组名,指向行 a0;a0:一维数组名,指向列元素 a00。故 a+1 a0+1在行指针前加一个*,就转换为列指针*a:指向第0行0列的指针在列指针前面加&,就成为行指针&a0:指向第0行的指针,表示形式,含义,地址,二维数组名,第0行首地址 2000,第0行0列元素a00的地址 2000,第1行首地址 2008,第1行0列元素a10的地址 2008,第1行2列元
22、素a12的地址 2012,第1行2列元素a12的值 值为13,a,a0,*(a+0),*a,a+1,&a1,a1,*(a+1),a1+2,*(a+1)+2,&a12,*(a1+2),*(*(a+1)+2),a12,int a34;,例10.0 输出二维数组有关的值,#include define FROMAT,void main()int 341,3,5,7,9,;printf(,*);printf(,0,*();printf(,0,00);printf(,1,);printf(,10,*(+)+);printf(,*();printf(,);printf(,*(*();,2.指向多维数组元素
23、的指针变量,在了解上面的概念后,可以用指针变量指向多维数组的元素。(1)指向数组元素的指针变量,例10.11 用指针变量输出二维数组元素的值,#include void main()int a341,3,5,7,9,11,13,15,17,19,21,23;int*p;for(p=a0;pa0+12;p+)if(p-a0)%4=0)printf(”n”);printf(“%4d”,*p);printf(“n”);,运行结果如下:1 3 5 7 9 11 13 1517 19 21 23,定位某个指定的数组元素:数组起始地址相对位置。aij在数组anm(n行m列)中的相对位置的计算:i*m+j/
24、*之前有i行,每行有m个;之前还有j个*/故aij的值可表示为*(p+i*m+j),开始时p=&a00例如,数组a34中的元素a23的值可表示为:*(p+2*4+3)即*(p+11)如下图所示,(2)指向由个元素组成的一维数组的指针变量,例10.13 输出二维数组任一行任一列元素的值,#include void main()int a34=1,3,5,7,9,11,13,15,17,19,21,23;int(*p)4,i,j;p=a;scanf(,);printf(,*(*();,运行情况如下:,(本行为键盘输入),,对 int(*p)4;的理解:int a4;/a为数组名,有4个整型元素 i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 第十 指针 课件

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