1、第10章 指针,本章主要内容:1. 指针的基本概念2. 各种类型的指针:数组的指针、字符串的指针、函数的指针、指针的指针等,指针的优点: (1)可有效地表示复杂的数据结构; (2)动态分配内存; (3)方便地使用字符串,数组; (4)直接处理内存地址等。指针的缺点: 概念繁杂,使用时较灵活,不易掌握。,10.1 地址和指针的概念,在计算机中,所有的数据都是存放在存储器中的。 一般把存储器中的一个字节称为一个内存单元, 不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符量占1个单元等。为了正确地访问这些内存单元, 必须为每个内存单元编上号。 根据一个内存单元的编号即可准确地找到该内存
2、单元。内存单元的编号也叫做地址。 既然根据内存单元的编号或地址就可以找到所需的内存单元,所以通常也把这个地址称为指针。,变量与地址,程序中: short i; float k;,内存中每个字节有一个编号-地址,i,k,变量是一块存储空间变量的地址就是指针,10.1 地址和指针的概念,一、关于内存,内存单元的指针和内存单元的内容是两个不同的概念。对于一个内存单元来说,单元的地址即为指针, 其中存放的数据才是该单元的内容。在语言中, 允许用一个变量来存放指针,这种变量称为指针变量。因此, 一个指针变量的值就是某个内存单元的地址或称为某内存单元的指针。,二、关于变量的访问 1. 直接访问:根据变量名
3、直接访问变量。int i;i=3;printf(“%d”,i); 2. 间接访问:将变量的地址存放于另一变量问题:如何获得一个变量的地址? 如何保存一个变量的地址?,如何获得一个变量的地址?,则&a获得变量的地址,如何保存一个变量的地址?,将变量的地址放在另一个(变量)中,三、若干术语 1. 指针:一个变量的地址,称为该变量的指针。 2. 指针变量:专门用来存放另一变量的地址(指 针)的变量,称为指针变量。 3. 指向:指针变量指向变量。,pt指向a,10.2 变量的指针和指向变量的指针变量一、指针变量的定义一般形式: 类型标识符 * 标识符; 例如:float * pf;int * p1,*
4、 p2;说明:(1)定义时,标识符前面的“ * ”表示该变量为指针变量,上例中 变量名为p1,p2。(2)类型标识符指出p1、p2所指向的变量的类型。,二、指针变量的引用两个相关运算符:1& 取地址运算符。,例: int a, *pt; 若: pt=&a,2* 指针运算符(间接访问运算符) *pt为指针变量pt所指向的变量. *pt等价于a *pt=10; 相当于a=10,pt指向a,例:main() int a,b; int *pointer_1,*pointer_2; a=100;b=10; pointer_1=,a,b,pointer_1,pointer_2,100,10,&a,&b,例
5、:输入两个整数a,b,按大小顺序输出。 main() int a,b,*p1,*p2,*p; scanf(“%d%d”, ,a,b,p1,p2,3,4,&b,p,&a,&a,&b,&a,注意:1、指针变量必须先赋值,再使用,只能保存地址例如:int *p,*p1,a=10; *p=20; printf(”%d”,*p1);,3、 则: &a、pt 、 &*pt是等价的 则: *&a、*pt、a 是等价的,2、一个指针变量只能指向同一类型的变量。int a,*p;float f;p=,三、指针变量作为函数参数 实参形参:传去的是地址值,分占不同空间。 1、指针变量作形参,在函数内部可以改变函数外
6、部变量的值例:输入两个整数,从大到小输出。,void swap(int*,int*); main() int a,b; int *p1,*p2; scanf(“%d,%d”,a,b,p1,p2,q1,q2,&a,&b,3,4,&a,&b,q,3,4,3,2、指针变量作形参,可以用来保存函数的返回值 (输出型形参)例:写一个函数,功能是求出一维整型数组中的最大值和最小值。,void maxmin(int a, int n, int *pmax, int *pmin) int i; *pmax=*pmin=a0; for(i=1;i*pmax) *pmax=ai;if(ai*pmin) *pmin
7、=ai; void main( ) int a10=0,9,-5,4,23,87,34,2,65,-45; int max,min; maxmin(a,10, ,课上练习,看程序写结果:void ast(int x,int y,int *cp,int *dp) *cp=x+y; *dp=x-y; void main()int a,b,c,d;a=4;b=3;ast(a,b,答案:7,1,10.3 数组的指针和指向数组的指针变量,一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个
8、指针变量中)。所谓数组元素的指针就是数组元素的地址。,一、指向数组元素的指针1.定义: int a10,*p; 注意:如果数组为int型,则指针变量的基类型 亦应为int型。 2. 赋值: p=,把0元素的地址赋给指针变量。也就是使指向数组的第号元素,如图:,说明: c语言规定数组名(不包括形参数组名),代表数组中首元素(下标为0的元素)的地址。 p= */习题集第七单元 一、8,9,10,36,二、通过指针引用数组元素 int a10,*p; 若p=a; 则*p=1 等价于 a0=1 p+1含义是什么? C中规定:若p=&a0, 则p+1指向下一个元素,不是简单的 加1。,因此,如果int
9、a10,*p;p=a;则有以下关系:(1) p+i a+i &ai。(2) *(p+i) *(a+i) ai。(3) 指向数组元素的指针变量也可带下标: pi *(p+i) 。 即有*(p+i) *(a+i) ai pi,练习(习题集7单元二、3),阅读程序,写结果void main() int a =2,4,6,8,10; int y=1,x,*p; p=,y=19,例:输出数组中全部元素。(设a数组,整型,10个元素),(1)下标法void main ( ) int a10; int i; for (i=0;i10;i+) scanf(%d,(2)用数组名计算数组元素地址法void mai
10、n ( ) int a10; int i; for (i=0;i10;i+) scanf(%d,a+i); printf(n); for (i=0;i10;i+) printf(%3d,*(a+i);,(3)用指针变量法1:main( ) int *p,i,a10; p=,/ p=a;,/ p=a;,用指针变量法2main( ) int *p,i,a10; p=a; for(i=0;i10;i+) scanf(%d, p+); printf(n); for (p=a;p(a+10);p+) printf(“%3d,*p );,3,5,-4,12,在使用指针变量时应注意的几个问题: 1. 数组名
11、是数组的首地址,因此 p=&a0 与 p=a 等价。 2指针变量可以实现使本身的值改变,数组名不可以。 例: p+正确 a+不正确 3要注意指针变量的当前值,指针变量可以指到数组后的内存单元。即指针变量的越界问题 4注意指针变量的运算,若先使p指向数组a(即p=a),则 (1) p+ (或p+=1) 指向下一个元素。 (2) *p+等价于*(p+)先得到p指向的变量的值,p再加1。 (3) *(p+)与*(+p)作用不同,前者先取*p,后使p加1; 后者相反。 (4) (*p)+表示p所指向的元素值加1。 (5) 若p当前指向a数组第i个元素,则: *(p-)相当于ai-,先取p值作*运算,再
12、使p自减; *(+p)相当于a+i,先使p自加,再作*运算; *(-p)相当于a-i,先使p自减,再作*运算。,void main() int a10,b10,i;int *pa,*pb;pa=a;pb=b;for(i=0;i10;i+)scanf(“%d”,pb+);pb=b; /*必不可少,否则出现越界*/for(i=0;i10;i+) *pa=*pb;pa+;pb+;pa=a; /*必不可少,否则出现越界*/for(i=0;i10;i+)printf(“%5d”,*pa+);,例:编程实现把整型数组b中的所有元素拷贝到数组a中。,习题集第七单元 一、1,14,15,16,17,18,19
13、,20,二、数组名作函数参数(P235),内容回顾:数组名做函数参数,当发生函数调用时实参传递给形参是什么?,int sum(int arr,int n)int s=0,i;for(i=0;in;i+)s+=ai;return s;,void main() int array5=1,2,3,4,5,i,s; s=sum(array,5); printf(“sum=%dn”,s);,实参传递给形参是实参数组的首地址实际上,形参数组名就是一个指针变量 int sum(int arr,int n)等价于 int sum(int * arr,int n),2,3,4,7,5,9,void inv(in
14、t *x, int n),例10.7:将数组a中n个整数按相反顺序存放。,void inv(int x, int n),void inv(int *x, int n) int temp,*p1,*p2,m; m=n/2; p1=x; p2=x+n-1; for ( ;p1x+m;p1+,p2-) temp=*p1; *p1=*p2; *p2=temp; ,void main() int a5=1,2,3,4,5; int i; inv(a,5); for(i=0;i5;i+)printf(“%4d”,ai);,如果有一个实参数组,想在函数中改变此数组,实参与形参的对应关系有以下几类情况:,例1
15、0.9:用选择法对10个整数排序。,void sort(int x, int n) int i,j,k,t; for (i=0;ixk) k=j; if (k!=i) t=xi; xi=xk; xk=t; ,main ( ) int *p,i,a10; p=a; for (i=0;i10;i+) scanf(%d,p+); p=a; sort(p,10); for (p=a,i=0;i10;i+) printf(%d,*p+);,(1) 形参用数组名, 实参用指针变量,sort(a,10);也行,(2) 形参用指针变量, 实参用数组名,void sort(int *x, int n) int
16、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; ,main ( ) int i,a10; for (i=0;i10;i+) scanf(%d,指针变量与一维数组的关系int *p 与 int q10 数组名是指针(地址)常量p=q; p+i 是qi的地址数组元素的表示方法:下标法和指针法, 即若p=q, 则 pi qi *(p+i) *(q+i) 形参数组实质上是指针变量, 即int q int *q系统只给p分配能保存一个指针值的内存区(一般4字节);而给q分配4*10字节的内存区,1、使
17、用指针访问二维数组方法一: 指向数组元素的指针变量。书上246247页,例:用指针变量输出二维数组元素的值。,main( ) int a23=2,3,6,7,8,5; int *p; p= ,三、二维数组和指针(P242),p,例:用指针变量输出数组元素aij的值。,main( ) int a23=2,3,6,7,8,5; int i,j,*p; p=,其中3是二维数组的列数,如果有如下定义:int a45; int * p;p=问题: p+11是哪个数据元素的地址。,答案:&a21,总结:p+i是&ai/5i%5其中5是二维数组的列数,习题集第七单元 二、4,main() int a45=1
18、,4,2,3,7,6,9,10,8,-1, -2,-6,-4,4,2,7,6,9,11,14; int i,j; for(i=0;i4;i+) for(j=0;j5;j+) printf(%4d,aij); printf(n); sort( ,例: 将一个二维数组a45进行按行全排序,void sort(int *p,int n) int i,j,t,k; for(i=0;in-1;i+) k=i; for(j=i+1;j=n-1;j+) if(*(p+k)*(p+j) k=j; if (k!=i) t=*(p+i); *(p+i)=*(p+k); *(p+k)=t; ,sort(,p,int
19、 a34= 6,9,0,16, 8,-1,2,7, 3,48,-5,12;,(1)二维数组的地址 P242,2、使用指针访问二维数组方法二: 指向由m个整数组成的一维数组的指针变量。,a代表的是首行(即第0行)的首地址a+1代表的是第1行的首地址a+2代表的是第2行的首地址,2000,2004,2016,2020,2032,2036,a00,a01,a10,a11,a20,a21,a02,a03,a12,a13,a22,a23,数组a包含三个元素 a0,a1,a2数组名a是首元素的地址 a就是a0,a1,a2是一维数组名,C语言又规定了数组名代表数组首元素地址,因此,a0代表一维数组a0中第0
20、列元素的地址,即&a00a1代表一维数组a1中第0列元素的地址,即&a10a2代表一维数组a2中第0列元素的地址,即&a20,1) a+i &ai 第i行的地址 *(a+i) ai 是ai元素,3) ai+j &aij aij的地址 即: *(a+i)+j &aij,4) aij元素可以表示为: *(ai+j) *(*(a+i)+j) aij,ai元素本身又是一个一维数组,ai相当于一维数组名,即ai中保存一个地址,是ai0的地址,即&ai0 ai &ai0,(2) 指向由m个整数组成的一维数组的指针变量,填空:int a34;_ p=a;,答案:int * p;,正确答案:int (*p)4
21、;,p称为指向一维数组的指针是指向由4个整数组成的一维数组的指针。,p是a0的地址是二维数组a中第0行的地址,习题集第七单元 一、6,23,例:输出二维数组任一行任一列的元素的值。 main ( ) int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4; int i,j; p=a; scanf(i=%d,j=%d,(3) 多维数组的指针作函数参数。,例: 求二维数组a45每列最大值,3,4,12,33,27,5,15,void colum_max(int (*a)5, int * b) int i,j; for(j=0;j5;j+) *(b+j)=*(*(a+0)+j); /*a0j*/ for(i=1;i4;i+) if (*(b+j)*(*(a+i)+j) *(b+j)=*(*(a+i)+j); ,main( ) int a45,b5; int i,j; for(i=0;i4;i+) for(j=0;j5;j+) scanf(%d,打印原二维数组,打印每列最大值,习题集第七单元 一、2,23二、4,19,24,25,27,
Copyright © 2018-2021 Wenke99.com All rights reserved
工信部备案号:浙ICP备20026746号-2
公安局备案号:浙公网安备33038302330469号
本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。