C语言程序设计第九章善于利用指针_第1页
C语言程序设计第九章善于利用指针_第2页
C语言程序设计第九章善于利用指针_第3页
C语言程序设计第九章善于利用指针_第4页
C语言程序设计第九章善于利用指针_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

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

文档简介

C程序设计,主讲人:袁丽,燕大里仁基础教学部,第九章:善于利用指针,字符串指针和指向字符串的指针变量,指针数组和指向指针的指针,指针小结,地址指针的基本概念,一、指针变量,如何定义指针变量,如何引用指针变量,指针变量作为函数参数,引:指针是什么,如果在程序中定义了一个变量,在对程序进行编译时,系统就会给该变量分配内存单元编译系统根据程序中定义的变量类型,分配一定长度的空间例如,VC+为整型变量分配4个字节,对单精度浮点型变量分配个字节,对字符型变量分配个字节,务必弄清楚存储单元的地址和存储单元的内容这两个概念的区别例如:,内存区的每一个字节有一个编号,这就是“地址”,它相当于旅馆中的房间号。在地址所标识的内存单元中存放数据,这相当于旅馆房间中居住的旅客一样。由于通过地址能找到所需的变量单元,我们可以说,地址指向该变量单元。将地址形象化地称为“指针”,inti=3,j=6,k;,printf(“%d”,i);,通过变量名i,找到i的地址2000,从而从存储单元读取3,inti=3,j=6,k;,k=i+j;,从这里取3,将9送到这里,从这里取6,直接存取,inti=3,j=6,k;,定义特殊变量i_pointer,将i的地址存到这里,间接存取,i_pointer=,*i_pointer=50;,50,i,2000,3,2000,i_pointer,*i_pointer,2000,3,直接存取,间接存取,为了表示将数值送到变量中,可以有两种表达方法:(1)将3直接送到变量i所标识的单元中,例如:i=3;(2)将3送到变量i_pointer所指向的单元(即变量i的存储单元),例如:*i_pointer=3;其中*i_pointer表示i_pointer指向的对象,指向就是通过地址来体现的假设i_pointer中的值是变量的地址(2000),这样就在i_pointer和变量之间建立起一种联系,即通过i_pointer能知道i的地址,从而找到变量i的内存单元,由于通过地址能找到所需的变量单元,因此说,地址指向该变量单元将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元,一个变量的地址称为该变量的“指针”例如,地址2000是变量的指针如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量”i_pointer就是一个指针变量。指针变量就是地址变量,用来存放地址的变量,指針变量的值是地址(即指针),“指针”和“指针变量”是不同的概念可以说变量i的指针是2000,而不能说i的指针变量是2000指针是一个地址,而指针变量是存放地址的变量,定义指针变量,定义指针变量的一般形式为:类型*指针变量名;其中,*表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数据类型如:int*pointer_1,*pointer_2;int是为指针变量指定的“基类型”基类型指定指针变量可指向的变量类型如pointer_1可以指向整型变量,但不能指向浮点型变量,如:int*p1;表示p1是一个指针变量,它的值是某个整型变量的地址。或者说p1指向一个整型变量。至于p1究竟指向哪一个整型变量,应由向p1赋予的地址来决定。,引用指针变量,在引用指针变量时,可能有三种情况:给指针变量赋值。如:p=,使p指向a,*p相当于a,以八进制输出a的地址,要熟练掌握两个有关的运算符:(1)取地址运算符。(把1赋给a),设有指向整型变量的指针变量p,如要把整型变量a的地址赋予p可以有以下两种方式:1.指针变量初始化的方法inta;int*p=2.被赋值的指针变量前不能再加“*”说明符,如写为*p=int*ip;我们定义了两个整型变量i,x,还定义了一个指向整型数的指针变量ip。i,x中可存放整数,而ip中只能存放整型变量的地址。我们可以把i的地址赋给ip:ip=此时指针变量ip指向整型变量i,假设变量i的地址为1800,这个赋值可形象理解为下图所示的联系。,以后我们便可以通过指针变量ip间接访问变量i,例如:x=*ip;运算符*访问以ip为地址的存储区域,而ip中存放的是变量i的地址,因此,*ip访问的是地址为1800的存储区域(因为是整数,实际上是从1800开始的两个字节),它就是i所占用的存储区域,所以上面的赋值表达式等价于x=i;,另外,指针变量和一般变量一样,存放在它们之中的值是可以改变的,也就是说可以改变它们的指向,假设inti,j,*p1,*p2;i=a;j=b;p1=则建立如下图所示的联系:,这时赋值表达式:p2=p1就使p2与p1指向同一对象i,此时*p2就等价于i,而不是j,图所示:,如果执行如下表达式:*p2=*p1;则表示把p1指向的内容赋给p2所指的区域,此时就变成图所示:,例:输入a和b两个整数,按先大后小的顺序输出a和b。解题思路:用指针方法来处理这个问题。不交换整型变量的值,而是交换两个指针变量的值。,#includeintmain()int*p1,*p2,*p,a,b;printf(“integernumbers:);scanf(“%d,%d”,a,b,p1,p2,p,5,9,printf(“integernumbers:);scanf(“%d,%d”,a,b,p1,p2,p,5,9,printf(“integernumbers:);scanf(“%d,%d”,a,b,p1,p2,p,5,9,inta,b;int*pointer_1,*pointer_2;printf(pleaseenteraandb:);scanf(“%d,%d”,pointer_1,a,temp=*p1;*p1=*p2;*p2=temp;,a,b,pointer_1,5,9,inta,b,c,*p1,*p2,*p3;scanf(%d,%d,%d,调用结束后不会改变指针的指向,voidexchange(int*q1,int*q2,int*q3)voidswap(int*pt1,int*pt2);if(*q1*q2)swap(q1,q2);if(*q1*q3)swap(q1,q3);if(*q2*q3)swap(q2,q3);voidswap(int*pt1,int*pt2)inttemp;temp=*pt1;*pt1=*pt2;*pt2=temp;,交换指针指向的变量值,二、数组指针和指向数组的指针变量,指向数组元素的指针,通过指针引用数组元素,数组名做函数参数,指向多维数组的指针和指针变量,指向数组元素的指针,一个数组是由连续的一块内存单元组成的。数组名就是这块连续内存单元的首地址。一个数组也是由各个数组元素(下标变量)组成的。每个数组元素按其类型不同占有几个连续的内存单元。一个数组元素的首地址也是指它所占有的几个内存单元的首地址。,定义一个指向数组元素的指针变量的方法,与以前介绍的指针变量相同。数组指针变量说明的一般形式为:类型说明符*指针变量名;,例如:inta10;/*定义a为包含10个整型数据的数组*/int*p;/*定义p为指向整型变量的指针*/应当注意,因为数组为int型,所以指针变量也应为指向int型的指针变量。下面是对指针变量赋值:p=把a0元素的地址赋给指针变量p。也就是说,p指向a数组的第0号元素。,C语言规定,数组名代表数组的首地址,也就是第0号元素的地址。因此,下面两个语句等价:p=从图中我们可以看出有以下关系:p,a,for(i=0;i10;i+)ai=i;for(i=0;i5;i+)printf(a%d=%dn,i,ai);,2.输出数组中的全部元素。(用指针变量指向元素)main()inta10,i,*p;p=a;for(i=0;i10;i+)*(p+i)=i;for(i=0;i10;i+)printf(a%d=%dn,i,*(p+i);,3.输出数组中的全部元素。(通过数组名计算元素的地址,找出元素的值)main()inta10,i;for(i=0;i0)swap(str1,str3);if(strcmp(str2,str3)0)swap(str2,str3);printf(“theorderis:n”);printf(“%sn%sn%sn”,str1,str2,str3);return0;,例:输入3个字符串,按由小到大的顺序输出。,voidswap(char*p1,char*p2)charp20;strcpy(p,p1);strcpy(p1,p2);strcpy(p2,p);,使用字符串指针变量与字符数组的区别,用字符数组和字符指针变量都可实现字符串的存储和运算。但是两者是有区别的。在使用时应注意以下几个问题:1.字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以0作为串的结束。字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。2.对字符串指针方式char*ps=CLanguage;可以写为:char*ps;ps=CLanguage;而对数组方式:staticcharst=CLanguage;不能写为:charst20;st=CLanguage;而只能对字符数组的各元素逐个赋值。,四、指针数组和指向指针的指针,指针数组的概念,指向指针的指针,字符串的表示形式,指针数组的概念,一个数组的元素值为指针则是指针数组。指针数组是一组有序的指针的集合。指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。指针数组说明的一般形式为:类型说明符*数组名数组长度其中类型说明符为指针值所指向的变量的类型。例如:int*pa3表示pa是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整型变量。,应该注意指针数组和二维数组指针变量的区别。这两者虽然都可用来表示二维数组,但是其表示方法和意义是不同的。二维数组指针变量是单个的变量,其一般形式中(*指针变量名)两边的括号不可少。而指针数组类型表示的是多个指针(一组有序指针)在一般形式中*指针数组名两边不能有括号。例如:int(*p)3;表示一个指向二维数组的指针变量。该二维数组的列数为3或分解为一维数组的长度为3。int*p3表示p是一个指针数组,有三个下标变量p0,p1,p2均为指针变量。,指向指针的指针,从下图可以看到,name是一个指针数组,它的每一个元素是一个指针型数据,其值为地址。name是一个数组,它的每一个元素都有相应的地址。数组名name代表该指针数组的首地址。name+1是manei的地址。name+1就是指向指针型数据的指针(地址)。还可以设置一个指针变量p,使它指向指针数组元素。P就是指向指针型数据的指针变量。,如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。,char*p;p前面有两个*号,相当于*(*p)。显然*p是指针变量的定义形式,如果没有最前面的*,那就是定义了一个指向字符数据的指针变量。现在它前面又有一个*号,表示指针变量p是指向一个字符指针型变量的。*p就是p所指向的另一个指针变量。,如果有:p=name+2;printf(“%on”,*p);printf(“%sn”,*p);则第一个printf函数语句输出name2的值(它是一个地址),第二个printf函数语句以字符串形式(%s)输出字符串“GreatWall”。,指针变量可以进行某些运算,但其运算的种类是有限的。它只能进行赋值运算和部分算术运算及关系运算。1.指针运算符取地址运算符pa=/*把a的地址赋予指针变量pb*/由于pa,pb均为指向整型变量的指针变量,因此可以相互赋值。,指针变量的进一步说明,2.指针变量的运算把数组的首地址赋予指向数组的指针变量。例如:inta5,*pa;pa=a;(数组名表示数组的首地址,故可赋予指向数组的指针变量pa)也可写为:pa=,指针变量的进一步说明,把字符串的首地址赋予指向字符类型的指针变量。例如:char*pc;pc=CLanguage;或用初始化赋值的方法写为:char*pc=CLanguage;这里应说明的是并不是把整个字符串装入指针变量,而是把存放该字符串的字符数组的首地址装入指针变量。把函数的入口地址赋予指向函数的指针变量。例如:int(*pf)();pf=f;/*f为函数名*/,2.指针变量的运算(2)加减算术运算:对于指向数组的指针变量,可以加上或减去一个整数n。设pa是指向数组a的指针变量,则pa+n,pa-n,pa+,+pa,pa-,-pa运算都是合法的。指针变量加或减一个整数n的意义是把指针指向的当前位置(指向某数组元素)向前或向后移动n个位置。应该注意,数组指针变量向前或向后移动一个位置和地址加1或减1在概念上是不同的。因为

温馨提示

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

评论

0/150

提交评论