收藏 分享(赏)

c语言第五章 指针.ppt

上传人:wjmd390 文档编号:8116495 上传时间:2019-06-09 格式:PPT 页数:55 大小:310KB
下载 相关 举报
c语言第五章 指针.ppt_第1页
第1页 / 共55页
c语言第五章 指针.ppt_第2页
第2页 / 共55页
c语言第五章 指针.ppt_第3页
第3页 / 共55页
c语言第五章 指针.ppt_第4页
第4页 / 共55页
c语言第五章 指针.ppt_第5页
第5页 / 共55页
点击查看更多>>
资源描述

1、C语言程序设计,1,C语言程序设计,第五章 指针,C语言程序设计,2,第五章 指针,教学目标 指针的基本概念 指针变量的定义与初始化 指针运算符 在数组、字符串与结构中使用指针,C语言程序设计,3,六、指针,内容要点 指针的基本概念 指针的定义和初始化 指针赋值、间接访问运算符 指针与数组 用数组名给指针赋值 指针数组,字符串指针与结构指针与结构数组,C语言程序设计,4,指针是C语言中的一个重要概念。掌握指针的用法,可使程序简洁、高效、灵活,但并不难学。为了了解什么是指针,先看一个小故事 地下工作者阿金接到上级指令,要去寻找打开密电码的密钥,这是一个整数。几经周折,才探知如下线索:密钥藏在一栋

2、三年前就被贴上封条的小楼中。一个风雨交加的夜晚,阿金潜入了小楼,房间很多,不知该进哪一间,正在一筹莫展之际,忽然走廊上的电话铃声响起。艺高人胆大,阿金毫不迟疑,抓起听筒,只听一个陌生人说:“去打开211房间,那里有线索”。阿金疾步上楼,打开211房间,用电筒一照,只见桌上赫然6个大字:地址1000。阿金眼睛一亮,迅速找到1000房间,取出重要数据66,完成了任务。,5.1 指针的概念,C语言程序设计,5,我们画出下图,211,1000,P,说明: 1、数据藏在一个内存地址单元中,地址是1000。 2、地址1000又由P单元所指认,P单元的地址为211。 3、66的直接地址是1000;66的间接

3、地址是211;211中存的是直接地址1000。 4、称P为指针变量,1000是指针变量的值,实际上是有用数据藏在存储器中的地址。,C语言程序设计,6,指针变量用来存放另一变量地址的变量 变量的指针就是变量的地址。 1、指针的概念 指针是一种特殊的变量,特殊性表现在类型和值上。 从变量讲,指针也具有变量的三个要素: (1)变量名,这与一般变量取名相同,由英文字符开始。 (2)指针变量的类型,是指针所指向的变量的类型,而不是自身的类型。 (3)指针的值是某个变量的内存地址。 从上面的概念可知,指针本身类型是int型,因为任何内存地址都是整型的。但是指针变量的类型却定义成它所指向的变量的类型。,C语

4、言程序设计,7,2、指针的定义与初始化 例如: int *p, *q; / 定义p,q为指向整数类型变量的指针 float *point; / 定义point为指向float型变量的指针 double *pd; / 定义pd为指向double型变量的指针 int (*pa)10;/ 定义pa为指向int型数组的指针 int *qq; / 定义qq为指向int型指针的指针 还有指向结构、联合的指针,后面再介绍,C语言程序设计,8,2、指针的定义与初始化,int *p=NULL; 定义了一个名为p的指针,该指针指向一个整数类型的变量,且被初始化为空指针(NULL) 一时指针被定义,系统会为p分配内

5、存单元,该单元的地址可以用&p表示。 在p中赋入一个符号化的常量NULL,称为将指针p初始化0 。 NULL定义在iostream.h中,其值为0,0是唯一可赋给指针变量的整型值。 在定义时让指针初始化为NULL,可防止其指向未知的内存区域,以避免产生难以预料的错误。这是一个好习惯。,C语言程序设计,9,3、指针赋值 例 int akey; / 定义一个整型变量akey int *p,*q; / 定义p,q为指向整型变量的指针变量 akey=66; / 将66赋给akey p = / 将p的值赋给q,见图2,C语言程序设计,10,q = p; / 将p的值赋给q,见图2,C语言程序设计,11,

6、#include /预编译命令 void main() /主函数 /函数体开始int a5=0,1,2,3,4;/定义数组,赋初值int *p1,*p2; /定义指针变量p1=/输出a1和a2的值 /函数体结束,C语言程序设计,12,说明:见图,&a1,&a2,&p1,&p2,p1,p2,p1和p2分别指向a1,a2,这里 & 取地址运算符 * 指针运算符(间接访问运算符) *p1 间接访问p1所指向的内存单元,当然是输出a1的值 *p2 间接访问p2所指向的内存单元,当然是输出a2的值,C语言程序设计,13,#include /预编译命令 void main() /主函数 /函数体开始int

