c语言程序设计(第五章12-22).ppt_第1页
c语言程序设计(第五章12-22).ppt_第2页
c语言程序设计(第五章12-22).ppt_第3页
c语言程序设计(第五章12-22).ppt_第4页
c语言程序设计(第五章12-22).ppt_第5页
已阅读5页,还剩75页未读 继续免费阅读

下载本文档

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

文档简介

第五章 指针,重点: 1、指针的概念 2、指针与数组的应用 3、指针与字符串 4、指向指针的指针,指针是在C语言中广泛使用的一种数据类型。指针能够模拟引用调用;能够建立和操作动态数据结构(如链表、队列、堆栈和树);能很方便的使用数组和字符串;并能处理内存地址,从而编出精炼高效的程序。,5.1 指针的基本概念,计算机中的所有数据是存放在存储器里的。一般将存储器中的一个字节称为一个内存单元。我们为每个内存单元编上号,使之能正确的访问这些内存单元。内存单元的编号也称为地址。指针变量则是将内存地址作为其值的变量。,指针变量的值不仅可以是变量的地址,还可以是其他数据结构的地址,比如说数组、函数的首地址。,一个指针是一个地址,是一个常量,而一个指针变量却可以被赋予不同的指针值,即取值为不同地址的变量。定义它的目的是为了通过指针变量去访问内存单元。 变量的指针就是变量的地址,存放变量地址的变量是指针变量。,i=3; * i_point=3;,i,2000H,5.2 指针变量的定义和初始化,5.2.1 指针变量的定义,格式: 类型说明符 *变量名 例: int * p1; /p1是一个指向整型变量的指针变量 float * p2; char * p3; 注意: 一个指针变量只能指向同类型的变量。,5.2.2 指针变量的初始化,指针变量可以用定义语句或赋值语句进行初始化。 例:int x,y; int *ipx= 在使用指针之前一定要将指针指向一个确定的地址。未被初始化的指针称为“无向指针”,使用该指针非常危险。可以将指针初始化为0、NULL或某个地址。具有值NULL的指针不指向任何值。NULL是在头文件中定义的符号常量。把一个指针初始化为0等价于把它初始化为NULL,但使用NULL更好。值0是唯一能够直接赋值给指针变量的整型数。,5.3 指针运算符,5.3.1 取地址运算符&,格式: ,1800,300,ip,i,1800H,5.3.2 指针运算符 *,指针运算符*通常称为“间接访问运算符”或“复引用运算符”,它返回其操作数(即一个指针)所指向的对象的值。 例: int i, *ip; ip=,*和,5.4指针变量的运算,5.4.1 赋值运算,指针变量的赋值运算有以下的几种形式: 指针变量初始化赋值。 把一个变量的地址赋予指向相同数据类型的指针变量。 把一个指针变量的值赋予指向相同类型变量的另一个指针变量。 例: int i , *ip= 把数组的首地址赋予指向数组的指针变量。,例: int a5, *pa; pa=a; 或 pa=,int i ; int *p=,int *p=,main() int i=10; int *p; *p=i; printf(“%d”,*p); ,程序的输出结果? main() int a=10,b; int *ipa= ,main() int a=10,b; int *ipa; b=*ipa; printf(“%d”,b); ,main() int a=10,b; int *ipa; *ipa=a; b=*ipa; printf(“%d”,b); a=100; b=*ipa; printf(“%d”,b); ,通过指针变量实现两变量值的交换,法1: main() int a=10,b=20,t=0; printf(“n a=%d,b=%d”,a,b); t=a; a=b; b=t; printf(“na=%d,b=%d”,a,b); getch(); ,法2: main() int a=10,b=20,t=0,*pa= ,5.4.2 加减算术运算,指针可进行的算术运算有:自增运算(+)、自减运算(-) 、加上一个整数(+或+=)、减去一个整数(-或-=)、减去一个指针。 1、指针变量加或减一个整数 ip+,ip-,ip+n,ip-n,ip+=n,ip-=n 当一个指针变量加或减一个整数时,并不是指针变量加(减)一个整数n,它的实质意义是 加上或减去该整数与指针指向对象的大小的乘积。对象的大小(即字节数)取决于对象的数据类型。即将指针由当前位置向前(向后)移动n个数据位置。,2000H,2002H,2004H,3000H,3004H,a0,a1,a2,x0,x1,指针变量ipa,int a=10,20,30; float x=15.5,25.5; int *ipa=a; float *fpx=,指针变量fpx,2、两指针变量相减 两指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。实质上是两个指针值(地址)相减之差再除以该数组元素的长度(字节数)。 注:两个指针变量不能进行加法运算。,main() int a=1,2,3,4,5,6,7,8,9,10; int *ip1=a,*ip2= ,3、指针变量的使用 指针变量可出现在表达式中 例:int x , y , *px=,5.4.3 两指针变量进行关系运算,指向同一数组的两指针变量可以进行关系运算 ,pa; 若两个指针指向同一个数组的元素,则指向前面元素的指针变量小于指向后面元素的指针变量。,程序的运行结果: main() int a=1,2,3,4,5,6,7,8,9,10; int *ip1= ,5.5 指针和数组,5.5.1 指向数组的指针变量,例 int array10; int *p; p= P是变量,array,&array0是常量。,数组名是表示数组首地址的地址常量,1,4,7,13,15,26,27,p,a0,a6,5.5.2 通过指针引用数组元素,C语言中规定,如果指针变量p 已指向数组中的一个元素。则P+1指向同一数组中的下一个元素。 1)用指针表达式引用数组元素 用指针表达式也可引用地址 数组名本身是一个指针,也可在指针表达式运算中引用数组元素。 指针也可以象数组一样带下标。,.,下标法,指针法,ai pi *(p+i) *(a+i), 下标运算符 ai *(a+i),P0,P1,P2,P9,main() int a5,*pa,i; for(i=0;i5;i+) ai=i+1; pa=a; for(i=0;i5;i+) printf(“*(pa+%d):%dn“,i,*(pa+i); for(i=0;i5;i+) printf(“*(a+%d):%dn“,i,*(a+i); for(i=0;i5;i+) printf(“pa%d:%dn“,i,pai); for(i=0;i5;i+) printf(“a%d:%dn“,i,ai); ,数组元素的四种引用方法,5.5.3 通过指针引用数组元素时应注意的几个问题,1)指针变量可以实现本身的值的改变,例 int a =1,2,3,4,5,6,7,8,9,10,*p=a,i; 数组元素地址的正确表示: (A)&(a+1) (B)a+ (C)&p (D)&pi,数组名是地址常量 p+,p- () a+,a- () a+1, *(a+2) (),2) 指针变量可以指向数组的任何元素,要注意指针变量的当前值。,main() int i,*p,a7; p=a; for(i=0;i7;i+) scanf(“%d“,p+); printf(“n“); p=a; for(i=0;i7;i+,p+) printf(“%d“,*p); ,指针变量可以指到数组后的内存单元,3)注意运算符+、-、&和*的混合运算,void main() int a =5,8,7,6,2,7,3; int y,*p= ,输出:5 6,*p+ *(p+) (*p)+ *(p-) *(+p) *(- -p),通过指针引用数组元素来输出一个一维数组。,#define N 5 main() int aN; int *p=a; printf(“n please input %d number :”,N); for (;pa+N;p+) scanf(“%d”,p); printf(“n”); for (p=a;pa+N;p+) printf(“%d”,*p); ,通过指针引用数组元素实现一位数组的反序输出,#define N 5 main() int xN,*p=x,*q=x+N-1,j,t; clrscr(); for (j=0;jN;j+) scanf(“%d”,p+j); for ( ;pq ; p+,q-) t=*p; *p=*q; *q=t; for (j=0,p=x;jN;j+) printf(“%d”,*(p+j); ,0 1 2 3 4 5 6 7 8 9 10 11,int a340,1,2,3,4,5,6,7,8,9,10,11,5.5.4 指向二维数组的指针,1、二维数组和数组元素的地址,1000,1008,1016,a0,a1,a2,(1)从2维数组角度看,数组名a代表整个二维数组的起始地址, 是一个以行为单位进行控制的行指针: a+i:行指针值,指向2维数组的第i行,代表第i行的首地址。,a,a+1,a+2,(2)从1维数组角度看,数组名a和第1维下标的每一个值, 共同构成一组新的1维数组名a0、a1、a2,它们均由4个元素组成。 语言规定:数组名代表数组的地址,所以ai是第i行1维数组的地址, 它指向该行的第0列元素,是一个以数组元素为单位进行控制的列指针: ai+j:(列)指针值,指向数组元素aij。 *(ai+j):表示数组元素aij的值。 如果有“int a34,*p=a0;”,则p+1指向下一个元素 用p作指针访问数组元素aij的格式: *(p+(*每行列数+j) ),*(a+i):(列)指针值,指向第i行第列(控制由行转为列,但仍为指针),表示一维数组第0列的元素地址。 *(*(a+i):表示数组元素ai0的值。 用a作指针访问数组元素aij的格式: *(*(a+i)j),例:通过指向数组元素的指针输出二维数组的各元素。,main() int a32=1,2,3,4,5,6,*pa; clrscr(); for( pa= ,用不同的表示方法输出二维数组a每行的起始地址和每行的起始单元的值。,#include void main() int a34=0,1,2,3,4,5,6,7,8,9,10,11; printf(“,printf(“a00- %dn”,a00); printf(“*(a0+0)- %dn”,*(a0+0); printf(“*(*(a+0)+0)- %dn”,*(*(a+0)+0); printf(“,2、 指针数组的概念,定义:数组中的元素值为指针。它是一组有序 的指针的集合。 格式: 类型说明符 *数组名数组长度,指针值所指向的变量的类型,int *pa3;,指针数组赋值和初始化,初始化: main() int b23,*pb =b0,b1; ,通常可用一个指针数组来指向一个二维数组。指针数组中的每个元素被赋予二维数组每一行的首地址,因此也可理解为指向一个一维数组。,#include void main() int a33=1,2,3,4,5,6,7,8,9; int *pa3; int *p=a0,i,j; for (i=0;i3;i+) pai=ai; for ( i=0;i3;i+) printf(“%p-%dn”,pai,*pai);,for (i=0;i3;i+) for (j=0;j3;j+) printf(“%p-%d”,p,*p); p=p+1; printf(“n”); ,指针可以指向整型、实型及任何类型,也可以指向一个数组类型,成为数组指针变量。 格式: 类型说明符 (*指针变量)长度; 类型说明符:为所指数组的数据类型 *:表示其后的变量是指针类型 长度:表示二维数组分解为多个一维数组时,一维数组的长度,即二维数组的列数。,3、 指向数组的指针变量,设p为一个指向数组的指针变量,可定义为: int (*p)4; 它表示p是一个数组指针变量,它可以指向包含4个元素的一维数组。 当p指向一个二维数组时, p+i 表示指向一维数组ai,即二维数组的第i行 *(p+i)+j 表示二维数组i行j列的元素的地址 *(*(p+i)+j)表示二维数组i行j列的元素的值,通过指向整型变量的指针变量输出二维数组任意一行、任意一列的元素值。,#include void main() int a34; int (*p)4; int i,j; printf(“pointer of array:n”); p=a; for (i=0;i3;i+) for (j=0;j4;j+) scanf(“%2d”, *(p+i)+j);,printf(“n”); printf(“please input i j :n”); scanf(“%d %d”, ,指针数组和二维数组指针变量的区别: 指向二维数组的指针变量是单个的变量,其形式为“(*指针变量名)”. 指针数组类型表示的是多个指针(一组有序指针),一般在指针数组名的两边不能有括号。 例: int (*p)3; 表示p是一个指向二维数组的指针变量,该二维数组的列数为3或分解为一维数组的长度为3。 int *p3 表示p是一个指针数组,有三个下标变量p0、p1、p2,均为指针变量。,二维数组与指针数组区别:,char name59=“gain”,“much”,“stronger”, “point”,“bye”;,char *name5=“gain”,“much”,“stronger”, “point”,“bye”;,指针数组元素的作用相当于二维数组的行名但指针数组中的元素值是地址值。 二维数组存储空间固定 字符指针数组相当于可变列长的二维数组,5.6 指向字符串的指针变量,5.6.1 字符串表示形式,1)用字符数组存放一个字符串 例: main( ) char string=“I love China!”; printf(“%sn”,string); printf(“%sn”,string+7); ,2)用字符串指针指向一个字符串,字符指针初始化:把字符串首地址赋给string char *string; string=“I love China!”; 例 main( ) char *string=“I love China!”; printf(“%sn”,string); string+=7; while(*string) putchar(string0); string+; ,*string!=0,5.6.2 使用字符串指针变量与字符数组的区别,(1)字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一片连续的内存空间中并以“0”作为串的结束,这片空间是无名的。 字符数组是由若干个数组元素组成的,它在内存中也占有一片连续的空间,但是它是有名的、有固定的空间,也可用来存放整个字符串。 (2)字符串的赋值方式,字符串与数组关系 字符串用一维字符数组存放 字符数组具有一维数组的所有特点 数组名是指向数组首地址的地址常量 数组元素的引用方法可用指针法和下标法 数组名作函数参数是地址传递等 区别 存储格式:字符串结束标志 赋值方式与初始化 输入输出方式:%s %c,char str=“Hello!”; () char str=“Hello!”; () char str=H,e,l,l,o,!; () char *cp=“Hello”; () int a=1,2,3,4,5; () int *p=1,2,3,4,5; (),char str10,*cp; int a10,*p; str=“Hello”; () cp=“Hello!”; () a=1,2,3,4,5; () p=1,2,3,4,5; (),赋值方式:,字符指针变量与字符数组 char *cp; 与 char str20; str由若干元素组成,每个元素放一个字符;而cp中存放字符串首地址 char str20; str=“I love China!”; () char *cp; cp=“I love China!”; () str是地址常量;cp是地址变量 cp接受键入字符串时,必须先开辟存储空间,例 char str10; scanf(“%s”,str); () 而 char *cp; scanf(“%s”, cp); (),改为: char *cp,str10; cp=str; scanf(“%s”,cp); (),例:使用指向字符串常量的指针来处理不同长度的字符串。,main() char *p=“I am a student”; printf(“n %s”,p); p=“You are a teacher.”); printf(“n%s”,p); getch(); ,例:从键盘输入两个字符串s1,s2,然后将s2的内容合并到s1的后面。,#define N 40 #define M 20 main() int i,j; char s1N,s2M,*p1,*p2; p1=s1; p2=s2; printf(“n input s1:”); gets(s1); printf(“n input s2:”);,gets(s2); while (*p1) p1+; while (*p2) *p1+=*p2+; *p1=0; printf(“result is :%s”,s1); ,从键盘输入一个字符串,删除其中与字符变量c相同的字符。,#include “stdio.h” #include “string.h” main() char str20,*s=str,c; int i,n; clrscr(); printf(“n enter s:”); gets(s); printf(“n enter c:”); c=getchar();,n=strlen(s); for (i=0;in;i+) if (*s=c) strcpy(s,s+1); else s+; s=str; puts(s); getch(); ,从键盘中输入两个字符串s1,s2,然后从s1中删除任何在s2中出现的字符。,#define N 40 main() int i; char s1N,s2N,*p1,*p2; printf(“n input s1:”); gets(s1); printf(“n input s2:”); gets(s2); p1=s1;,for (i=0;*(p1+i)!=0;i+) for (p2=s2;*p2!=0;p2+) while(*(p1+i)=*p2) strcpy( ,5.7 指向指针的指针变量,一级指针:指针变量中存放目标变量的地址,例 int *p; int i=3; p=,&i,3,P(指针变量),i(整型变量),一级指针,单级间接寻址,二级指针:指针变量中存放一级指针变量的地址,例 int *p1; int *p2; int i=3; p2=,二级指针,一级指针,目标变量,二级间接寻址,定义形式:存储类型 数据类型 *指针名; 如 char *p;,最终目标变量的数据类型,*p是p间接指向对象的地址 *p是p间接指向对象的值,例 int i=3; int *p1; int *p2; p1=,例 int i, *p; p= ()/p是二级指针,不能用变量地址为其赋值,指向指针的指针通常用于操作指针数组,读程,写结果 main() int i,j; char *p; char *str=“monitor”,”landscape”,”paddle”,”partition”,”current”; p=str;,for(i=0;i5;i+) printf(“n %s”,pi); for (i=0;i5;i+) printf(“n%d”,(*p)+); ,stri *(p+i),5.8 用于动态内存分配的函数 ANSI C标准为动态分配系统定义了四个函数:malloc、calloc、free、realloc。它们必须包含在文件 stdlib.h或malloc.h中。 库函数malloc、calloc是在内存中申请存储单元,并把存储单元的开始地址赋值给指针变量。 库函数free是将指针变量所指向的存储空间释放。,1、malloc()函数 格式: void *malloc(unsigned size) 功能:在内存中分配一个指定长度(以字节为单位)的存储空间,函数返回指向分配的存储区起始地址的指针。 由于函数的返回值为无值型的指针,因此在把返回值赋予具有一定数据类型的指针变量时,应该对返回值实行强制类型转换。 例:int *p; float *q; p=(int *)malloc(2); q=(float *)malloc(4);,2、free()函数 格式: void free(void *prt) 功能:释放由prt所指向的内存空间,以便这些空间可再次分配使用。,3、calloc()函数 格式: void *calloc(unsigned num, unsigned size) 功能:在内存中分配一块连续的容量为num*size的存储空间,num为需要分配的元素个数,size为每个元素所占的内存空间。函数返回一个指向被分配内存的指针。,4、realloc()函数 格式: void *realloc(void *p, un

温馨提示

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

评论

0/150

提交评论