c语言课件 第九章.ppt

上传人:本田雅阁 文档编号:2143304 上传时间:2019-02-21 格式:PPT 页数:90 大小:861.01KB
返回 下载 相关 举报
c语言课件 第九章.ppt_第1页
第1页 / 共90页
c语言课件 第九章.ppt_第2页
第2页 / 共90页
c语言课件 第九章.ppt_第3页
第3页 / 共90页
亲,该文档总共90页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《c语言课件 第九章.ppt》由会员分享,可在线阅读,更多相关《c语言课件 第九章.ppt(90页珍藏版)》请在三一文库上搜索。

1、共 90 页 第 1 页,第九章 指 针,C语言程序设计,共 90 页 第 2 页,本 章 要 点,1. 理解指针与地址的概念; 2. 掌握指针的定义和运算; 3. 掌握指向基本类型、数组、字符串的指针的使用; 4.充分理解指针和数组的等价性; 5.掌握指针函数和函数指针的使用; 6.了解指向指针的指针的概念及其使用。,共 90 页 第 3 页,预 备 知 识,内存:就是内部存储器,是由存储单元组成 的。它的特点是存储单元是线性连续 的。存储单元的最小单位是字节。,1. 内存的概念,共 90 页 第 4 页,地址:为了访问内存中的某个存储单元,我们 要为它编号,这种编号称为内存地址。 通过地址