7、 akey,b; /定义整型变量int *p=NULL,*q=NULL; /定义指针变量akey=66; /赋值给变量akeyp=/输出b的值 /函数体结束,4、在赋值语句中使用间接访问运算符,C语言程序设计,14,C语言程序设计,15,有关指针变量的说明, 一个指针变量可以指向任何一个同类型的普通变量;但是, 在某一个时刻,它只能指向某一个同类型的变量, 让指针变量指向某个同类型普通变量的方法是:把该普通 变量的地址保存到指针变量中。, 必须对指针变量进行了正确合法的初始化后,才能使用该 指针变量访问它所指向的内存单元。,int *pa, *pb, a, b; pa = ,int *pa,

8、*pb, a, b; *pa = 100; 或 printf(“*pa=%dn”, *pa);,C语言程序设计,16,有关指针变量的说明, 即使对指针变量进行了正确合法的初始化后,也只能用该 指针变量访问合法的允许访问的内存单元。不能使用该指针 变量去随意访问其它不确定的内存单元,否则,结果是不可 预料的。,int *pa, *pb, a, b; pa = ,正确安全使用指针变量,错误使用指针变量,错误使用指针变量而且可能很危险,C语言程序设计,17,有关运算符*和&的说明, 假设有 int a, *pa; pa = 则:&*pa 相当于 &a,因为 *pa 就相当于 a*&a 相当于 *pa

9、,因为 &a 就相当于 pa(*pa) + 相当于 (a +),pa,*(pa +) :得到100,pa自增 (*pa) + :得到101,pa所指 向的单元变成101,而pa不变, 注意 (*pa) + 和 *pa + 的区别 由于 + 和 * 为同一运算级别,则根据结合性, *pa + 相当于*(pa +) ,与(*pa) +是完全不同的。 *(pa +) :先得到pa当前指向的单元的值,再使pa自增 (*pa) + :是pa所指向的单元的值自增,C语言程序设计,18,#include /预编译命令5_3.cpp void main() /主函数 /函数体开始int a5=1,3,5,7,

10、9;/定义数组,赋初值int *p=NULL; /定义指针变量int i; /定义整型变量p=a; /赋值给指针变量,让p指向a数组for(i=0;i5;i=i+1) /循环体开始 cout“a“i“=“*pendl;/输出a数组元素的值p=p+1; /指针变量加1 /循环体结束 /函数体结束,5.2 指针与数组 5.2.1 用指针名为数组赋值,C语言程序设计,19,说明 (1) p=a; 这里数组名作为数组的起始地址,即a0的地址。 因此 p=a 等效于 p=,p,p+1,p+2,p,p+1,p+2,等效,C语言程序设计,20,#include / 预编译命令 5_4.cpp void ma

11、in() / 主函数 / 函数体开始int a5=1,3,5,7,9; / 定义数组,赋初值int *p=NULL; / 定义指针变量int i=0; / 定义整型变量,赋初值for(p=a;pa+5;p=p+1) / 让p指向a数组 / 循环体开始 cout“a“i“=“*pendl;/ 输出a数组元素的值i=i+1; / 让i加1 / 循环体结束 / 函数体结束,做下面的实验,C语言程序设计,21,#include / 5_5.cpp void main() char *p; / 定义指向字符类型的指针变量pchar s = “abcdefgh”;/ 定义字符数组,并赋值p=s; / 数组

12、名是一个常量指针,/ 它指向该数组首地址while (*p != 0) / 当p所指向的元素不为0时p=p+1; / 让指针加1printf(“字串长度为%dn”,p-s); / 输出字串长 ,5.2.2 数组名是一个常量指针,指向该数组的首地址. 例,C语言程序设计,22,s,s,p,图中数组的首地址是s0的地址,即&s0。s可看作是指向s0的指针。s是不会动的,是常量指针。,C语言程序设计,23,/ 5_6.cpp #include /预编译命令 void main() /主函数 /函数体开始char shuzi=“987654321“;/定义数组,/ 赋初值为数字字符串char *p=

