收藏 分享(赏)

THE C PROGRAMMING LANGUAGE.ppt

上传人:Facebook 文档编号:3490413 上传时间:2018-11-05 格式:PPT 页数:106 大小:541.50KB
下载 相关 举报
THE C PROGRAMMING LANGUAGE.ppt_第1页
第1页 / 共106页
THE C PROGRAMMING LANGUAGE.ppt_第2页
第2页 / 共106页
THE C PROGRAMMING LANGUAGE.ppt_第3页
第3页 / 共106页
THE C PROGRAMMING LANGUAGE.ppt_第4页
第4页 / 共106页
THE C PROGRAMMING LANGUAGE.ppt_第5页
第5页 / 共106页
点击查看更多>>
资源描述

1、THE C PROGRAMMING LANGUAGE,计算中心- NEU Computer Center 高克宁-gaokening E_mail:,0.本章内容,指针的概念 指针的各种运算 指针传递参数 指针的应用 指针与数组 指针与字符串 指针与函数 指针数组与数组指针 多级指针,0.本章内容,指针是语言的重要概念之一 它使语言比之其它程序设计语言更具特色 深入理解语言特性 掌握语言编程技巧 指针是学习使用语言的难点 指针是C语言的一个重要概念 正确而灵活地使用指针 有效地描述各种复杂的数据结构 动态地分配内存空间 自由地在函数之间传递各种类型的数据 使程序简洁、紧凑,执行效率高 指针是C

2、提供的一种数据结构 属于简单数据类型 它的意义和作用明显又不同于一般的数据类型,1.预备知识,直接和间接的含义内存 即内部存储器,是由内存单元组成 特点 存储单元是线性连续的 存储单元的最小单位为字节,1.预备知识,内存 计算机的内存中的每一个字节都有一个编号 所有的内存单元都要统一进行“编号” 这个编号就是该字节在整个内存中的“地址” 所有的内存单元都要有地址 每一内存单元具有唯一的内存地址 系统为每一个已定义的变量分配一定存储空间 使变量名与内存的一个地址相对应 通过地址我们就能够访问该地址所标识的存储单元 程序处理过程 需要根据地址取出变量所对应的内存单元中存放的值 参与计算/操作 处理

3、结果存入相应的变量名所对应的内存单元,1.预备知识,计算机的寻址方式 直接寻址间接寻址,数据 数据,内存,地址 1003 1004 1008 100C,B单元,内存,地址 1050 1051 3020 3021 ,地 址,数据 数据,A单元,1.预备知识,C语言如何处理? 高级语言中的变量具有三个属性 变量的名 变量的值 变量的地址 编程者使用c程序的一个变量 定义变量的数据类型 数据类型决定了一个变量在内存中所占用的存储空间的大小 变量在内存中总是占用几个连续的字节 定义变量名 语言的编译系统会根据变量的数据类型为该变量分配内存单元 确定变量的地址 变量的地址就是为变量分配的内存单元的起始编

4、号 就可以通过变量名对内存中变量对应的地址进行操作,1.预备知识,1.预备知识,C语言如何处理? 直接访问 通过变量名访问数据的方式称为“直接访问“ 例如 printf(“%d“, n); /* 通过变量名访问变量n */ 间接访问 如果将变量n的地址存放在另一个变量pn中,通过访问变量pn,间接达到访问变量i的目的,这种方式称为变量的“间接访问“ 在C语言中,间接寻址方式访问内存是通过指针变量实现的 指针变量通过直接寻址方式访问获得的是一个地址值 在该地址起始的一个存储单元中存放程序需要的数据,2.指针变量,定义 用于指向其他变量的变量 指针变量是一个变量 和普通变量一样占用一定的存储空间