2、我们就能够访问该地址所标 识的存储单元。,2. 地址的概念,共 90 页 第 5 页,变量的地址:变量的地址是变量在内存中占用连续字节的首地址。,2007,存储单元,共 90 页 第 6 页,以往对变量的访问: 定义变量: int k;编译系统根据类型为k分配内存。 输入变量的值:scanf(“%d”,通过指针间接访问: C提供了另一种方式,将变量 k的地址存放在另一个变量处(假定为pk),通过访问 pk,就可以间接地访问变量 k,这种方式称为间接访问。,变量的存取方法:直接存取和间接存取。,共 90 页 第 7 页,引入指针程序设计的优点,有效表示复杂的数据结构。 方便使用字符串、数组。 可

3、以得到多个返回值。 可以进行动态分配内存。 程序简洁、紧凑, 执行效率高。,共 90 页 第 8 页,9.1.1 指针的基本概念,指针:一个变量的地址称为该变量的指针。 指针变量:若一个变量专用于存放另一个变量的地址(指针),则称此变量为指针变量。 若指针变量p的值等于变量x的地址, 则说指针变量p指向变量x。,1000,35,1000,p,x,x的值,p的值,X的内存地址,9.1 指针的基本概念及指针变量的定义,共 90 页 第 9 页,指针的对象:当把变量的地址存入指针变量后,就可以说这个指针指向了该变量。,共 90 页 第 10 页,9.1.2 指针变量的定义,指针变量定义的一般形式:

4、类型标识符 *标识符,例: float *p1; int *p2; 作用:定义变量为指针类型,使之专门用于存放地址。,指针所指的变量的类型,指针变量名,共 90 页 第 11 页,说明:,(1)*用于定义指针变量,但指针变量名不带*。 如 int *p1; float *p2; 定义的指针变量为p1,p2 (2)一个指针变量只能指向同一类型的变量。 如 p1 只能用于指向整型变量 p2 只能用于指向实型变量 (3)无论指针变量指向何种类型,指针变量本身都是整型的,指针变量本身也有自己的地址,占两个字节的存储空间。,共 90 页 第 12 页,1.取地址运算 &,格式: 让p指向b,使q指向a,

5、p指向b,9.2 指针变量的引用和运算,C语言提供两种与指针有关的运算符:& *,共 90 页 第 13 页,2. 取内容运算 *,格式: * 指针表达式 设p是一个指针表达式,则: (1)若*p出现在赋值号左边,表示给p所指变量赋值 (2)若*p不出现在赋值号左边,表示p所指变量的值 若有变量说明:int a, *p ; p= 给变量a输入值 *p+25 等价于a+25,共 90 页 第 14 页,3. 为指针变量赋初值,指针变量使用前必须有值,指针变量的初值必须是地址值(不能是整数),方法 :,在说明指针变量时同时初始化 int a , *p = ,可以为指针赋空值(NULL),此时指针不

6、指向任何 变量, 如 p=NULL或 p=0;p=0; ( p为空指针),共 90 页 第 15 页,对*及&的说明:(同级运算,由右向左),若pa=&a (将 a 的地址送指针变量pa), 则 &*pa &(*pa) &(a) &a *&a *(&a) *pa a (*pa)+ a+ *pa+ *(pa+) (先取*pa值,然后使pa加1) *+pa *(+pa) (先使pa加1 ,再取*pa值),注意:此时pa不再指向a,共 90 页 第 16 页,例 9-1 输出变量的值。 main( ) int a,b; int *pa, *pb; a=100; b=10; pa= ,定义指针变量pa

7、,pb,将a的地址送pa,将b的地址送pb,输出所指向的变量,运行结果为 100,10 100,10,共 90 页 第 17 页,例9-2将两个整型数a,b按由大到小次序输出。,main( ) int *p1 ,*p2 ,*p ,a ,b; scanf(“%d,%d”, ,注意:a和b并未交换,但p1和p2的值交换了,运行情况: 5,9 a=5,b=9 larger=9,little=5,共 90 页 第 18 页,在C语言中,凡是可以通过数组下标方式完成的访问(操作)均可以通过指针方式实现。称为指针方式。,9. 3指针与数组,数组中的每个元素都可以通过下标唯一确定,即通过下标可以访问(操作)

8、数组中的元素,称为下标方式。如ai,访问数组的两种方式:下标方式,指针方式.,C语言规定:数组名就是数组的首地址常量.,于是:,a = &a0,语言系统内部处理机制,指针方式效率高,共 90 页 第 19 页,int a10, *p; p=a; (等价于 p= 2.通过指针引用数组 引用数组元素可以用下标法,也可以用指针法,即通过指向数组元素的指针变量找到所需元素。,P=&a0,1.数组元素的指针,9.3.1 指针变量与一维数组之间的联系,共 90 页 第 20 页,9.3.2 指针的运算,1.指针表达式与整数的加减运算 形式:p+n 或 p-n 其中:p是任意一个指针表达式,n 是任何一种整

9、型表达式 计算规则: 表达式p+n的值=p的值+p所指类型长度*n 表达式p-n的值=p的值-p所指类型长度*n 说明: 只有当p和p+n或p-n都指向连续存放的同类型数据区域(数组)时,指针加、减才有实际意义。 C语言规定:表达式p+n和p-n的类型与p相同。,共 90 页 第 21 页,p, a,p+1,a+1,p+9,a+9,p+i,a+i,a0,a1,a2,ai,a9,a数组,例如: int a10,*p; p=a;,*(p+i),共 90 页 第 22 页,例如:设有变量定义: int a10, *p , *q ; 则 p=a p指向a0 q=a+6 q指向a6 p=q-4 p指向a

10、2,3,4,12,11,5,6,7,8,9,10,p=a,a0,a6,a9,q=a+6,q- 4,1000,共 90 页 第 23 页,2. 指针自增自减运算,语法:p+ ; p- ; +p ; -p ; 进行+p或p+运算后都使p指向下一个数据 p+与+p的区别: 表达式p+的值等于p的原来值; 表达式+p的值等于p的新值; 取内容运算符“ * ”、取地址运算符“ & ”和自增自减运算符都是单目运算符,运算的优先级相同,结合方向都是自右至左。,例如:int a =1,2,3,4,5,*p,*q ; p=q= a?变成100,a3,a4,共 90 页 第 24 页,把值为0的指针变量称作空指针

11、变量。 空指针变量表示不指向任何地方,表示指针变量的一种状态。 p=0 ; p=0; p=NULL; 三个语句等价。其中p为指针变量;0的ASCII码值为0;NULL是在“stdio.h”文件中定义的符号常数,其值为0,代表地址0和空指针的概念。 如果给空指针变量所指内存区域赋值,将会得到一个出错信息。,3. 空指针,共 90 页 第 25 页,p-2,p-1,p,p+1,p+2,p-3,当两个指针指向同一个数组中的元素时,才能进行、=、=、!=、=的关系运算。,任何指针p与NULL进行“P=NULL”或“P!=NULL”运算均有意义:判断指针 p 是否指向空。,4.指针的关系运算,指针的关系

12、运算只有同类指针进行比较才有意义,共 90 页 第 26 页,p=q 两指针指向同一元素时为 1,反之为0。,p!=q 两指针不指向同一元素时为 1,反之为0。,假定指针p 和q指向同一个数组,则:,pq p指针所指元素位于q所指元素之后时为1,反之为0。,p=q p指针所指元素位于q所指元素之后(或两指针指向同一元素)时为1,反之为0。,=和!=运算符,比较的是两个指针表达式是否指向同一个内存单元; 、=,比较的是两个指针所指内存区域的先后次序 语法格式: 指针表达式 关系运算符 指针表达式,例:int a10; int *p=a, *q=a+3; 判断以下表达式的值 p=&a0 p=&a1

13、 p=q p+4=q+2 pa+2 pq,共 90 页 第 27 页,5. 同类指针相减,同类指针相减时,两个指针应该指向连续存放的同类数据区域。 语法 :p-q 说明: p-q 的值,等于(p的值-q的值)/所指类型长度, 即p,q两个指针之间数据元素的个数。 例如:若有 int a10 , *p, *q; p=a; q= 则p-q=5 表示p,q之间数据元素的个数是5。,共 90 页 第 28 页,格式: (类型名 * ) 指针表达式 功能:将指针表达式的值转换成指定类型的指针。 例如: int *p; double d, *q=,6. 强制类型转换运算,共 90 页 第 29 页,9.3

14、.3 通过指针引用数组元素,引用数组中的元素可以用以下方法: 下标法 : 如 a3,ai 指针法: 即通过指向数组元素的指针找到所需的元素. 这种方法占内存少, 运行速度快,程序代码质量高。 假设p已定义为指针变量,并已赋了一个地址,它指向某一个数组元素. 且有赋值语句p= 则: p+1 表示数组中的下一个元素, a+i和p+i都是ai 的地址,或者说它们指向ai. *(a+i) 或 *(p+i)是a+i或p+i所指向的数组元素。 指向数组的指针变量也可带有下标,如pi与*(p+i)等价。,对下标为i的元素访问: ai,*(a+i),*(p+i),pi 对ai的地址表示: &ai,a+i,p+

15、i,&pi,共 90 页 第 30 页,例: 用三种方法输出数组全部元素。,下标法: main( ) int a10, i; for(i=0;i10;i+) scanf(“%d”, ,地址法 (通过数组名计算数组元素地址) for(i=0;i10;i+) printf(“%5d”,*(a+i); 指针法 for(p=a;p(a+10);p+) printf(“%5d”,*p );,共 90 页 第 31 页,例9-3 用指针访问数组元素。,main( ) int a10,*pa, i; for (i=0;i10;i+) ai=i+1; pa=a; for(i=0;i10;i+,pa+) pri

16、ntf(“%d”,*pa); printf(“n”); ,不要忘记赋初值,如何修改程序可以完成功能?,共 90 页 第 32 页,例9-4 给定10个整数,求最大值。,main( ) int a10=5,7,3,6,2,1,8,9,4,0; int i, *p,max; p=a; max=*p+; for(i=1; imax ) max=*p ; printf ( “max=%dn”, max); ,问题:如果修改语句 for(i=1;imax) max=*p+ ; 能实现程序功能吗?,问题:如果修改语句 for(;pmax) max=*p ; 能实现程序功能吗?,共 90 页 第 33 页,

17、9.3.4 字符串指针与字符串,1.字符串的表示形式 用字符数组表示,如: main( ) char string =“I love China!”; printf(“%sn”,string); ,数组名,用字符指针实现,如: mian( ) char * string =“I love China!”; printf(“%sn”,string); ,把“I love China!”的首地 址赋给指针变量string,特点:字符串的长度不受限制;字符指针指向别处,字符串将失踪.,共 90 页 第 34 页,2.字符指针变量与字符数组的比较,字符数组由若干个元素组成,每个元素中放一个字符,而字符

18、指针变量中存放的是字符串的首地址。 赋值方式: char str =“I am a boy!” 或: char str20; scanf(“%s”,str); 字符指针变量指向字符串首地址。赋值方法三种: (1) char *pa=“I am a boy!” (2) char *pa; pa=“I am a boy!” (3) char *pa, str20; pa=str; scanf(“%s”,pa);,共 90 页 第 35 页,例9-5 已知下面程序的输出结果:ABCDCD,请完善程序: main() char *chp=“ABCD”; for( ; _A_; chp=chp+2) p

19、rintf(“%s”, _B_); printf(“n”); ,A. *chp!=0,B. chp,共 90 页 第 36 页,作用: 函数的参数不仅可以是整型、实型、字符型,还可以是指针型,它的作用是将一个变量的地址传送到另外一个函数中。,9. 4 指针与函数,9.4.1 指针变量作函数参数,共 90 页 第 37 页,例:交换两个变量的值。注意函数调用形实结合方式.,swap(x,y) int x,y; int t; t=x; x=y; y=t; ,main( ) int a,b; scanf(“%d,%d”, ,单向值传递!,调用函数时a的值传送给x,b值传送给y,可是执行完函数后,x和

20、y的值是互换了,但a,b的值并未互换。,共 90 页 第 38 页,swap(int *p1,int *p2) int p; p=*p1; *p1=*p2; *p2=p; ,main( ) int a,b; int *pa, *pb; scanf(“%d,%d”, ,运行情况: 5,9 9,5,交换指针所指 向的变量的值,分析观察使用指针做形参和实参的结果,例:将两个数按从大到小顺序输出(交换两个变量的值)。,结论:被调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。,共 90 页 第 39 页,函数调用过程如下图所示:,调用swap函数之前:,共 90 页 第 40

21、页,执行函数语句,p1、p2所指向的变量的值相互交换,*p1,*p2,共 90 页 第 41 页,函数调用结束后,p1、p2所占用的内存单元被释放,,共 90 页 第 42 页,swap(int *p1,int *p2) int *p; p=p1; p1=p2; p2=p; ,main( ) int a,b; int *pa, *pb; scanf(“%d,%d”, ,C语言中,实参和形参间的数据是单向值传递方式。 指针做函数参数也遵循该原则.,改变指针形参的值,也不能改变指针实参的值.,结果为:?,交换了两个指针中的内容。,共 90 页 第 43 页,9.4.2 数组名作函数参数,当用数组名

22、作为参数时,如果形参数组中元素的值发生变化,实参数组元素的值也随之变化,为什么? 若有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种情况: 形参与实参都用数组名 实参用数组名,形参用指针变量 实参形参均用指针变量 实参为指针变量,形参为数组名,都是地址传递,只是形式不同!,共 90 页 第 44 页,指针作函数参数应注意的问题,指针变量在作实参时,必须有确定的值,即指向一个已定义的单元。 如:main() int *p; f(p,10); int f(int x ,int n) ,如何修改?,共 90 页 第 45 页,例9-6:用选择法对10个整数由小到大排序。

23、 方法1:形参和实参都用数组名(在函数中介绍的),main( ) int i, a10; void sort( ); for(i=0;i10;i+) scanf(“%d”, ,void sort( int x , int n) int i,j, t; for(i=0;ixj) t=xi; xi=xj; xj=t; ,形参是数组名,实参也是数组名,共 90 页 第 46 页,方法2:形参是数组名,实参是指针变量。,main( ) int *p, i, a10; void sort( ); p=a; for(i=0;i10;i+) scanf(“%d“,p+); sort(p,10); for(p

24、=a, i=0; i10 ;i+) printf(“%d“, *p+); ,void sort( int x, int n) int i,j, t; for(i=0;ixj) t=xi; xi=xj; xj=t; ,p=a;,形参是数组名,实参是指针,当用数组名作函数参数时,由于数组名代表的是数组首元素地址,因此传递的是地址,所以要求实参为指针变量。,共 90 页 第 47 页,方法3:实参是数组名,形参是指针变量。,void sort( int *x, int n) int i,j, t; for(i=0;i*(x+j) t=*(x+i); *(x+i)=*(x+j); *(x+j)=t;

25、,实参是指针,main( ) int i, a10; void sort( ); for(i=0;i10;i+) scanf(“%d”, ,形参是指针,实参是数组名,共 90 页 第 48 页,方法4:实参和形参都是指针变量。,void sort( int*x, int n) int i,j, t; for(i=0;i*(x+j) t=*(x+i); *(x+i)=*(x+j); *(x+j)=t; ,实参是指针,main( ) int *p, i, a10; void sort( ); p=a; for(i=0;i10;i+) scanf(“%d“,p+); p=a; sort(p,10);

26、 for(p=a, i=0; i10 ;i+) printf(“%d“, *p+); ,实参也是指针,形参是指针,共 90 页 第 49 页,例9-7 编写函数,删除字符串中的给定字符。 delete(char d , char f) int j=0, k=0; while (dj!=0) if(dj!=f ) dk+=dj; j+; dk=0; ,共 90 页 第 50 页,main( ) char *str=How, are, you! , c=, ; printf(original string is: %sn,str); delete(str, c); printf(compresse

27、d string is: %sn,str); 程序执行结果: original string is: How, are, you! compressed string is: How are you!,本例主函数调用语句的实参分别是字符型指针变量和字符型变量,对应的子函数的形参分别是字符型一维数组名和字符型变量。程序的功能是删除逗号“,”字符。,共 90 页 第 51 页,strcopy ( char *str1, char *str2 ) /*形参为指向字符的指针 */ while ( (*str2+ = *str1+)!=0); main( ) char a30, b30; printf(

28、“Enter string:“); scanf (“%s“, a); strcopy ( a, b ); printf (“a=%snb=%sn“, a, b ); ,例9-8 编写字符串复制函数,并调用。,共 90 页 第 52 页,返回指针的函数定义形式: 类型说明符 *函数名(形式参数表) 说明部分 语句 说明: 表示函数的返回值是一个指针.其他和一般函数相同.,9.4.3 返回指针的函数,如 int * f(int x , int y) ;,共 90 页 第 53 页,例9-9 在给定的字符串s中寻找一个特定的字符x,若找到x,则返回x在s中第一次出现的地址,并把s中该字符和该字符之前

29、的字符按逆序输出。,char *str(char *s, char x) int c=0; while(x!=sc ,共 90 页 第 54 页,#include stdio.h main( ) char s40, *p, x, *str( ); gets(s); x=getchar( ); p=str(s,x); if(*p) printf(%c,*p); do p - -; printf(%c,*p); while(p-s); else printf(char %c not found, x); ,共 90 页 第 55 页,9.4.4 函数的指针和指向函数的指针变量,1 . 函数的指针

30、函数名字的值等于该函数存储的首地址,即等于该函数的入口地址。 一个函数在编译时被分配一个入口地址,这个入口地址称为函数的指针。,共 90 页 第 56 页,2.指向函数的指针变量的定义和功能 (1)定义形式,数据类型标识符(*指针变量名)(形式参数表);,函数返回值的类型,(2) 功能 定义一个指向函数的指针变量,该指针变量所指向的函数的返回值是“类型说明符”的类型,该函数的参数个数及类型由“形式参数表”确定。 定义指向函数的指针变量时,形式参数表只写出各个形式参数的类型即可,也可以省略形式参数表。,共 90 页 第 57 页,3.指向函数的指针变量允许的操作 将函数名或指向函数的指针变量的值

31、赋给指向同一类型函数的指针变量。 函数名或指向函数的指针变量作为函数的参数。即将函数名传给形参。,(3) 可以利用指向函数的指针变量调用函数,调用形式是: (*变量名)(实际参数表) 调用结果:使程序的执行流程转移到指针变量所指向函数的函数体。 函数指针经定义和赋初值后,就可以引用该指针,调用被指针所指的函数.增加了函数调用的方式。,共 90 页 第 58 页,例9-10 求a和b中的大者。 main ( ) int max( ); int (*p)( ); int a,b ,c; p=max; scanf(%d,%d”, ,max(x,y) int x,y; int z; if (xy) z

32、=x; else z=y; return (z); ,指向函数 的指针,指向max 函数,共 90 页 第 59 页,在一个程序中,一个指针变量可以先后指向不同的函数; 例如: int (*p)( ); int max( ); int min( ); p=max; c=(*p)(a , b); p=min; c=(*p)(a , b);,P先于*结合,是指针变量,然后再与()结合,表示此指针变量指向函数。,共 90 页 第 60 页,实参函数名f1 f2 sub( x1, x2) int(*x1)( ),(*x2)( ); int a,b,i,j; a=(*x1)(i); b=(*x2)(i,

33、j); ,定义x1,x2为函数 指针变量,调用f1函数,调用f2函数,指向函数的指针变量作函数参数:,共 90 页 第 61 页,9.5 指针与二维数组,9.5.1 二维数组的结构 数组的名代表该数组的首地址,并可看成是地址常量,这一规定对二维数组或更高维数组同样适用。 若有定义: float *p, d35; d0,d1,d2 分别是一维数组名,表示一维数组的首地址,p=d0是正确的。,可以把d看成是由3个一维数组组成,即d0,d1,d2,共 90 页 第 62 页,a代表整个二维数组的首地址,即第0行的首地址 a+1是数组a第1行首地址(208) a0,a1,a2是二维数组中三个一维数组的

34、名字(地址),是第0行,第1行,第2行的首地址,即:a0=a+0、a1=a+1、a2=a+2 ai+j是第i行j列的地址 *(ai+j)是该地址存储的值, 即aij 考虑 *(a2+3)=?,假设数组名为a,起始地址设为200,按行优先存放, int a34=1,3,5,7,9,11,13,15,17,19,21,23;则:,9.5.2 二维数组元素及其地址,共 90 页 第 63 页,注意:,ai和*(a+i)无条件等价 a+i、ai、*(a+i)、&ai0均表示第i行首地址; &aij、 ai+j、*(a+i)+j都是第i行j列元素的地址; aij、 *(ai+j)、*(*(a+i)+j)

35、都是第i行j列元素的值;,共 90 页 第 64 页,int i,j; main( ) int *p, a34, b34, c34; printf(“The value of a:n“); for(i=0; i3; i+) for(j=0; j4; j+) scanf(“%d“,ai+j); printf(“The value of b:n“); for(i=0; i3; i+) for(j=0; j4; j+) scanf(“%d“, *(b+i)+j);,例9-11: 将a矩阵与b矩阵相加,计算结果存入c矩阵。,表示a数组第i行第j列元素的地址,表示b数组第i行第j列元素的地址,共 90

36、页 第 65 页,matrix(*a, b0, ,matrix(int *x, int *y, int *z) for(i=0; i3; i+) for(j=0; j4; j+) *(z+i*4+j)=*(x+i*4+j)+ *(y+i*4+j); ,数组元素在内存中按“行优先”的顺序存放,因此可用x+i*4+j表示二维数组各元素的地址,相当于&xij ,*(x+i*4+j)就是取该元素的值。,*a相当于*(a+0),即a0表示a数组第0行第0列元素的地址。 b0表示 b数组第0行第0列元素的地址。 &c00表示 c数组第0行第0列元素的地址。,计算aij在数组中相对位置的计算公式为:i*m+

37、j m为二维数组的列数,共 90 页 第 66 页,例9-12 将矩阵A转置后存放到矩阵B中, 即:bji=aij (下标法),main() int a34,b43,i,j; for(i=0;i3;i+) for(j=0;j4;j+) scanf(“%d“, ,共 90 页 第 67 页,指针法(方法1),main() int a34,b43,i,j,*p,*q; p=,将指针变量p,q指向两数组的开始位置,利用指针p为数组a输入数据,利用指针q输出数组b,这里的指针变量p和q都是用int *p,*q定义的 是指向整型数据的,p+1是指向p所指向的下一个元素。能否使p不是指向整型变量,而是指向

38、一个包含m个元数的一维数组呢?,共 90 页 第 68 页,9.5.3 指向数组的指针变量,1. 定义格式 类型说明符 (*变量名)正整型常量表达式 2. 功能 定义一个名为“变量名”的指针变量,这个指针变量所指的对象是一个有“正整型常量表达式”个元素的一维数组。 例如:int a34,(*p)4=a; 定义p是一个指针变量,它指向包含4个整型元素的一维数组。 p的值就是该一维数组的起始地址。,共 90 页 第 69 页,例9-13:输出二维数组任一行任一列元素的值,main( ) int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p,i,j ; p=a

39、; scanf(“%d,%d”, 输入1,2 运行结果:a12=13,这里的指针变量p是定义为指向整型数据的,aij在数组中的位置用相对于数组起始位置的相对移位量计算,共 90 页 第 70 页,例9-14 输出二维数组任一行任一列元素的值,main( ) int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4,i,j ; p=a; scanf(“%d%d”, 输入1,2 运行结果:a12=13,第i行j列元素的地址为:*(p+i)+j 第i行j列元素的值为:*(*(p+i)+j),这里的指针变量p不是指向整型变量,而是指向一个包含4个整型元素的一维

40、数组。,共 90 页 第 71 页,例9-15 阅读下面程序。 main( ) int i; int *q,(*p)4,a34=2,4,6,8,10,12,14,16,18,20,22,24; q=a0; for(i=1;i=0;i-) printf(“%dt“, *(pi+i); printf(“n“); ,程序运行结果: 2 6 10 14 22 12 2,第i行j列元素的地址为:pi+j 第i行j列元素的值为:*(pi+j),q是定义为指向整型数据的,P指向一个包含4个整型元素的一维数组。,共 90 页 第 72 页,定义一个由 6个指针变量构成的指针数组,数组中 的每个数组元素都是一个

41、指向一个整数的指针变量。,指针数组:数组中的元素均为指针类型。适合用来指向字符串,1.定义形式:,数据类型 * 数组名常量表达式,例如: int *pa6;,2.功能:,9.6 指针数组,共 90 页 第 73 页,3.指针数组的初始化,必须用地址值为指针数组初始化,int a33 = 1,2,3,4,5,6,7,8,9,*pa3; pa0=a0;pa1=a1;pa2=a2;,指针数组*pa3 相当于有三个指针,*pa0,*pa1,*pa2,初始化的结果:,共 90 页 第 74 页,对指针数组中的任意一个pai,移动j个元素,有:,pai+j = ai+j = ,指针与数组的等价性: *(a

42、+i )=*(pa+i )=a i ;,*(pa i +j)=*(a i +j )=*(*(a+i )+j ) =a i j ,指针数组与二维数组是等价的,通过指针数组可以引用二维数组中的元素。,注意: int *p5 与 int (*p)5 不同,共 90 页 第 75 页,字符串数组:数组中的每个元素都是存放字符的数组。 字符串数组的每一行可存放一个字符串。 用赋初值的方式给字符串数组赋值: 直接给字符串数组赋初值 若有定义: char b48= Turbo C, FORTRAN, BASIC, Foxpro; 此定义还可以写成: char b8= Turbo C, FORTRAN, BA

43、SIC, Foxpro; 由于字符串长短不一,定义时应考虑最长的串和结束标志的位置。,9.7 指针与字符串数组,共 90 页 第 76 页,用给字符型指针数组赋初值的方式构成字符串数组 若有定义: char *f4= Turbo C, FORTRAN, BASIC, Foxpro; 此定义还可以写成: char *f= Turbo C, FORTRAN, BASIC, Foxpro; 则数组f中的每个元素都存放着对应的一个字符串的首地址,各字符串依次存入各相应的首地址开始的连续存储单元中。,节省内存空间!,共 90 页 第 77 页,例9-16,#include “stdio.h” main(

44、 ) char *s4=“dog”,“cat” , “pig”, “all animals”; int i; for (i=0; i 4; i+) printf(“%sn”, *(s+i); ,指针数组S各元素的内容是指向各字符串的首地址。,运行结果: dog cat pig all animals,共 90 页 第 78 页,问 题,二维数组的元素与地址 如何使用指针与字符串数组? 指针数组的作用,如何使用? 如何使用指向数组的指针变量访问二维数组? (指向数组的指针变量,所指的对象是一个一维数组,具有M个元素,是有构造的)。,共 90 页 第 79 页,9.8 二级指针,指向指针的指针:

45、指向指针数据的指针变量。通常用于指向字符型指针变量。 说明格式: 类型说明符 * 指针变量名 例如: char * p; 定义指针变量p,用于存储另一个指针变量的地址。,共 90 页 第 80 页,例如:,main( ) char *s =“China”,“Japan”, “English”,”Franch”; char *p; int i; p=s+2; printf(“%sn”, *p); ,*p=*(s+2)=s2存放的是English的首地址,打印p指针内的内容,即指针指向的字符串,共 90 页 第 81 页,9.9 用指针实现内存动态分配,1.动态内存分配的步骤 了解需要多少内存空间

46、 利用C语言提供的动态内存分配函数分配所需要的存储空间; 使指针指向获得的内存空间,以便实施运算或操作; 当使用完毕内存后,释放这一空间。,2.动态内存分配函数 动态存储分配函数:malloc() 原型是:void malloc(unsigned size) 功能:在内存中动态分配一连续空间,其长度为size.申请成功,返回一个指针,否则,返回NULL.,共 90 页 第 82 页,int *p; p=(int *)malloc(n*sizeof(int); 申请能保持n个整型数据的连续内存空间,使p指向该区域。,共 90 页 第 83 页, 计数动态存储分配函数: calloc() 原型是:void *calloc (unsigned n, unsigned size) 功能:在内存中动态存储区分配n个连续空间,并初始化为0,每一空间其长度为size.申请成功,返回一个指针,否则,返回NULL., 动态存储释放函数:free() 原型是:void free(void *ptr) 功能:释放由动态存储分配

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1