13、/ 换行 ,数组名是一个常量指针,指向该数组的首地址,例,C语言程序设计,24,shuzi,p,说明: 1、字符串: 数字字符串。 2、p指向shuzi8,即指向串中的字符1。 3、直到型循环,用putchar函数将shuzi8输出到屏幕;之后让p=p-1。 4、在while中,当p=shuzi则继续执行循环体。一旦 pshuzi 则退出循环。这种做法使输出结果为123456789 5、在本例中数组名shuzi是一个常量指针,永远指向shuzi0的地址上。 思考:如何通过p和shuzi求该数字字符串的长度,C语言程序设计,25,#include /预编译命令 5_7.cpp void main

14、() /主函数 /函数体开始int i;char *p=NULL; /定义指针变量,赋初值为NULLp=“computer“; /指针赋值,指向字苻串coutpendl; /输出字苻串for (i=0;i8;i=i+1)coutpi; /输出第i个字苻coutendl; /换行while(*p) /循环体开始cout*p; /输出p所指向的字符 p=p+1; /指针变量值加1 /循环体结束coutendl; /换行 /函数体结束,C语言程序设计,26,上例中有三种不同的输出方式,请你自己分析一下,各有什么特点说明: 1、对字符指针变量赋值的写法 (1)char *p; (2) char *p=

15、“computer”;p = “computer”; 以上两种都行。可以整体赋值。2、对字符数组赋初值的写法 (1)char as12=“department”;/ 可以。在定义时可以整体赋值char as =“department”;/ 可以。在定义时可以整体赋值 (2)char as12;as = “department”; / 不可以!不可以整体赋值as12=“department”; /不可以!不可以整体赋值,C语言程序设计,27,5.2.3 指针数组,1. 指针数组的概念指针数组也是数组,但它的各数组元素都是指针,且必须是指向同一种数据类型的指针。 2. 指针数组的定义和初始化 假设

16、存在3个数组,定义如下ar0=0,1,2;ar1=1,2,3;ar2=2,3,4; 下面的语句定义一个指针数组p,并初始化int *p=ar0,ar1,ar2;,C语言程序设计,28,5.2.3 指针数组,这条语句定义p是int *类型的数组,其长度由初始化的项决定,此处为3.这个数组的每个元素都是一个指针变量,分别指向数组ar0,ar1和ar2的首地址。,C语言程序设计,29,5.2.3 指针数组,下面给出一个程序,程序5_8.cpp。希望在机器上运行这个程序,重点理解: (1)如何输出一个变量的地址 (2)上图中p与数组ar0,ar1,ar2间的指向关系 (3)p00与p01的含义,C语言

17、程序设计,30,5.2.4 指向指针的指针,指向指针的指针:双重指针变量,其值为一个指针变量的内存存放地址 int a = 123; int *p_a = /p 指向指针 p_a,C语言程序设计,31,5.2.4 指向指针的指针,二维数组的数组名的含义 二维数组的名称也是一个首地址,指向二维数组的第一个元素。 二维数组是一个特殊的一维数组。该一维数组的每一个元素是一个指针(指向另外的一维数组), 实际上,二维数组就是一个指针数组 二维数组的数组名可以看成是指向指针的指针。,C语言程序设计,32,5.2.4 指向指针的指针,char name3 = China, America, German;

18、 数组名:name(双重指针) 元素:name0, name1, name2(指针) 元素:name00,name11(字符),C语言程序设计,33,5.2.4 指向指针的指针,例:通过双重指针访问数组元素(5_9.cpp)/ 通过双重指针访问字符串for (i=0; i3; i+)printf(“n第%d个字符串的首地址:%ld, %ld,%ld, %ld“, i,name+i,namei,C语言程序设计,34,5.3 字符串及其处理,在C语言里,没有提供专门的字符串类型,所以需要使用字符数组来处理字符串。字符数组是最常用的一维数组,因为C语言经常用它来书写与字符串处理有关的程序。字符数组是

19、以字符作为元素的数组,可用于存储和处理字符型数据。字符数组中一个元素存放一个字符。,C语言程序设计,35,5.3.1 字符串指针,可以使用指针指向字符数组或字符串常量,通过指针来使用字符数组或字符串常量。 指向字符串的指针变量实际上就是一个指向字符型变量的指针变量,正如同指向整型数组的指针变量就是指向一个整型变量的指针变量一样,因为一个字符串就是一个字符数组。 指向字符串的指针变量,它保存的是字符串中第一个字符所在内存单元的地址。,C语言程序设计,36,通过指针变量访问字符串,能够通过指针变量访问字符串的前提是:已经定义了一个字符型指针变量,并且已经把某个字符串的指针赋值给它。,访问方法: 指

20、针法或下标法,如果pstr的初值为字符串的第一个字符的地址,比如有 char *pstr = “Hello, World”; 则有以下事实: pstr + i 就是第 i 个字符的地址,即它指向字符串中的第 i 个字符 *(pstr + i) 或者 pstri 就是它所指向的字符 指针变量也可以使用下标法,即 pstri 和*(pstr + i) 是等价的,C语言程序设计,37,通过指针变量引用数组元素:, 编程把字符串s2复制到字符串s1中,/* 方法1:用数组名和下标 */ #include void main( ) char s180 = “”, s2 = “hello, world”;

21、int n;for(n = 0; s2n != 0; n +)s1n = s2n;s1n = 0;printf( “s1=%sns2=%s”, s1, s2); ,C语言程序设计,38,通过指针变量引用数组元素:, 编程把字符串s2复制到字符串s1中,/* 方法2:用数组名偏移量得到元素地址,访问元素*/ #include void main( ) char s180 = “”, s2 = “hello, world”;int n;for(n = 0; s2n != 0; n +)*(s1 + n) = *(s2 + n);*(s1 + n) = 0;printf( “s1=%sns2=%s”

22、, s1, s2); ,特点: 数组名本身不变也不可能被改变,C语言程序设计,39,通过指针变量引用数组元素:, 编程把字符串s2复制到字符串s1中,/* 方法3:用指针变量偏移量得到元素地址,访问元素*/ #include void main( ) char s180 = “”, s2 = “hello, world”;int n; char *p1 = s1, *p2 = s2;for(n = 0; *(p2 + n) != 0; n +)*(p1 + n) = *(p2 + n);*(p1 + n) = 0;printf( “s1=%sns2=%s”, s1, s2); ,特点: 指针变