5、该存储空间存放的是一个地址值而不是普通的数据值 指针变量是一个地址变量 指针变量的值是一个内存单元的地址 它指向另一个变量的值 指针就是地址 当将变量的地址存入指针变量后,就说这个指针指向了该变量 指针变量只能存放某一数据类型的变量 问题? 变量的类型和指向变量的类型之间的区别?,2.指针变量,指针变量的声明 指针变量与一般的变量的区别 格式 *指针变量名; 说明 数据类型表示指针所指向的数据的数据类型 提示:不是指针变量的数据类型 *是指针的标志,表示它后面的变量名是指针类型 例 int *i_p;/*定义了指针变量i_p ,指向的对象类型为整型*/char *cp;/*定义了指针变量cp,

6、 指向的对象类型为字符型*/struct student int No ;char name10 ;float score;*p_stud; /* 定义了指针变量p_stud,指向的对象类型为结构体student类型*/,2.指针变量,指针变量的声明 提示 声明语句的*只能用于指针变量 这种表示方式说明被声明的变量是一个指针 *不针对声明语句中的所有变量 每一个指针都必须在其名字前面有一个前缀*声明 例如:int *pt1,pt2; pt2为整型变量而不是整型指针变量 指针变量名是pt1而不是*pt1 指针变量只能指向定义时规定的类型变量 只有同一数据类型的地 址才能存放在指向该类型变量的指针

7、变量中 例如: int *ip;/*ip指针变量只能存放整型变量的地址*/,2.指针变量,指针变量的声明 提示 在定义指针时可以用void将指针定义为空类型 不指定指针指向一个确定的类型 区分“值”与“内容”的含义 例如 整型变量是内容为整型数值的变量 整型指针变量是存放整型变量地址的变量 在引用指针变量前必须首先让指针指向一个变量 这一点非常重要 定义指针变量后,并未确定该变量指向何处,该变量的值是不确定的,2.指针变量,指针变量初始化 在使用指针变量时,要首先对指针变量进行初始化,让指针变量指向一个具体的变量 初始化的方式 使用赋值语句 例 int i, *pi; /* 说明指针变量pa和

8、变量a */ pi=会出现什么问题?,2.指针变量,指针变量初始化 在使用指针变量时,要首先对指针变量进行初始化,让指针变量指向一个具体的变量 初始化的方式 给指针变量赋空值(赋值为符号常量NULL ) 例 p=NULL;/*表示指针p为空,没有指向任何对象*/ 一般情况下给没有初始值的指针变量赋值为NULL 实际上,NULL是整数0,系统保证0单元不存储任何数据的值(地址)NULL是头文件以及其它几个头文件中定义的符号常量,2.指针变量,指针变量初始化 提示 在使用指针之前一定要对其进行初始化 否则程序不知道指向何处 系统在执行程序时会给出如下的信息 run-time error R6001

9、null pointer assigment 或者引起更严重的错误系统崩溃 对未使用的指针应该赋以空值NULL 表明它未指向任何地方 这并不是对指针的初始化 只是 表示该指针未被使用而已,2.指针变量,指针变量初始化 提示 一个指针变量赋空值与不赋值是完全不同的概念 前者是有不指向任何变量的地址 后者是一个不确定的随机值 这时指针可能指向一个事先未指定的数据 利用空指针可以简化程序代码、提高效率 指针变量应具有无符号整型类型的值 存放的是地址 由于地址本身的特征,不能将一个整型值赋给一个指针变量。同样也不能将指针变量的值赋给一个整型变量例如:int *p;p=2000;(非法),2.指针变量,

10、指针变量初始化 提示 用void将指针定义为空类型 即不指定指针指向一个确定的类型 例如:void *p;/*表示指针变量P不指向一个确定的类型*/ 它的作用仅用来存放一个地址 作用 任何类型的指针都可以赋给指向void类型的指针 指向void类型的指针也可以赋给任何类型的指针 但是:不能复引用void*类型的指针 编译器不能根据类型确定它引用的字节数 常见错误 将一种类型的指针赋给另一种类型的指针,而这两种指针都不是void*类型 复引用void*类型指针,【例】定义指针变量void *p2;int *p1,i=5;p1=&i;p2=p1;演示91。C,3.指针变量,指针变量的运算 语言提供

