[IT认证]指针详细介绍.ppt
《[IT认证]指针详细介绍.ppt》由会员分享,可在线阅读,更多相关《[IT认证]指针详细介绍.ppt(132页珍藏版)》请在三一文库上搜索。
1、void main(void) float s10=90,95,88,70,65,86,74,80,92,84; float aver=ave(s,10); cout“aver=“avern; ,float ave(float a ,int n) int i; float sum=a0; for (i=1; in; i+) sum=sum+ai; return sum/10; ,float ave(float *a,int n) int i; float sum=a0; for (i=1; in; i+) sum=sum+ai; return sum/10; ,第7章 指针,本章导读,指针是C
2、+语言编程中最重要的概念之一,也是最容易产生困惑并导致程序出错的问题之一。,指针用于存储数据和程序的地址,这是指针的基本功能。,利用指针编程可以表示各种数据结构,进行各种奇妙有效的运算;,通过指针可使主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯;并能像汇编语言一样处理内存地址,从而编写出精练而高效的程序。,本章提要:,1变量地址的概念,2一级及多级指针的概念,3指针的定义与引用,4一维数组与指针的关系,5二维数组与指针的关系,6字符串和指针的关系,7特殊指针常指针,8指针作为函数的参数,9引用,10动态数据的申请和释放,字节地址的概念,系统根据程序中定义变量的类型,给变量分配
3、一定的长度空间。字符型占1个字节,整型数占4个字节.。内存区的每个字节都有编号,称之为地址。,内存单元的地址,内存单元的内容,7.2 指针,变量地址概念,设有说明语句: char ch=65; int i=8; float x=3.14;,变量的两种访问方式,1、直接访问,按变量名字存取变量的值。cini; 实际上是按地址将输入直接放到定义 i 单元中。,2、间接访问,将变量的地址存放在另一个单元p中,通过 p 取出变量的地址,再针对变量操作。,指针的概念,一个变量的地址称为该变量的指针。,如果在程序中定义了一个变量或数组,那么,这个变量或数组的地址(指针)也就确定为一个常量。,变量的指针和指
4、向变量的指针变量,变量的指针就是变量的地址,当变量定义后,其指针(地址)是一常量。,int i;,&i :2000H,可以定义一个变量专门用来存放另一变量的地址,这种变量称之为指针变量。在编译时同样分配一定字节的存储单元,未赋初值时,该存储单元内的值是随机的。,7.2.1 指针变量的定义,指针变量定义的一般形式为:,类型标识符 *变量名,int *i_point;,指针类型,变量名,指针变量同样也可以赋值:,int i; int *i_point=,2000H,i,2000H,运算符*和指针变量,一个指针变量只能指向同一类型的变量。即整型指针变量只能放整型数据的地址,而不能放其它类型数据的地址
5、。&运算符表示“地址”。,* 在定义语句中只表示变量的类型是指针,没有任何其它意义。int *p=&a,* 和指针变量结合表示“指向”,表示对指针变量指向的内存单元(变量)进行读/写操作。*p=3,*point=5;,表示指向,表示类型,5,int i;,int *point=,指针和指向,指针变量只能指向和其同类型的变量,不能指向其它类型的变量,也不能指向常量和表达式。C+允许将一个常量经强制类型转换后赋值给指针变量。 int *p= (int *)0x2000; /初始化指针变量p,使其值为0x2000 float *f= (float *)100; /初始化指针变量f,使其值为100,如
6、果在定义指针变量时没有初始化,其值是随机的、不确定的(静态存储类型、文件作用域类型的除外,=0)。 例:定义指针变量,使其指向另一个变量。 int i, *p; /指针p的值是随机的 p= /指针赋值,使其指向变量i,p指向不确定,不能用,例:通过指针变量,输入/输出数据。 #include void main(void) int a, b, *p1, *p2; p1=/通过指针输出 ,间接表示a,间接表示b,7.2.2 指针变量的引用,a,b,&a,&b,p1,p2,4,8,输出:4 8 4 8,直接输出变量,通过指针引用间接输出变量,例:指针必须指向某变量后才能正确引用。 void mai
7、n(void) int x, y, *p1, *p2; *p1=5; *p2=10; ,错误,p1和p2未指向任何变量,void main(void) int x, y, *p1, *p2; p1= ,正确,例:通过指针交换变量。输入a, b两个整数,按大小输出这两个数。 void main(void) int *p1, *p2, *p,a,b; cinab; /输入a、b p1= ,b,p1,p2,a,&a,&b,4,8,b,p1,a,&a,&b,4,p2,8,交换前,交换后,对于指针变量,系统也为其分配地址,同样可以定义一个变量来存放其地址。 int x,*p1,*p2; p1= 二级指针
8、变量的定义和赋初值方法如下: *=初值;,p2,p1,x,&p1,&x,可以缺省,7.2.3 多级指针,在+语言中,把这种指针型变量称为“指针的指针”,意为这种变量是指向指针变量的指针变量,也称多级指针。 通常使用的多级指针是二级指针,相对来说,前面介绍的指针变量可以称为“一级指针”。,int *ptr=,但是:pptr=,则: *ptr相当于i *ptr=5相当于i=5 *pptr也相当于i *pptr=8相当于i=8 *pptr相当于ptr *pptr=&i相当于ptr=&i,非法,基类型不符,设有:,7.3.1 指针与一维数组 一级指针与一维数组的关系十分密切。指向一维数组的指针变量,实
9、际上是指向一维数组元素的指针变量。可以利用指向一维数组的指针变量,完成对数组数据的操作处理。,int a5,*p,*p1; p=a; p1=&a0,p指向a,p1指向a0,int a10, *p; p= /正确,p指向a5,数组名为一常指针,不能赋值和修改,说明一个指针变量(注意类型要与数组元素 相同)并使之指向数组的某个元素,则可以使 用该指针变量来操作数组。 int a10,b10; int *ptra,*ptrb; ptra= 由于指针使用的灵活性,可以在一个数组 定义后再用指针对数组进行处理。 例:用指针访问数组.cpp,总结(对一维数组): 1)数组名等同于数组第0个元素的地址,也就
10、是数组的起始地址,相当于一个常指针。 2)指针指向数组的首地址后,其值+i后指向数组的第i个元素。 3)指针指向数组a的首地址后,可以用指针代替数组名使用,*(point+i)、*(a+i)、ai、pointi、*ai、*pointi等同,都是表示一维数组的第i个元素。 若point指向a2, *(point+i)表示什么?,指针变量的运算主要有三种:赋值运算、算术运算和关系运算。,1.赋值运算 int a, *pa; pa= 相同类型指针赋值,把变量a的地址赋予指针变量pb,7.3.2 指针的运算,同类型指针赋值的含义是什么?,char *ptr; ptr=“I love you!“; 把字
11、符串的首地址赋予指针变量 char *str; cin.getline(str); /错误 指针变量str未赋值,指向不确定,可以对指针变量赋0值。指针变量赋0值后称为空指针,空指针不指向任何地方。 int *p=0; /p不指向任何地方 或 int *p=NULL; /p不指向任何地方,NULL相当于0指针 #define NULL 0,2.指针的算术运算 int a5, *pa; pa=a; /pa指向数组a,也就是指向a0 pa=pa+2; /pa指向a2,即pa的值为&pa2 一般的,在指针指向一个数组后,指针加减一个整数的算术运算才有实际意义。指针变量加减一个整数n的含义是将指针指向
12、的位置向前或向后移动n个元素。指针偏移,一般的,当有了定义“int a10, *p=a; ”后,有: *(p+1)=2; /p+1为a1地址 *(a+1)=2; /a+1为a1地址 *+p=2; / +p为a1地址 p=p+1; *p=2; /p=p+1与+p等价 a1=2; /直接对数组元素赋值 p1=2; /指针名作数组名用 这些行是等价的,都是使a1为2。,int c=7,b=5,a=3,*p= /设&a=2000H,则有(*运算符是左结合的): (*p)+; /相当于a+。表达式为3,a=4,p不变 *p+; / *p+首先*p ,然后p=p+1,指针指向b, /表达式为3, p200
13、4H,a不变 +*p /相当于+(*p),就是*p=*p+1,即a=4 *+p /相当于*(+p),首先:p=p+1,然后取*p。 /即p先指向b,再取b的内容。表达式为5, /p2004H,(*p)+、+*p,*p+、*+p,4,a,注意进行算术运算的是指针本身还是指针指向的对象,两个指针变量之间只能做减法算术运算。只有指向同一数组的两个指针变量之间的减法才有意义。两指针相减所得之差是两个指针所指数组元素之间相差的元素个数。 指针变量之间的加法和乘除法没有意义 设有:int a10, *p1, *p2; p1= 则:p2-p1的值为3,就是p2、p1所指数组元素下标的差。,指向同一数组的两指
14、针变量进行关系运算可表示它们所指数组元素之间的关系。 设:int a10,*p1= 则:p2p1 值为真,因为p2的值大于 p1的值。即&a5&a0 p2=p1 值为假,因为p1和p2不是 指向同一个变量(值不同) p1!=0 值为真,因为p1指向了 a0,不是空指针。,3.指针的关系运算,例:使用指针处理数组 void main(void) int a10, i; int *p; for(i=0;iai; for(p=a;p=a+9; p+ ) cout*pt; ,p=a使p指向数组a;a+9为一常指针,指向数组a的最后一个元素,p=a+9表示指针p指向移动时,不能超出数组最后一个元素。,f
15、or(p=a;p=a+9; ) cout*pt;,p+,p,每次p+,p就指向a的下一个元素,4.指针参与混合运算及优先级(补充) (1) *和 /指针定义 &*p1: 先*运算再&运算 &a 即a的地址(p1的值) *&p1: 先&运算再*运算 *(p1的指针) 即变量p1值 *&a: 相当于*p1,即a *&放到一起互相抵消,(2) *和 /指针定义 p1=&a0,b=*p1+ /先取a0的值,赋值后,再使指针加1,b=100 /此后p1不指向a0,指向a1 p1=&a0, b=*+p1 /先+p1再*p1,左结合,b=200,p1指向a1, p1=&a0,b=(*p1)+ /相当于a0+
16、,此后p1仍指向a0 /b=100先赋值,a0=101,+优先级低 p1=&a0, b=*(p1+) /相当于*p1+,括号不起作用,比较特殊 /b=100, p1指向a1 p1=&a0, b=+*p1 /相当于+(*p1),左结合 /b=101,a0=101,p1指向a0 在涉及到与指针变量相关的操作时,特别 要注意操作对象是指针变量本身还是指针 变量所指的对象,以及指针变量变化后实 际所指的对象。,例:输入n(不大于20)个整型数存入一维数组,用指针变量处理数组元素的方式将其逆序存放后输出。n从键盘输入。 分析:用指针处理数组逆序,需要定义两个指针,具体的思路为: 首先设置两个指针变量,分
17、别指向数组的首地址(第0个元素,首指针)和数组的尾地址(最后一个元素,尾指针)。 然后用循环处理,每次交换首、尾指针指向的两个元素,再令首指针后移一个元素;尾指针前移一个元素,为下一次交换做好准备。,开始时,pb指向a0,pe指向a9。 在交换*pb和*pe后,pb+指向后一个元素,pe-指向前一个元素,再进行交换,反复进行,直到pb=pe。 过程如下图所示:,pb,pe,交换*pb、*pe,10,1,2,3,4,5,6,7,8,9,7.3.3 指针与二维数组,二维数组是“数组的数组”,即二维数组是由若干个一维数组所组成的。 二维数组有三种地址:数组地址、行地址和元素地址。 设有定义“int
18、a34;”,则三种地址为: 数组首地址:a 行地址:a+0、a+1、a+2 元素地址:a i 或a i +j或&a i j 等,int a34; /设数组a的首地址是2000H,a,数组首地址是2000H,三个行地址分别是2000H、2010H和2020H,各数组元素地址从2000H到202CH连续分布。 a0、a1、a2为组成二维数组a的3个一维数组名字(一维数组名是元素指针)。,下面分析二维数组名与其所分解成的多个一维数组名之间的关系。 a= 一维数组名是一个元素指针 二维数组名是一个行指针,ai :表示第i行第0列元素的地址 a+i :表示第i行地址(偏移i行) &ai:表示第i行地址,
19、&不表示取地址,用来区 分元素地址和行地址. *(a+i):表示第i行第0列元素的地址, *不表示 取内容,用来区分元素地址和行地址. 元素指针ai前加&转换成行指针 行指针(a+i)前加*转换成元素指针 元素指针算术运算是偏移多少元素 行指针算术运算是偏移多少行 结合指针偏移的概念理解 元素指针和行指针是不同的指针 *的4种作用:乘、指针定义、取内容、区分为元素地址(运算符&),a00=*a0=*(*a); ai0=*ai=*(*(a+i); aij=*(ai+j)=*(*(a+i)+j); &aij=ai+j=*(a+i)+j;,二维数组地址和元素的表示法,使用二维数组名、指向运算符和取地
20、址运算符,二维数组元素有着多种表示方法,例如(优先级()*): *(a+1)+2=&a12 *(*(a+1)+2)=a12 *(a+1)=*(a1)=*(&a10)=a10 (*(a+1)1 =(a1)1=b1=a11 /b=a1 *(a+1)1=*(a+1)1) =*(b1)=*(&b10)=b10 =a20 /b=a+1,行指针,例:指针访问二维数组.CPP,7.3.4 指针数组 由同类型指针所组成的数组称为指针数组。或者当某个数组被定义为指针类型,就称这样的数组为指针数组。指针数组的每个元素都是一个指针变量。 定义指针数组的一般格式为: *; 可以给指针数组赋初值,赋初值有多种方式,同普
21、通的数组。 定义指针变量时的“数据类型“可以选取任何基本数据类型,也可以是结构体类型、枚举类型或类类型。,设有:“int a,b,c,*p3= ”,,数组名,指针个数,初始化地址,定义一整型数组和指针数组,通过指针数组来输出整型数组。 void main(void) int a=10,20,30,40,50,60; int *p= ,输出结果:10 20 30 40 50 60,void main(void) a5=1,3,5,7,9, *pa5 , *p=pa, i; for(i=0;i5;i+) pai= ,p=p+1;指向pa数组下一个元素,1 3 5 7 9,p=&pai,例:指针数组
22、.cpp,7.3.5 指向二维数组的指针 二维数组名不能赋值给一级指针和二级指针 对于一个m列的二维数组anm,可以定义一个指向它的指针:“int (*p)m; ”。就可以赋值:“p=a; ”。这里的指针p称为“指向数组的指针”。 定义指向数组的指针的一般形式为: (*) 指向二维数组的指针可以用来代替二维数组名,使用指向二维数组的指针输出二维数组中的元素。 void main() int a34=0,1,2,3,4,5,6,7,8,9,10,11; int (*p)4, i, j; p=a; /指针p指向二维数组a(起始地址) for(i=0;i3;i+) /使用相对于a数组起始地址的偏移量
23、 for(j=0;j4;j+) /用指针+偏移量生成临时指针 cout*(*(p+i)+j)t; /使用行指针p+偏移量 cout*(pi+j)t; /使用列指针pi+偏移量 cout*(*(a+i)+j)t; /使用行指针a+偏移量 cout*(ai+j)n; /使用列指针ai+偏移量 ,7.4 指针与函数,在C+中,指针与函数的关系密切复杂。与数组名一样,函数名也是一个常指针。函数的参数可以是指针,函数的返回值也可以是指针。还可以定义指向函数的指针。 指针作函数参数,形参要求是指针变量,实参要求分为以下几种情况。 实参为数组名 实参为地址 实参为指针,一、实参用数组名,形参用指针变量,vo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- IT认证 IT 认证 指针 详细 介绍
链接地址:https://www.31doc.com/p-1995443.html