23、量本身的值没有变化,C语言程序设计,40,通过指针变量引用数组元素:, 编程把字符串s2复制到字符串s1中,/* 方法4:用指针变量自身变化得到元素地址,访问元素*/ #include void main( ) char s180 = “”, s2 = “hello, world”;int n; char *p1 = s1, *p2 = s2;for(n = 0; *p2 != 0; n +)*(p1 +) = *(p2 +);*p1 = 0;printf( “s1=%sns2=%s”, s1, s2); ,特点: 普通变量做循环控制变量,C语言程序设计,41,通过指针变量引用数组元素:, 编

24、程把字符串s2复制到字符串s1中,/* 方法5:用指针变量自身变化得到元素地址,访问元素 */ #include void main( ) char s180 = “”, s2 = “hello, world”;char *p1 = s1, *p2 = s2;for( ; *p2 != 0; p1 +, p2 +)*p1 = *p2;*p1 = 0;printf( “s1=%sns2=%s”, s1, s2); ,特点: 指针变量做循环控制变量,C语言程序设计,42,通过指针变量访问字符串时的注意事项,注意:在利用指针变量本身的值的改变来访问字符串时,要时刻注意指针变量的当前值。,#inclu

25、de void main( ) char s180 = “”, s2 = “hello, world”;char *p1 = s1, *p2 = s2;for( ; *p2 != 0; p1 +, p2 +)*p1 = *p2;*p1 = 0;printf( “s1=%sns2=%s”, p1, p2); ,此处用p1和p2来输出字符串,是得不到正确结果的。,C语言程序设计,43,指向字符串的指针变量的有关运算,如有: char str80, *ps;ps = str; 或 ps = , ps + 或 ps += 1,是下一个字符的地址(即 ps 指 向下一个字符)ps - 或 ps -= 1

26、,是上一个字符的地址(即 ps 指向 上一个字符), * ps + 等价于 *(ps +) ,即先得到 ps 当前指向 的字符,然后再使 ps 自增,从而指向下一个字符, * + ps 等价于 *(+ ps) ,即先使 ps 自增,指向 下一个字符,然后得到 ps 所指向的字符, (* ps) + ,则是表示 ps 当前指向的字符加1,C语言程序设计,44,5.3.2 字符串应用举例,一辆肇事汽车的号码是4位十进制数。目击者向交警描述这个车号:这是一个完全平方数,且这4个数字从左至右一个比一个大。试编程算出车号。 解题思路 (1)令n为待求的车号,则n=I*I,且I=32,33,99 (2)枚

27、举I,得n=I*I,查看n的各位从高到低是否一个比一个大,如是则找到答案。,C语言程序设计,45,5.3.2 字符串应用举例,(3)将n这个数字按位分解为4个数字字符,这可以用将数字转为字符串的函数 char *itoa(int value,char *string,int radix) itoa是函数名,其前的char *表示返回值是一个指向字符串的指针。 第一个参数value是待转换的数值 第二个参数是字符串的指针,用于返回转换得到的字符串,必须在使用前声明相应的存储空间(即字符数组的长度) 第三个参数用于限定进制,值为2到36,C语言程序设计,46,5.3.2 字符串应用举例,如果n的值

