南邮吴江职业技术学院.ppt_第1页
南邮吴江职业技术学院.ppt_第2页
南邮吴江职业技术学院.ppt_第3页
南邮吴江职业技术学院.ppt_第4页
南邮吴江职业技术学院.ppt_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1,第 十 章,指 针,2,一、指针在程序中的用途 二、地址和指针的概念 三、变量的指针和指针变量 四、数组与指针 五、字符串与指针 六、返回指针值的函数,主要内容:,3,一、指针在程序中的用途,有效的表示复杂的数据结构 能动态分配内存 方便的使用字符串 直接处理内存地址 总之,指针的应用,使程序简洁、紧凑、高效。,4,二、指针的概念,1.数据在内存中的存储、读取过程 例如:整型变量 i , j , k ; 在编译时为变量分配内存,内存示意图如图 1 所示.,(2) 给变量赋值为 i=3; j=6; k=9;,(1) 假设变量 i,j,k 被分配的 内存地址分别为2000,2002,2004,(3) 通常,在程序中通过变量名对变量 进行存取。,其实程序经过编译后已将变量名转换为变量的地址,对变量值的存取都是通过变量的地址进行的。,图1,5,(1) 直接访问方式 按变量地址存取变量值的方式。 如果读取变量 i的值,直接到为变量i分配的存储单元(2000、2001字节)中取出i的值(3)即可。,(2) 间接访问方式 先将变量 i 的地址存放在另一个变量p中,如果读取变量 i的值,先找到变量p,从p中取出内容(2000,即变量i的起始地址),然后到2000、2001字节中取出i的值(3)。 即通过变量p访问为变量i分配的内存单元。,访问变量的两种方式:,6,直接访问示意图,间接访问示意图,表示将数值3送到变量i中,可有两种表达方法: (1)将3送到变量i所标志的单元中。即直接访问方式 (2)将3送到变量p所指向的单元(变量i)中。 即间接访问方式,注意:我们并不关心变量p的存储地址, 对 变量p的访问属于直接访问。,7,三、 指针变量,1.变量的指针 变量的地址称为变量的指针。 2. 指针变量 存储变量地址的变量称为指针变量,用来指向另一个变量。 3. * 操作符 为了表示指针变量与它所指向的变量的之间的关系,在程序中用 * 符号表示“指向”。,例如,P代表指针变量,* P则表示P所指向的变量。,以下两个语句作用相同: i=3; *P=3;,8,三、 指针变量(续),4.指针变量的定义,int i , j ; int *pointer1, *pointer2;,定义形式: 基类型 *指针变量名;,举例,说明,(1)指针变量名前的*,表示该变量是指针型的变量。指针变量名为pointer1,而非 *pointer1。,(2)定义指针变量时必须指明基类型。,*注:以后几张幻灯片中提到的pointer1 pointer2是基于此例的。,9,如何使一个指针变量指向一个变量呢?,使用取地址运算符 ,赋值语句pointer1=&i;实现将变量i的地址保存入指针变量pointer1中。如右图所示。,你能画出第二个赋值语句的示意图吗?,三、 指针变量,5.指针运算符 &,10,三、 指针变量(续),6.指针变量的引用,与指针变量有关的两个运算符: & : 取地址运算符 * :间接访问运算符,(1)上例将打印出i的值。 (2)*pointer1 与普通的整型变量一样使用,但前提是pointer1 必须已经明确地指向了某整型变量,或者说指针变量中必须已经存有了某整型变量的起始地址。,例如,i=3; pointer1=,说明,11,三、 指针变量(续),例1: 输入两个整数,按先大后小输出这两个整数,#include void main() int *p1, *p2, *p, a, b; scanf(“%d%d“, ,你能画出程序中指针处理过程的示意图吗?,12,三、 指针变量(续),7.指针变量作为函数参数,函数的实参值是地址,函数的形参应定义为指针类型,此时,实参和形参之间仍然是传值方式。参见例2。,#include void swap(int *p1, int *p2) int temp; temp=*p1; *p1=*p2; *p2=temp; void main() int a,b,*pointer1, *pointer2; scanf(“%d%d“,/* 打印函数调用后,变量a,b的值,观察其变化*/ ,在被调函数中,通过间接访问, 改变了主调函数中实参变量的值。,变量a,b的地址被传递 到函数的形参变量p1,p2中,13,四、数组与指针,数组在内存中占一片连续的存储区,该存储区的大小与数组的元素类型和数组长度有关。 每个数组元素占用相同大小的存储空间。 利用数组存储区的起始地址,可以逐个获得每个数组元素的存储地址。,例如,定义数组 int a10;,1.数组的存储,a0 a1 a2 a3 a4 a5 a6 a7 a8 a9,注:假设数组a的存储区起始地址为2000。,2000,2002,2004,2006,2000+4*2,2000+9*2,由上图可知,数组元素ai的存储地址的计算公式为: 数组a的起始地址+i元素类型占内存的字节数,图2,14,C语言规定: 数组名代表数组的起始地址,该地址在程序运行过程中不能修改。 即数组名a是个常量。,2.指向数组元素的指针,四、数组与指针,例如, int a10; int *p;,对指针变量p赋值:p= 则使p指向了数组的第一个元素。,因此,下面对指针变量p赋值的两个语句等价: p=,因此定义指向数组的指针变量时,可以对其初始化: int a10; int *p=a; (或 int *p=&a0; ),15,四、数组与指针,例如,定义:int a10 ,*p=a; 可有如下操作: p=a; p=,3.通过指针变量引用数组元素,4.指针变量表达式和指针的算术运算符,(1) 可以对指针进行有限的算术运算,包括自增运算(+)、自减运算(-)、加上一个整数、减去一个整数,以及减去一个指针变量。,(2)指针运算的结果依赖于指针所指向的对象的大小。,指针的算术运算的规则是: 当一个指针加上或减去一个整数时,指针并非简单的加上或减去该整数值, 而是加上或减去该整数与指针指向的对象的大小的乘积。,例如:int a10 ,*p=a; 则 p=p+1; 使指针变量的值更新为数组元素a1的地址,即p指向了数组元素a1。,16,注意:a+是错误的,为什么呢?,例如:int a10 ,*p=a,*q,x; 假定数组a的起始地址为2000,则下列每个操作后变量的值分别为多少?,四、数组与指针,p=p+1;,q=p;,q+=2;,x=q-p;,p+;,+p;,-p;,p的值为2002,p指向数组元素a1.,q的值为2002, q指向数组元素a1.,q的值为2006, q指向数组元素a3.,x 的值为2,p的值为2004, p指向数组元素a2.,p的值为2006 , p指向数组元素a3.,p的值为2004, p指向数组元素a2.,p-;,p的值为2002, p指向数组元素a1.,通过 - 运算, 让指针变量指向数组中 的上一个元素。,得到: 从p到q的数组元素的个数,通过+ 运算, 让指针变量指向数组中 的下一个元素。,指针的算术运算 除了用于数组外 没有什么意义,17,四、数组与指针,5.指针和数组的关系,C语言中数组与指针关系密切,它们几乎可以互换。数组名可认为是一个常量指针,指针可以完成涉及数组下标的操作。,例如:int a10 ,*p=a; 则,p指向数组的第一个元素,可用如下的指针表达式引用数组元素a3 *(p+3) 式中的 3 是对于指针变量p的偏移量。,当p指向数组的起始位置时,偏移量等于数组的下标。 *(p+3) 这种表示法称为“指针表示法” (或 *(a+3) ),因为*的优先级高于+,所以圆括号是必需的。,注意,总结,至此,引用一个数组元素,可以采用如下两种方法之一: (1) 下标法: 如ai (2) 指针法:如 *(p+i) 或 *(a+i),18,四、数组与指针,例3:输出数组中的全部元素。(采用三种方法输出数组元素的值),#include void main() int a10 , i ; for(i=0; i10;i+) scanf(“%d“, ,#include void main() int a10 , i ; for(i=0; i10;i+) scanf(“%d“, ,#include void main() int a10 , i , *p; for(i=0; i10;i+) scanf(“%d“, ,1.下标法,2. 通过数组名计算数组元素的地址,找出元素的值,3. 用指针变量指向数组元素,(1)用下标法直观; (2)用前两种方法效率一样; C编译系统是将ai转换为 *(a+i)来处理的 (3)用第三种方法省时间, p+操作快。,19,四、数组与指针,6.用数组名作函数的参数,(1) 实参数组名代表该数组首元素的地址。而形参是用来接收 从实参传递过来的数组首元素的地址。因此,形参应该是一个指针变量(只有指针变量才能存放地址)。,(2) 虽然函数 f 的原型为 void f( int arr, int n) ,但编译时是将arr数组按指针变量来处理的。即: void f( int arr, int n) 与 void f( int *arr, int n) 等价,#include void main() int array10 ; . f(array,10); . ,void f( int arr, int n) . . ,首先回顾第八章“函数”中介绍的数组名作函数参数的情形:,规定:如果形参数组中 元素的值发生变化, 实参数组元素的值 随之变化。,说明,20,四、数组与指针,例4.将数组a中n个元素按相反的顺序存放。,#include void inv( int *x, int n) /* 形参为指针变量*/ int *p, temp,*i,*j, m=(n-1)/2; i=x; j=x+n-1; p=x+m; for(;i=p; i+,j-) temp=*i; *i=*j; *j=temp; return; void main() int i,a10=3,7,9,11,0,6,7,5,4,2; for(i=0;i10;i+) printf(“%d“,ai); inv(a , 10 ); /* 函数调用,实参为数组名*/ for(i=0;i10;i+) printf(“%d“,ai); ,a0 a1 a2 a3 a4 a5 a6 a7 a8 a9,a 数组,图3,21,四、数组与指针,例5.用选择法对10个整数按由小到大顺序排序。,#include void sort( int *x, int n) /* 形参为指针变量*/ int i,j,k,t; for(i=0;i*(x+k) k=j; if(k!=i) t=*(x+i);*(x+i)=*(x+k);*(x+k)=t; void main() int *p,i,a10; p=a; for(i=0;i10;i+,p+) scanf(“%d“,p); sort(p , 10 ); /* 函数调用,实参为指针变量*/ for(i=0, p=a;i10;i+,p+) printf(“%d“,*p); ,a0 a1 a2 a3 a4 a5 a6 a7 a8 a9,图4,a 数组,22,四、数组与指针,7.指针和多维数组,多维数组元素的地址,假设有数组定义: int a34;,C语言规定: (1) 二维数组的起始地址为a; (2) 此二维数组由三个行元素组成:a0,a1,a2; (3) 每个行元素又是一个一维数组,包含4个元素: a0 为第一行的起始地址;a0 可用*a表示。 a1 为第二行的起始地址;a1 可用*(a+1)表示。 a2 为第三行的起始地址;a2 可用*(a+2)表示。 (4) 第0行第0列的元素a00的地址为: a0 ,也可用 *a表示。 第0行第1列的元素a01的地址为: a0+1,也可用 *a+1表示。 第0行第2列的元素a02的地址为: a0+2,也可用 *a+2表示。 第0行第3列的元素a03的地址为: a0+3,也可用 *a+3表示。 (5) 第0行第0列的元素a00可表示为: *(a0),也可用 *(*a)表示。 第0行第1列的元素a01可表示为: *(a0+1),也可用 *(*a+1)表示。 第0行第2列的元素a02可表示为: *(a0+2),也可用 *(*a+2)表示。 第0行第3列的元素a03可表示为: *(a0+3),也可用 *(*a+3)表示。 (6) 第1行第3列的元素a13可表示为: *(a1+3),也可用 *(*(a+1)+3)表示。,把 a 看成一维数组时, 按照前面给出方法 表示一维数组的元素。,23,在C程序中,用两种方法访问字符串: (1)用字符数组存放一个字符串。 (2)用字符指针指向一个字符串。,1.字符串的表示形式,五、字符串与指针,#include void main() char string=“china!“ ; printf(“%sn“,string); ,#include void main() char *string=“china!“ ; printf(“%sn“,string); ,(1)用字符数组存放一个字符串。,(2)用字符指针指向一个字符串。,用字符串常量 初始化字符指针,用字符串常量 初始化字符数组,24,五、字符串与指针

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论