C语言程序设计ppt第9章课件.ppt
《C语言程序设计ppt第9章课件.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计ppt第9章课件.ppt(105页珍藏版)》请在三一办公上搜索。
1、2023/1/7,华中科技大学计算机学院,1,C语言程序设计,The C Programming Language,华中科技大学计算机学院曹计昌,2023/1/7,华中科技大学计算机学院,2,9.1 指针的概念与指针的使用,9.1.1 指针的概念 数据(变量、常量)(根据类型)占有一定数目的连续存储单元;数据的连续存储单元首地址称为数据的地址。变量的地址称为指针,存放地址数据的变量称为指针变量。指针也是一种变量,也要占用一定的内存单元。指针的特殊之处在于它存放的是另一个变量所占存储单元的起始地址。,2023/1/7,华中科技大学计算机学院,3,指针变量的类型由其基类型决定.基类型是指针变量所指
2、(即所指向)变量的数据类型。因此,称指向某种类型变量的指针为该类型的指针。如:指向整型变量的指针称为整型指针,指向字符型变量的指针称为字符指针等。不管是何种类型的指针,所占的存储与机器字长相当.如:16位机,指针占2字节,思考:为什么指针指针有类型?,指针变量的类型,2023/1/7,华中科技大学计算机学院,4,ptr指向x,如果整型变量x的地址是0 xFEC0,x的值是0 xABCD,整型指针ptr的地址是0 xFEBC,整型指针ptr指向整型变量x的内存存储和指向情况可以由下图描述:,2023/1/7,华中科技大学计算机学院,5,9.1.2 指针的声明,声明指针的一般形式:T*标识符1,*
3、标识符2,,*标识符n;其中,T是数据类型。*是指针说明符,用于将其说明的标识符说明为指针类型。标识符1,标识符2,标识符n是T类型的指针的名字.例9.1:char*pc1,*pc2;int*pi;float*pf;,2023/1/7,华中科技大学计算机学院,6,指针变量也可以在声明的时候对其进行初始化,但必须用所指变量的地址进行初始化。初始化后的指针将指向以初值为地址的变量。例9.2 声明指针并初始化。int x=10,*p=,2023/1/7,华中科技大学计算机学院,7,例9.3 给出以下一些复杂声明,解释其含义。,int(*p1)3;double*p25;char(*fp)(int,in
4、t);int*pf(float a);int(*fp_ary2)(char*,int*);,2023/1/7,华中科技大学计算机学院,8,9.1.3 指针的使用,在声明指针变量的前提下,指针的使用首先要获取变量的地址作为指针值,然后要将该指针值赋给指针变量,建立指针变量与被指变量间的指向关系。接下来就是如何通过指针变量来间接访问和操作指针所指的变量。,2023/1/7,华中科技大学计算机学院,9,1.取地址运算符-单目&单目&在C中表示取地址运算。该表达式的一般使用形式是:&右操作数 根据表达式的操作语义可知,右操作数必须是一个左值表达式。如果右操作数的类型是T,则表达式&右操作数的类型是T*
5、。,2023/1/7,华中科技大学计算机学院,10,2.指针的赋值 指针的声明只是创建了指针变量,获得了指针变量的存储,但并没有给出指针变量指向那个具体的变量,此时指针的值是不确定的随机值,指针处于“无所指”的状态。例如:用 int*p;语句来说明p是一个整型指针变量时,p的值是不确定的随机值。此时称p为悬挂指针。,2023/1/7,华中科技大学计算机学院,11,例9.5 设有下面说明:int i,*pi;char c,*pc;float x5,*pf;则:pi=合法有效。,2023/1/7,华中科技大学计算机学院,12,3.间访运算符单目*声明指针的目的是希望通过指针实现对内存中变量的快速访
6、问,必须使用单目*这个间访运算符才能实现利用指针对内存变量的访问。间访的含义是间接访问。单目*运算实际上是单目&运算的逆运算.使用单目*间访变量的一般形式是:*操作数“*操作数”称为间访表达式,它的操作语义是引用以操作数之值为地址的变量。操作数也可以是表达式,但其值必须是地址值。间访表达式的值是一个左值,代表指针所指的变量。而指针所指的变量的类型就是间访表达式运算结果的类型。,2023/1/7,华中科技大学计算机学院,13,例9.6 间访运算符的基本操作举例。设有声明和赋值:char ch=a,*pc=&ch;*pc=b;并且假设字符变量ch的地址是0 x1b2a,试问ch,pc,以及*pc的
7、值是什么?,2023/1/7,华中科技大学计算机学院,14,4.无值型指针 类型为void*的指针称为无值型指针或void指针。C语言规定,任何类型的指针都可以将其值赋给void指针,但是不能对void指针执行间访操作,即对void指针施行“*”操作属于非法操作。int x=1,*px=/*非法*/,2023/1/7,华中科技大学计算机学院,15,9.2 指针运算,指针允许进行算术运算、赋值运算和关系运算。通过指针运算可以快速定位到指定的内存单元,提高程序的执行效率。9.2.1 指针的算术运算1.指针的移动指针的移动指指针在原有位置的基础上,通过加一个整数实现指针的前移(地址增大的方向)或者通
8、过减一个整数实现指针的后移。当然,如果加减的是一个负数,则移动的方向刚好和前面相反。,2023/1/7,华中科技大学计算机学院,16,例9.9 指针的算术运算应用举例(演示EX9_9)。#include stdio.hvoid main(void)int iary5=0,1,2,3,4;int*px=,2023/1/7,华中科技大学计算机学院,17,px+=3;printf(after px plus 3:n);printf(px=%p*px=%dn,px,*px);px-=2;printf(after px minus 2:n);printf(px=%p*px=%dn,px,*px);pri
9、ntf(*(+px)=%dn,*(+px);printf(px=%p*px=%dn,px,*px);printf(*(px+)=%dn,*(px+);printf(px=%p*px=%dn,px,*px);printf(*(-px)=%dn,*(-px);printf(px=%p*px=%dn,px,*px);printf(*(px-)=%dn,*(px-);printf(px=%p*px=%dn,px,*px);,2023/1/7,华中科技大学计算机学院,18,9.2.2 指针的赋值运算和关系运算1.指针的赋值运算 指针的初始化和基本赋值操作前面已有叙述。下面主要进行一些归纳并给出应用的例子
10、,其中利用指针的赋值运算以及类型强制来突破语言的一些制约因素的编程算法和思想可以在底层软件开发时借鉴,达到汇编级别开发的自由度。,2023/1/7,华中科技大学计算机学院,19,指针的赋值运算规则:(1)同类型的指针才可以直接使用赋值操作符进行赋值操作。如:int a3=1,2,3,*p=a,*q=p;(2)如果要实现不同基本类型指针之间的赋值运算,必须使用类型强制。利用指针的赋值运算以及类型强制可以实现一些特殊操作。,2023/1/7,华中科技大学计算机学院,20,例9.11 一个长整型数占4个字节,其中每个字节又分成高4位和低4位。试从长整型数的低字节开始,依次取出每个字节的高4位和低4位
11、并以ASCII码的形式进行显示。,2023/1/7,华中科技大学计算机学院,21,例9.11(演示EX9_11),#include stdio.h“void main(void)long x=0 x1234ABCD,k;char*p=(char*),2023/1/7,华中科技大学计算机学院,22,2 指针的关系运算指针的关系运算指对指针施行诸如:,=,以及!=这样一些比较操作。指针属于一种派生类型,它属于何种类型的指针要受所指变量的类型,即指针的基类型的限制。不同类型的变量在内存中分配的存储不同;对于不同的数据类型,定义于其上的操作和运算也不尽相同。因此,尽管所有指针的值都是二进制正整数,从关
12、系运算的操作语义上看,允许不同类型的指针进行比较没有实际意义,并且只会给语言和程序带来副作用。因此,C语言规定指针的关系运算只能限于同类型指针,不同类型指针之间的关系运算被视为非法操作。,2023/1/7,华中科技大学计算机学院,23,9.3 指针作为函数的参数,9.3.1 形参指针对实参变量的影响 例9.12 被调用函数中对形参的修改无法影响调用函数中实参变量的值举例(演示EX9_12)。#include stdio.hvoid swap(int u,int v)int t;printf(in function swap,before swap,u=%d and v=%dn,u,v);t=u
13、;u=v;v=t;printf(in function swap,after swap,u=%d and v=%dn,u,v);,2023/1/7,华中科技大学计算机学院,24,(演示EX9_12)void main(void)int x,y;printf(input two integers for x and y please!n);scanf(%d%d,2023/1/7,华中科技大学计算机学院,25,程序运行中的输入以及运行结果为:input two integers for x and y please!10 20(键盘输入)in function main,before swap,x
14、=10 and y=20in function swap,before swap,u=10 and v=20in function swap,after swap,u=20 and v=10in function main,after swap,x=10 and y=20,2023/1/7,华中科技大学计算机学院,26,(演示EX9_13)例9.13 以指针作为函数的参数实现变量值的交换。#include stdio.hvoid swap(int*p1,int*p2)int t;t=*p1;*p1=*p2;*p2=t;,2023/1/7,华中科技大学计算机学院,27,void main(voi
15、d)int x,y;printf(input two integers for x and y please!n);scanf(%d%d,2023/1/7,华中科技大学计算机学院,28,程序运行中的输入以及运行结果为:input two integers for x and y please!12 45before swap,x=12 and y=45after swap,x=45 and y=12,2023/1/7,华中科技大学计算机学院,29,对于数组,由于数组名标识的数组的起始地址,故可直接作为指针类型的实参;除此之外,都必须以&变量名的形式给出变量的地址作为实参,以保证在被调用函数中能
16、够操作调用函数中的对应变量。例9.14 将键盘输入的所有数字串逐个的转换为整数,并且依次存放于一个数组中。数字串前面可以加+、-号,各数字串之间至少用一个空格分开,用回车结束输入。演示并解释p267 例9-14,9.3.2 指针作为函数形参的应用,2023/1/7,华中科技大学计算机学院,30,#include ctype.h#define NUMBER 100int getint(int*pn);int getint(int*pn)int c,sign;while(isspace(c=getchar();/*跳过前导空格*/if(!isdigit(c),void main(void)int
17、aNUMBER,i,j,k;printf(input integers ends with Entern);for(i=0;i NUMBER,2023/1/7,华中科技大学计算机学院,31,9.4 数组的指针表示,数组元素既可以用下标表示,也可以用指针表示。对于T类型的数组元素ai,用下标表示时其地址为&ai,用指针表示时其地址为a+i,编译程序计算ai的地址都统一按照:a+i*sizeof(T)的形式进行。其中i*sizeof(T)表示数组元素ai相对该数组的起始地址向后偏移的字节数。由于下标操作符是系统的预定义函数,下标操作实际涉及对系统预定义函数的调用。因此,一般说来,指针运算比数组下标
18、运算的速度要快。,2023/1/7,华中科技大学计算机学院,32,9.4.1 一维数组的指针表示设有说明:int x5;各元素的访问方式:x0、x1、x2、x3、x4*(x+0)、*(x+1)、*(x+2)、*(x+3)、*(x+4)各元素的指针:&x0、&x1、&x2、&x3、&x4x+0、x+1、x+2、x+3、x+4,2023/1/7,华中科技大学计算机学院,33,ISO/IEC 9899中关于数组与指针关系的描述见p70,E1E2与(*(E1)+(E2)因此:ai=(*(a)+(i)=*(a+i)对于:bij,令bi=E1,E2=jbij=*(bi+j)=*(*(a+i)+j)所以:C
19、ijk=*(cij+k)=*(*(ci+j)+k)=*(*(*(c+i)+j)+k)思考:eijklm的间访表示?,2023/1/7,华中科技大学计算机学院,34,迭代处处都存在,上例求bij,Cijk 的间访表示就用到了迭代的方法.求诸个数中最大数,最小数等也应该灵活运用迭代方法.如:e1=ab?a:b(求两个数中较大数)e2=ce1?c:e1(求三个数中最大数)=c(ab?a:b)?c:(ab?a:b)对于de2?d:e2,将e2代入可求四个数中最大数学习要注意方法,学习要注意抽象,学习要注意应用.,2023/1/7,华中科技大学计算机学院,35,例9.15 任意位数的超长数据的加法运算。
20、,#include stdio.h“(演示EX9_15)#include ctype.h#define N 20/*N表示参与运算数据最长的长度*/void shift(int*a,int n);void shift(int*a,int n)int k,len,sft;len=N-1-n;/*数据的长度*/sft=N-len;/*右对齐移位的位数*/for(k=0;klen;k+)/*右对齐移位*/*(a+k)=*(a+k+sft);for(k=len;kN;k+)/*右对齐移位的位数*/*(a+k)=0;/*对没有存放数据的位填充零*/,2023/1/7,华中科技大学计算机学院,36,求:1
21、2345678901234567+98765432109876543void main(void)int xN,yN,zN+1,i,carry=0,flag;for(i=0;i=0/*数据长度小于N,右对齐移位*/,2023/1/7,华中科技大学计算机学院,37,for(i=0;i=0;i-)/*输出结果。和中的前导字符0不输出*/if(flag=0,2023/1/7,华中科技大学计算机学院,38,2以指针变量为数组首地址时一维数组的指针表示,一般的,为了用指针变量表示数组中的元素,应该先声明一个数组,再声明一个与数组名类型相同的指针变量,然后通过初始化或者赋值操作使指针变量值向数组中的元素。
22、这样就可以指针变量来快速访问数组中的其他元素。例如,先声明指针变量,然后通过赋值语句将数组的起始地址赋给指针变量,使指针变量指向数组中下标为0的元素。int a6,*p;p=a;或者p=一般地,此时称指针变量p指向数组a。,2023/1/7,华中科技大学计算机学院,39,例9.16 显示输出指向数组a的指针变量p的地址、值,数组名a的值,a0的地址。数组a中每个元素的地址和值,以及p依次指向数组中各个元素时的取值和所指元素的值。,#include stdio.hvoid main(void)int i,a5=1,2,3,4,5,*p=a;printf(address of p is%pn,运行
23、结果见P272,2023/1/7,华中科技大学计算机学院,40,3.指向数组元素的指针变量的运算操作,指向数组的指针变量的运算操作可以分为三类。一是对指针变量或由指针变量组成的地址表达式进行运算,目的是快速定位到数组中的指定元素。二是间访操作,即访问指针变量或由指针变量组成的地址表达式所指向的数组元素。三是对间访后的数组元素施行运算。这些运算中往往涉及+和*操作,+和*操作在C中位于第二优先级,结合性是右结合,当两者同时出现的时候需要严格通过结合性来进行分析判断。,2023/1/7,华中科技大学计算机学院,41,设有说明:char s20,*pc;对于字符指针pc,下面的操作合法:,pc=s对
24、字符指针变量pc赋值,使其指向字符数组s(即s0).pc+i 结果为pc后面第i个元素的地址。*(pc+i)结果为pc后面第i个元素。*+pc 结果为pc加1之后所指元素。+*pc 结果为pc所指元素加1。*pc+结果为pc所指元素,然后pc加1。(*pc)+结果为pc所指元素,然后pc所指元素加1。&pc 结果为字符指针变量pc的地址,类型为char*,2023/1/7,华中科技大学计算机学院,42,对于数组名s,下面的操作合法:s+i 结果为数组s中第i个元素的地址(即si的地址)。*(s+i)结果为数组s中第i个元素si。+*s 结果为元素s0加1。(*s)+结果为元素s0的值,然后s0
25、加1。由于数组名s是地址常量,因此下面的操作非法:s=pc 非法.数组名s是地址常量,不能进行赋值操作。&s 非法.数组名s是地址常量,不能取地址。*+s 非法.不能对数组名s进行前缀+操作。*s+非法.不能对数组名s进行后缀+操作,2023/1/7,华中科技大学计算机学院,43,9.4.2 一维数组参数的指针表示 一维数组参数的指针表示是讨论在定义函数时如何用指针表示函数的形参,以及在调用函数时如何用指针表示函数的实参。对于形如int f(int a)的函数,调用时应该用一个整型数组x的数组名x,或者数组打头元素的地址&x0作为实参。数组名x和打头元素的地址&x0的类型都是int*。所以,一
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言程序设计 ppt 课件
链接地址:https://www.31ppt.com/p-2075947.html