28、为1089,则 char buf5; itoa(n,buf,10); 执行上面的语句,得到buf的值为“1089”. 于是buf0,buf1,buf2,buf3依次存储了n从高到低的各位 (4)比较n的数值是否是从高到低位越来越大,只需用下面的条件表达式: buf0buf1&buf1buf2&buf2buf3 如果上面条件满足了,则n即为所求 参考程序:程序5_10.cpp,C语言程序设计,47,5.4 指针和结构,例:程序5_11.cpp 程序说明: (1)语句student *point是定义一个指向结构student的指针point (2)语句point =&my是将名为my的结构的地址

29、赋给point。这时point指向my结构。,C语言程序设计,48,5.4 指针和结构,(3)有了指向结构的指针,就可以通过箭头操作符“-”来访问结构的成员。如point-birthday=19840923;point-sex=1; 都是给结构成员赋值的语句 (4)strcpy(point-name,”王小二”)是利用库函数将名字复制到my结构的name成员 (5)点操作符和箭头操作符可以互换使用,以下三种访问结构成员的写法是等价的:point-name,(*point)-name,my.nam,C语言程序设计,49,5.5 指针与结构数组,例:输入同学信息并按身高从低到高排序,然后顺序输出各

30、位同学的姓名和身高。程序5_12.cpp 程序说明: (1)p_stu是指结构student的指针。 (2)p_stu-name是p_stu通过箭头操作符来访问student结构成员name (3)p_stu+让p_stu指向结构数组的下一个数组元素,C语言程序设计,50,5.6 程序举例,例1:编辑手中有一篇英文文稿需付稿酬,稿酬按40元/千字计算。英文文稿的字按单词数量计,请计算文稿中有多少单词? 算法分析 (1)假设文稿是从键盘输入,最多不超过50个字符,将一个字符指针指向文稿的开头。 (2)从指针当前所指的字符开始逐个对字符检查。如果该字符为0,则结束统计,转步骤;否则,继续以下步骤。

31、 (3)如果该字符是空格,则将指向字符的指针往下移动一个字符;重复该步骤直到指针当前所指的字符不为空格。,C语言程序设计,51,例1:统计单词数量,(4) 检查指针当前所指的字符是否为结束标志0,如果是,转步骤;否则,继续以下步骤。 (5) 单词计数器加1。 (6)检查指针当前所指的字符。如果不是空格并且也不是结束标志0,则将指向字符的指针往下移动一个字符;重复该步直到指针当前所指的字符为空格或结束标志0;转步骤。 (7)输出统计出的单词数量。 判断空格的方法可以用C提供的库函数:isspace(int c)。如果c是一个空格字符,则该函数返回一个非零整数。该函数对应的头文件是。 5_13.c

32、pp,C语言程序设计,52,5.6 程序举例,例2:打鱼还是晒网?中国有句俗语叫“三天打鱼两天晒网”。某人从2000年1月1日起开始“三天打鱼两天晒网”。问这个人在以后的某一天中是在“打鱼”,还是在“晒网” 。 算法分析 计算从2000年1月1日开始至指定日期一共有多少天; 由于“打鱼”和“晒网”的周期为5天,所以将计算出的天数用5去除; 根据余数判断他是在“打鱼”,还是在“晒网”:若余数为1,2,3,则他是在“打鱼”;否则是在“晒网”。,C语言程序设计,53,例2:打渔还是晒网,这三步中,关键是第一步。要判断经历年份中是否有闰年,若是闰年,二月为29天,平年为28天。判断闰年的方法可以描述如

33、下: 如果年能被4除尽且不能被100除尽或能被400除尽则该年是闰年,否则不是闰年。 C语言中判断能否整除可使用求余(模)运算。 5_14.cpp,C语言程序设计,54,5.7 小结,(1)指针是一个特殊的变量,其值是内存的地址。给指针赋值就是将一个内存地址装入指针变量。如果这个内存地址是某变量的地址,则该指针就指向了该变量。 (2)指针变量的类型是指针所指向的变量的类型 (3)在定义指针变量时,将其初始化为空(NULL或0)是一个好习惯。,C语言程序设计,55,5.7 小结,(4)对指针变量赋值是将它所指向的变量的地址赋给指针变量。这时要用到取地址运算符&。&a表示变量a的地址。 (5)在赋值语句中可使用间接访问运算符,

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

当前位置:首页 > 企业管理 > 管理学资料

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


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

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

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