11、的指针运算 取地址运算( p=&x /* &表示取的地址,将变量地址赋给指针变量p */ 提示 &是一个单目运算符,它返回变量的地址 &的操作数必须是一个变量 取地址运算符“&”是取操作对象的地址而不是其值,3.指针变量,指针变量的运算 语言提供的指针运算 取内容运算(*) 运算对象必须是指针(该指针所指向的对象可以是任意类型) 作用是取指针所指向变量的内容。*也称为“间接引用运算符”或“指针的复引用”例如 a=*prt; /*表示指针 prt所指向变量的内容赋a*/ int a=3, *p, x; pa= /* *pa表示取指针变量pa所指单元的内容,即变量a的值,则x=3 */ 提示 被复

12、引用的指针没有被正确地初始化或没有指向具体的内存单元都会导致致命的执行错误或意外地修改重要的数据 如果修改了数据,程序虽然能够完成运行,但是将提供不正确的结果,3.指针变量,指针变量的引用 当指针变量定义和赋值之后,引用变量的方式 用变量名直接引用 例如 scanf(“%d”, /* 通过 * 运算符实现间接访问 */ ,3.指针变量,指针变量的引用 例:用指针变量进行输入输出,main() int *p,m;scanf(“%d”,&m);p=&m;printf(“%d”,*p); 演示 921。C,main() int *p,m;p=&m;scanf(“%d”, p );printf(“%d

13、”, m ); 演示922。C,运行结果完全一样。请思考一下若将程序修改为如下形式: main()int *p,m; scanf(“%d”, p );p=&m;printf(“%d”, m ); 会产生什么结果? 演示923。C,#include main() int a, *aptr;a=7;aptr= 演示94。C,3.指针变量,指针变量的引用 例:本程序演示了指针运算符的用法,【例】main()int *p1,*p2;int i=10,j=20;p1=&i;p2=&j;p2=p1;printf(“*p1=%d;*p2=%dn” ,*p1,*p2);printf(“i=%d;j=%dn”

14、,i,j);printf(“p1=%p,p2=%pn”,p1,p2); 演示95.C,本题中若*p2=*p1? 将p1指向变量的值传递给* p2的内存单元。即j的内存单元中,P2和p1中存放的地址并不发生变化。,结果为: *p1=10;*p2=10i=10;j=20,结果:*p1=10;*p2=10i=10;j=10,3.指针变量,3.指针变量,指针变量的提示 取内容运算符*p与定义指针变量时使用的*p含义不同 定义时的*p表示的是一个指针变量,该变量指向一个整型变量的地址 取内容运算符*p则表示取指针变量的内容,即另一个变量值 对指针的引用需要*和& &用于求任一类型变量的指针,求出的指针具

15、有对应的类型 *和指针一起使用时被认为是同类型的一个变量 可以参与该类型变量的一切运算 *和&是一对功能恰好相反的运算操作符 在实际应用中, 应特别注意&和*的操作对象 &的操作对象是一个“变量” *的操作对象是一个“地址”,THE C PROGRAMMING LANGUAGE,计算中心- NEU Computer Center 高克宁-gaokening E_mail:,0.本章内容,指针的概念 指针的应用 指针与一维数组 指针与字符串 指针与函数 指针与二维数组 数组指针 指针数组与多级指针,4.指针与数组,指针和数组紧密联系 对数组元素的访问可以通过指针和借助数组元素下标的方法实现 凡是

16、由数组下标完成的操作皆可用指针来实现 “下标方式“访问数组元素 通过数组的下标唯一确定了某个数组元素在数组中的顺序和存储地址 例如:int a5 = 1, 2, 3, 4, 5, x x=a0; /* 通过下标将第1个元素的值赋给x=1 */,4.指针与数组,指针和数组紧密联系 对数组元素的访问可以通过指针和借助数组元素下标的方法实现 凡是由数组下标完成的操作皆可用指针来实现 指针最常见的一种用途就是指向数组元素 当一个指针指向数组后,就可以灵活快速地处理数组元素,从而体现出指针的优点 “指针方式”访问数组中的元素 一个数组(/数组元素)有相应的地址,可以将数组的起始地址或某一个数组元素的地址

17、放到一个指针变量中 数组的指针就是数组的起始地址(数组名),既数组第一个元素的地址(&数组名0) 数组元素的指针就是该数组元素的地址,4.指针与数组,指针和数组紧密联系 分析程序语言中规定 数组第1个(下标为0)元素的地址就是数组的首地址 数组名代表的就是数组的首地址 数组名代表的一个地址常量,是数组的首地址 它不同于指针变量,#include main ( ) int a = 1, 2, 3, 4, 5 ; int x, y, *pt,*p2; pt = ,4.指针与数组,指针和数组紧密联系 语言中规定说明 当指针指向数组首地址时(pt=ary或pt=&ary0时) 指针可以向数组一样使用

18、提示 对数组元素的访问,下标方式和指针方式是等价的 从语言系统内部处理机制上讲,指针方式效率高 指针方式不如下标方式直观 下标方式可以直截了当地看出要访问的是数组中的哪个元素 指向数组的指针变量,进行运算以后,指针变量的值改变了,其当前指向的是哪一个数组元素不再是一目了然,4.指针与数组,指针和数组的可替代性 C语言中的指针和数组几乎可以互换 指针可以用来完成涉及数组下标的操作 例如:int a10;int *p; 若p=&a0;或 p=a;则p就指向了数组a的首址 当p指向了一维数组a,指针对数组元素可以表示: p+n与a+n( n (偏移量)的取值为09 )表示数组元素 an的地址,既&a

19、n *(p+n)和*(a+n) 表示数组元素an ( n的取值为09 ) 指向数组的指针变量也可以用数组的下标形式pn,其效果相当于*(p+n),等价于an,4.指针与数组,指针和数组的可替代性 例,#includevoid strcopy1(char str,const char *);void strcopy2(char str,const char *); main( )char str110,*str2=“teacher”;char str310,*str4=“boys and girls”;strcopy1 (str1,str2);printf(“str1=%sn”,str1);st

20、rcopy2(str3,str4);printf(“str3=%sn”,str3); pt4。c,这两个函数都将一 个字符串(可能是 一个字符数组)拷 贝到一个字符数组 中,比较这两个函 数原型可以发现其 形式是相同的,虽 然这两个函数完成 同样的功能,但是 他们的实现过程是 不同的。,/* 采用数组表示法将s2拷贝到s1.*/ void strcopy1(char *s1,const char *s2) int i;for(i=0;s1i=s2i;i+); /*函数体中没有任何动作*/,/* 采用指针表示法将s2拷贝到s1.*/void strcopy2(char *s1,const cha

21、r *s2)for( ;*s1=*s2;s1+,s2+); /*函数体中没有任何动作*/,4.指针与数组,4.指针与数组,指针和数组的可替代性 数组的表示法 数组/下标 指针/偏移量 利用*p、*(p+1)、来代表数组a0、a1 数组/偏移量 对数组的引用以*a、*(a+ 1)、代替a0、a9指针/下标 表达式p1引用了数组元素a1,【例1 】采用指针/偏移量表示的地址法输入输出数组元素。 main() int n,a10,*pa=a; /*定义时对指针变量初始化*/for (n=0;n=9;n+)scanf(“%d”,pa+n);for(n=0;n=9;n+)printf(“%d”,*(pa

22、+n);printf(“n”); pt31。c,【例2】采用表示的数组/偏移量表示的地址法输入输出数组元素。main() int n,a10,*pa=a; /*定义时对指针变量初始化*/for (n=0;n=9;n+)scanf(“%d”,a+n);for(n=0;n=9;n+)printf(“%d”,*(a+n);printf(“n”); pt32。c,4.指针与数组,【例3】采用指针/下标法输入输出数组元素。main() int n,a10,*pa=a;for (n=0;n=9;n+)scanf(“%d”, pt33。c,【例4】采用数组/下标法输入输出数组元素。main() int n,

23、a10;for (n=0;n=9;n+)scanf(“%d”, pt34。c,4.指针与数组,main() int ary4=2,4,8,16;int *iprt,i;iprt=ary;/*按正序输出数组元素*/for (i=0;i=0;i- -)printf(“%d” ,*( iprt+i );prntf(“n”); pt6。c,4.指针与数组,指针和数组的可替代性 例:将一个数组按正向、逆向输出,4.指针与数组,指针和数组的关系 提示 指针变量与数组的区别 指针变量是地址变量,数组名是地址常量 指针变量的内容可以在程序运行过程中被修改,数组名一旦被声明,它的值在整个程序运行中是不能改变 (

24、p+1)和 *(a+ 1)都可以表示数组元素a1, 两者并不能完全等价 对 数组a只能引用,不能修改 实际上就是指针与指针变量的区别 对于数组名,虽然可以使用它得到其元素的值,但它仅表示数组的首地址,不能将其改变 例如:for (n=0;n=9;n+) scanf(“%d”,pa+); /*pa+是允许的*/;for (n=0;n=9;n+)scanf(“%d”,a+); /*a+则是非法*/ 试图用指针算术运算修改数组名是一种语法错误,4.指针与数组,指针和数组的关系 提示 指针变量与数组的区别 指针变量可以改变其自身的值,应该特别注意其的当前值例如:对上例程序中的a和pa,若有程序段:pa

25、=a;printf(”%dn”,*pa);pa+;printf(“%dn”,*pa); 第一个printf输出的是a0的值 第二个printf则输出的是a1的值 指向数组的指针在数组处理时不要越界 由于C语言不检查数组越界,对一个仅有10个元素的数组a引用第11个元素a10时系统仍按 *(a+10)处理,发生错误,4.指针与数组,指针的运算 指针的运算旨在针对数组进行 指针的运算 指针与正整数的加减运算 两个指针的减法运算 两个指针的关系运算 禁止的运算 指针做乘除法运算 指针进行位操作运算 指针与浮点型数据运算 两个指针相加没有意义 指针运算的结果依赖于指针所指向对象的大小 指向对象的数据类

26、型,4.指针与数组,指针的运算 指针与正整数的加减运算 该指针下移或上移整型值所指定个数的存储单元的内存地址 存储单元的大小就是该指针的数据类型所需要的内存的大小 p+(-)i*sizeof(type) 对指针的加/减(整数)操作运算在用指针访问数组元素是经常用到 例如:当指针p指向数组中的元素时,n为一个正整数 表达式:p+n表示指针p所指向当前元素之后的第n个元素 而表达式:p-n表示指针p所指向当前元素之前的第n个元素,4.指针与数组,指针的运算 指针与正整数的加减运算 例如: int a10 ,*p; p=a;(或p=&a0 ;),4.指针与数组,指针的运算 指针与正整数的加减运算 自

27、增/自减 指针的自增(+)/自减(-)运算分别表示将指针移动到下一个/上一个存储单元并指向新的数据 p+的含义 指针加,指向数组中的下一个元素 p-的含义 指针减,指向数组中的前一个元素,main() int *prt;int arrary=2,4,6,8,10;prt=array;prt+=3; prt-;prt-=2;prt+; 96。C,4.指针与数组,指针的运算 提示 例如:int a5,*pa:pa=a; pa+; /*使pa指向下一个元素a1;*/ *pa; /*指针所指向的数组名(或变量或数组元素)*/ *pa+; /*先取出pa所指向元素的值 (*pa),后pa+1送 与pa。

28、由于+与*的优先级相同,自右向左的结 合方向,所以它等价于*(pa+);*/ *(+pa);/*先令pa加1,再取pa指向的值*/ (*pa)+; /*pa所指向的元素的值加1,即(a0)+*/ 对于-运算同上,4.指针与数组,指针的运算 两个指针的减法运算 减法运算的含义 当两个指针指向同一数组中的元素时 p-q表示计算两个指针相差的存储单元个数 计算公式为提示 只有当两个指针指向同一数组中的元素时才可进行两个指针的减法运算,prt1-prt2=(prt1的值-prt2的值)/指针的数据类型的所占字节数,4.指针与数组,指针的运算 两个指针的减法运算 例:计算一个字符串的长度(不用strle

29、n函数),#includemain() int len;char a80 ;gets(a);puts(a);len=lenth(a);printf(“%dn” ,len);,lenth(char *p) char *q=p; while (*q!=0) q+;return(q-p); 演示ptd.c,4.指针与数组,指针的运算 两个指针的关系运算 比较两个指针的含义 比较两个存储单元的地址(相对位置) 除非两个指针指向同一数组,否则这种比较是没有意义的 比较两个指向同一数组的指针反映的是指针所指向元素的先后顺序 任何指针p与NULL进行“p=NULL”或“p!=NULL”运算均有意义 “p=N

30、ULL”是当指针p为空时成立 “p!=NULL”的含义是当p不为空时成立 例如:有两个指针ptr1和ptr2 if (ptr1ptr2) printf(“ptr1 points to higher memory than ptr2n”);,例1:以下程序的输出结果是:#includemain( ) int x =10,20,30,40,50,60;int *p=x;*(p+4)+=6;printf(“%d,%d”,8,*(p+4);,A) 10,46 B) 0,56 C) 10,56 D) 50,46,例2:已知:int a10=1,2,3,4,5,6,7,8,9,10;int *p=a;则不

31、能表示数组a中元素的表达式是:,A)*p B)a10C)*a D)ap-a,4.指针与数组,4.指针与数组,指针的运算 提示 数组名代表数组的首地址 固定的,不允许修改的 不能对数组名采用 +/-操作 指针的算术运算除了应用于数组外没有什么意义 除数组外,不能认为两个数据类型相同的变量在内存中是连续存储的 指针的运算与其基类型有关 通常情况下允许一个指针或多个指针指向同一个目标 常见错误 对不指向数组的指针进行算术运算 将不是指向同一个数组的两个指针相减或比较,这是没有意义的 指针的运算结果超出的数组的范围,4.指针与数组,小测试,1. 以下对指针变量的操作中,不正确的是A、int a, *p

32、, *q; p=q=,2. 若有以下语句,则对x数组元素引用不正确的是int x =1, 2, 3, 4, 5, 6, *ptr;ptr=x;A、*(-ptr) B、*(ptr-) C、*(ptr+) D、*(+ptr),3. 若有说明语句:int a23, m, n; 且0m1,0n2,则以下对数组元素的正确引用形式是A、am+n B、(a+m)n C、*(a+m)+n D、*(*(a+m)+m),4.指针与数组,小测试,4. 若要对变量a进行- -运算,则a应具有的说明是A、int p3; int *a=p;B、int k; int *a=,5. 若有定义:int (*p)3;,则以下叙述

33、正确的是A、p是一个指针数组名B、p是一个指针,它可以指向一个一维数组中的任意元素C、p是一个指针,它可以指向一个含有3个整型元素的一维数组D、(*p)3等价于*p3,5.指针与字符串,可以通过字符数组和字符型指针处理字符串 例如: 字符数组实现的方式char ch =“this is a book!” ; printf (“%sn” ,ch); 对字符数组初始化 ch是字符数组 它存放了一个字符串 字符指针实现的方式char *ch=“this is a book!” ;printf (“%sn” ,ch); 是对字符指针初始化 *ch是字符指针 它指向的是一个字符串常量的首地址,即指向字符

34、串的首地址,5.指针与字符串,可以通过字符数组和字符型指针处理字符串 字符指针与字符数组区别 char *ch字符指针是一个变量 指向字符串的第一个字符 可以改变字符指针使它指向不同的字符串 不能改变字符指针所指的字符串常量的内容 char ch 是一个字符数组 一个足以存放字符串和空字符0的一维数组 可以改变数组中保存的内容 数组名 ch是一个不可改变的常量 C语言规定 一个指针类型的变量如果指向对象为字符型 可以对其赋值(或初始化)字符串常量 此时字符指针指向的就是用来保存字符串的字符数组的首地址,5.指针与字符串,可以通过字符数组和字符型指针处理字符串 C语言规定 一个指针类型的变量如果

35、指向对象为字符型 可以对其赋值(或初始化)字符串常量 此时字符指针指向的就是用来保存字符串的字符数组的首地址定义应用 可以使用字符指针指向一个字符类型的数据 可以使用字符指针访问字符串常量(另一种方法为字符数组) 将“good”赋予指针p并不是将字符串的字符赋予p,是将“good”在内存中的存储区的起始地址赋给p,char *p;,main( ) char *pc;char ch; pc=&ch;scanf(“%c” ,pc);printf(“%c” ,ch); ,char *p;p=“good” ;,5.指针与字符串,字符指针 应用 例如 p+1作首地址;输出结果为bc 提示 赋值时,字符串

36、的结束标志0是系统自动增加的 在输出或处理字符串指针变量和由字符数组组成的字符串时只要指出指针变量或字符数组的名字 对于其它类型的数组,不能只使用数组名,输出或处理全部元素 使用指针编写的字符串处理程序比使用数组方式处理字符串的程序更简洁、更方便 在C语言中,大量使用指针对字符串进行各种处理 在处理字符串的函数中,一般都使用字符指针作为形参 在函数之间通过指针传递整个数组,在被调用函数的内部就可以用指针方式访问数组中的元素,5.指针与字符串,指针与字符串的应用 例:字符串连接的一个程序 说明 在处理字符串时(包括它作为函数参数使用时),只需要指定其变量名,无须指出字符串的长度 对字符串str,

37、若写成*str则变成了该字符串的第一个字符,表达式*(str+i)则是表示该字符串的第i+1个字符,#includemain() char *str1=“People” ;char *str2=“teacher”;char *str3=“n”;strcat(str1,str2);strcat (str1,str3);printf(“%sn”,str1); 演示ptf。c,main()char *str=“A string!n”;printf(“%s”,str); /*整个字符串操作*/for(;*str!=0;) printf(“%c”,*(str+); /*单个字符操作*/ ptj。c,5.

38、指针与字符串,指针与字符串的应用 例:设计程序,将两个字符串连接起来 不要用strcat函数,#include main() char s180,s280 ;printf(“n input string1:”);gets(s1);printf(“n input string2:”);gets(s2);stringcat(s1,s2);printf(“n new string:%s”,s1);,stringcat(char *s1,char *s2) while (*s1!=0)s1+;while (*s2!=0) *s1=*s2;s1+;s2+;*s1=0; ptk。c,5.指针与字符串,指针

39、与字符串的应用 例:编写程序判定一个字符在一个字符串中出现的次数,如果该字符不出现则返回0值 算法 从头开始扫描字符串的每一个字符 若当前字符等于字符串中的字符时,次数计数器加1 直到字符串中的所有字符比较完成,#include main()char *str,c;printf(“enter a string:n”);gets(str);printf(“enter a char:n”); c=getchar();printf(“counts:%dn” ,char_count(str,c);int char_count(char *string,char letter) int count=0;

40、while (*string)if (*string+= =letter)count+;return(count); ptm。c,5.指针与字符串,5.指针与字符串,小测试,1. 以下能正确读入字符串的程序段是A、char *p; scanf(“%s“, p);B、char str10; scanf(“%s“, ,2. 以下运算正确的程序段是A、char str1=“12345“, str2=“abcdef“;strcpy(str1, str2);B、char str10, *st=“abcde“; strcat(str, st); C、char *st1=“12345“, *st2=“abc

41、de“;strcat(st1,st2);D、char str10=“, *st=“abcde“; strcat(str, st);,5.指针与字符串,小测试,3.下面程序段的运行结果是char str =“xyz“, *p=str;printf(“%dn“, *(p+3) );A、字符z的地址 B、0C、字符z的ASCII码 D、字符z,4.以下程序段的运行结果是char a =“program“, *p;p=a; while (*p!=g) printf(“%c“, *p-32); p+; A、PROgram B、PROGRAMC、PRO D、proGRAM,6.指针与函数,函数与指针之间有

42、着密切的关系 包含三种含义 指针作为函数的参数 函数的返回值为指针 指向函数的指针,6.指针与函数,指针作为函数的参数 调用函数并希望改变参数的值时,指针做函数参数非常实用 按址传递 当函数要求能够修改调用函数中的一个或多个值,或能够传递指向大型数据对象的地址以避免开销很大的传值调用 通过变量的地址就可以通过地址间接访问变量的数值 指针是变量的地址 指针作函数的参数就是在函数间传递变量的地址 函数间传递的不再是变量中的数据,而是变量的地址 变量的地址在调用函数时作为实参,被调用函数使用指针变量作为形参接收传递的地址,6.指针与函数,指针作为函数的参数 要求 在调用函数时以地址做参数传递 当将变

43、量的地址传递给被调函数后,在调用函数的函数体中采用间接引用运算符*修改内存单元中的该变量的值 实参的数据类型要与作为形参的指针所指的对象的数据类型一致 如果是变量的值需要修改,则在变量前面使用&来实现变量的地址 如果是数组的内容需要修改,则直接使用数组名 常见的错误 在需要复引用(*)一个指针来获取指针所指向的值时没有复引用该指针,6.指针与函数,指针作为函数的参数 典型例题:比较变量与指针变量的传递方式 变量传递,运行结果:x1=100,x2=200x1=100,x2=200 形参p1与p2的单元值发生交换与实参x1和x2无关。,#include void swap(int i, int j

44、) int temp;temp=i; i=j; j=temp; /*exchange*/ void main() int a,b;a=100; b=200;printf(“%d ,%dn“, a, b);swap(a,b);printf(“%d ,%dn“, a, b); /*main*/,6.指针与函数,#include void swap(int i, int j) int temp;temp=i;i=j;j=temp; /*exchange*/ void main() int a,b;a=100;b=200;printf(“%d ,%dn“, a, b);swap(a,b);printf

45、(“%d ,%dn“, a, b); /*main*/,运行结果:x1=100,x2=200x1=100,x2=200 形参p1与p2的单元值发生交换与实参x1和x2无关。,6.指针与函数,指针作为函数的参数 典型例题:比较变量与指针变量的传递方式 指针传递,#include void swap(int *i, int *j) int temp;temp= *i; *i = *j; *j = temp; /*exchange*/ void main() int a,b;a=100; b=200;printf(“%d, %dn“,a,b);swap( /*main*/,6.指针与函数,指针作为参

46、数时并未改变实参的值 而是改变了所指向单元中的内容,#include void swap(int *i, int *j) int temp;temp= *i; *i = *j; *j = temp; /*exchange*/ void main() int a,b;a=100; b=200;printf(“%d, %dn“,a,b);swap( /*main*/,6.指针与函数,指针作为函数的参数 在主调函数中,传递的是两个变量的地址 并没有试图改变调用函数时的参数,而只是利用了指针变量的特性,改变了指针变量所指向单元的内容 swap根据得到的两个变量的地址将指针指向的变量中的数据进行调换,s

47、wap就是在要调换数据的两个实际变量的存储单元上进行的数据交换 交换的结果自然带回到主调函数main中,6.指针与函数,指针作为函数的参数 问题? 如果将例题中的swap()函数写出如下的形式,那么主调函数中的实参a和b的值能否改变呢?,swap(p1,p2)int *p1,*p2; int *temp;temp=p1;p1=p2;p2=temp; void main() int a,b;a=100;b=200;printf(“%d, %dn“,a,b);swap( /*main*/,6.指针与函数,指针作为函数的参数 提示 地址作为函数的参数必须定义一个接收地址的指针参数(形参为指针类型) 例如: void max(int *mptr,int *nptr) 在使用函数之前先检查一下函数原型,确定该函数是否能够修改传递给它的值 函数原型中没有必要指出指针名,但是要指出指针类型 例如:函数原型void max(int *,int *); 用指针作为函数参数并在调用时传递地址作为实参这样可以改变主调函数中变量的值 不能通过改变指针形参的值而使指针实参改变 因为C语言中参数传递具有“单向性”,

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

当前位置:首页 > 中等教育 > 小学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报