




已阅读5页,还剩66页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
指针,目录,地址和指针的概念变量的指针和指向变量的指针变量数组与指针字符串与指针指向函数的指针返回指针值的函数指向数组和指向指针的指针指针的数据类型和指针运算小结,指针的概念,指针是C语言的一个重要概念,也是C语言的一个重要特色。深刻理解和正确使用指针是学习本章的基本要求。,一、地址,在计算机中,把内存区划分为一个一个的存储单元,每个单元为一个字节(位),它们都有一个编号,这个编号就是内存地址。如下图所示:,注意:1、程序中定义的每个变量在编译后都占有各自的内存区,系统通过内存地址对变量进行存取。2、数据所占有的存储单元个数是由其类型决定的。3、首地址:第1个单元的地址4、表示地址的数与整数的区别,指针的概念,二、举例,如有定义:charc=A;inta=3;则所占内存情况如下:,注意:c和a的地址可能相邻,也可能不相邻,由系统分配。,指针的概念,三、指针与指针变量,1、指针:简单地说,指针就是地址。二者是同一个概念的两种说法。只不过指针更形象一些,就像一个针一样,可以指向某个内存单元。,2、指针变量:首先指针变量就是一个变量,和以前所讲的其它变量没有本质区别。不同之处在于这种变量中所存放的内容是地址。,指针的概念,四、直接访问和间接访问,指针的概念,A,B,1、直接访问,通过变量本身对变量进行存取的方式,称为直接访问。如定义:intx;则x=10;x+=5;这种访问方式只需要变量本身就得到了该变量的全部信息,不需要其它内容,是直接的。,指针的概念,2、间接访问,通过指针变量实现对变量的访问方式,称为间接访问。首先要定义一个指针变量,然后将一个同类型变量的地址赋给该指针变量(称指针变量指向该变量),这样就可以进行间接访问了。间接访问的过程是:由指针变量得到变量的地址,根据该地址找到变量的存储区,再对该存储区的内容进行存取,从而实现了对变量的间接访问。,指针的概念,指针变量的定义和引用,一、指针变量的定义和赋值,1、格式:类型名*指针变量名;,2、举例int*p1;char*s1,*s2;float*a1,*a2,f;,3、说明a.类型名:指针变量所指向的变量类型。b.*是定义指针变量的标志,不可丢掉。c.指针变量定义后,其值是不确定的。,4、赋值:可以进行初始化,也可以使用赋值语句,(1)、初始化:inta,*s=,(2)、赋值语句inta,*s;s=,(3)、注意:只能用同类型变量的地址进行赋值如定义:int*s;floatf;则s=是错误的。,指针变量的定义和引用,不定,在分析有关指针的程序时,画图是很好的方法:,若有:inta,*s;则,s,a,若有:inta=5,*s=则,不定,5,int*p1,*p2;p1=,指针变量的定义和引用,#includemain()inta1=11,a2=22;int*p1,*p2,*p;p1=,指针变量的定义和引用,#includemain()inta1=11,a2=22,t;int*p1,*p2;p1=,指针变量的定义和引用,三、指针变量作为函数的参数,1、形式:形式参数名前加上一个*。如:voidtest(int*pointer,charf,char*s),2、说明通过指针作为参数可以将主调函数中某变量的地址传递到被调函数中,从而可以改变该地址对应变量的值,即改变主调函数中变量的值。,指针变量的定义和引用,指针变量的定义和引用,#includevoidtest(int*pt);main()inta=11,*p=,指针与一维数组,在语言中,指针与数组有着密切的关系。对数组元素,既可以采用数组下标来引用,也可以通过指向数组元素的指针来引用。采用指针方法处理数组,可以产生代码长度小、运行速度快的程序。,一、通过指针访问一维数组,1、数组结构的分析,设有数组定义为:inta5;则有:(1)a表示数组在内存中的首地址,也就是数组中第1个元素的首地址,它是一个地址常量,其值由系统在编译时确定,程序运行期间不能改变。(2)数组中的各元素表示为:a0、a1、a2、a3、a4或者是:*(a+0)、*(a+1)、*(a+2)、*(a+3)、*(a+4),指针与一维数组,(3)数组中的各元素的地址表示为:并进行赋值:s=a;或s=则,指针变量s指向了数组a的开始,二者产生了联系,这样就可以通过指针变量s访问数组a了。,a,或s=图变为:,a,s+=2;效果与上述相同。,指针与一维数组,3、一维数组的访问,#includemain()inta5=1,3,5,7,9,i,*p=a;for(i=0;i5;i+)printf(“%d”,ai);for(i=0;i5;i+)printf(“%d”,*(a+i);for(i=0;i5;i+)printf(“%d”,pi);for(i=0;i5;i+)printf(“%d”,*(p+i);for(;pa+5;p+)printf(“%d”,*p);p=a;while(pa+5)printf(“%d”,*p+);,指针与一维数组,用多种方法访问一维数组各元素,4、几个表达式的分析,设定义:inta3=1,2,3,*s=a;s,*sa,*as+,*s+,a+,*a+*(s+),(*s)+*(a+),(*a)+初始化时的*s=a;与语句*s=a;的不同一个指针变量加/减一个整数后,指针变量值的变化情况,指针与一维数组,二、通过指针在函数间传递一维数组,1、函数的定义形式,intfunc(intarray,intn)函数体;也可以写为:intfunc(int*pointer,intn)函数体;,指针与一维数组,2、函数的说明形式,如有函数定义:intfunc(intarray,intn)函数体;则对该函数的说明形式可以写为:intfunc(intarray,intn);intfunc(int*array,intn);intfunc(int,int);intfunc(int*,int);,注意:作为形参定义的数组名是一个指针变量,它在函数体中可以变化,这一点与变量定义时不同。,指针与一维数组,编写在数组的最后一个元素中存放其它元素和的函数#includevoidsummary(int*p,intn);main()staticinta11=1,2,3,4,5,6,7,8,9,10;summary(a,10);printf(“Sumis%dn”,a10);voidsummary(int*p,intn)ints=0;while(n)s+=*(p+);*p=s;,指针与一维数组,函数还可写为:voidsummary(intarr,intn)inti,s=0;for(i=0;in;i+)s+=arri;arrn=s;,字符串是一种特殊的一维数组,字符串的特殊性在于:字符串的末尾是结束标志0,所以访问字符串时常用结束标志进行判断。,指针与字符串,一、通过指针访问字符串,1、字符串结构的分析,设有数组定义为:chars=“abcde”;则s是一个字符数组,它里面存放的是一个字符串。它在内存中占用6个字节,但长度为5。其结构为:,s,s0s1s2s3s4s5,结束标志,指针与字符串,字符串还可以定义为:char*s=“abcde”;它在内存中占用6个字节,长度为5。其结构为:,指针与字符串,s,s0s1s2s3s4s5,结束标志,2、用字符数组与用指针使用字符串的比较,定义及初始化chars=“abcde”;char*p=“abcde”;赋值chars6;char*p;s=“abcde”;p=“abcde”;strcpy(s,“abcde”);strcpy(p,“abcde”);使用s不能自加/减p可以自加/减,指针与字符串,注意:chars=“abc”;与chars=a,b,c;的区别,(2)指针法main()chara=“Hello,world!”;charb20;char*pa,*pb;for(pa=a,pb=b;*pa!=0;pa+,pb+)*pb=*pa;*pb=0;printf(“%sn”,b);,该功能相当于:strcpy(b,a);,指针与字符串,下标法main()chara=“Hello,world!”;charb20;inti;for(i=0;ai!=0;i+)bi=ai;bi=0;printf(“%sn”,b);,将字符数组a中的字符串拷贝到字符数组b中,二、字符串指针作函数参数,1、函数的定义形式,charfunc(chara,charb)函数体;也可以写为:charfunc(char*a,char*b)函数体;,指针与字符串,voidmystrcpy(char*to,char*from);main()charca20,*cp=“Hello,world!”;mystrcpy(ca,cp);printf(“%s”,ca);,设计一函数,实现与标准函数strcpy类似的功能。,voidmystrcpy(char*to,char*from)while(*from!=0)*to=*from;to+;from+;*to=0;,思考:调用mystrcpy(ca,cp+2);结果如何?,指针与多维数组,数组是具有相同“数据类型”的数据的顺序集合,而数组本身也是语言的一种数据类型,同样可以作为数组的元素类型。当一个一维数组的元素类型为数组时,便构成了多维数组。熟记下面两组等价式:xi*(x+i)则有:a表示数组在内存中的首地址,也就是数组中第1个元素(也是第一行)的首地址,它是一个地址常量,其值由系统在编译时确定,程序运行期间不能改变。该二维数组可以理解为:它是一个一维数组,含有3个元素,每个元素又是一个一维数组,该一维数组含有4个元素,每个元素是int类型。,指针与多维数组,二维数组的逻辑结构图如下:,a0,a1,a2,a+0,a+2,a+1,指针与多维数组,指针与多维数组,2、指向二维数组中一行的指针变量,(1)格式:类型名(*指针变量名)长度;(2)例如:int(*pa)4;(3)含义:pa是指针变量,它指向一个数组,数组含有4个元素,每个元素的类型是int。(4)说明:a.与定义int*pa;以及int*pa4;含义不同。b.如果执行pa+,则pa实际增加了多少呢?,pa实际增加了2*4=8个字节,指针与多维数组,c.若定义:inta34,(*pa)4=a;则关系图为:,a,pa,(*pa)0(*pa)1(*pa)2(*pa)3,如果执行pa+,则变为如图所示,pa,pa,那么(*pa)0、(*pa)1、(*pa)2、(*pa)3也变了,指针与多维数组,3、几个表达式,由xi*(x+i)和inti,j,*p,(*pa)4;/第一种方法for(pa=aa,i=0;i3;i+)printf(“n”);for(j=0;j4;j+)printf(“%5d”,paij);,/第二种方法for(pa=aa;paaa+3;pa+)printf(“n”);for(j=0;j4;j+)printf(“%5d”,(*pa)j);/第三种方法for(p=aa0;paa0+3*4;p+)printf(“n”);printf(“%5d”,*p);,指针与多维数组,二、通过指针在函数间传递多维数组,1、函数的定义形式,例如:intfunc(intarray4,intn)函数体;也可以写为:intfunc(int(*pa)4,intn)函数体;,指针与多维数组,2、函数的说明形式,如有函数定义:intfunc(intarray4,intn)函数体;则对该函数的说明形式可以写为:intfunc(intarray4,intn);intfunc(int(*pa)4,intn);intfunc(int4,int);intfunc(int(*)4,int);,注意:作为形参定义的数组名是一个指针变量,它在函数体中可以变化,这一点与变量定义时不同。,指针与多维数组,例求3行4列二维数组中的最大元素#includeintmax_value(int(*pa)4,introw);main()intaa34=1,3,5,7,2,4,6,8,20,15,32,12;printf(“maxelementis%dn”,max_value(aa,3);intmax_value(int(*pa)4,introw)inti,j,m=pa00;for(i=0;im)m=paij;return(m);,指针与多维数组,例求3行4列二维数组中的最大元素(另一种方法)#includeintmax_value(int*p,intn);main()intaa34=1,3,5,7,2,4,6,8,20,15,32,12;intmax=max_value(,指针与多维数组,指针数组与指向指针的指针,一、指针数组,1、指针数组的概念,指针数组是一种特殊的数组,它每个元素的类型都是指针类型(即地址),其它与一般数组相同。当把某个量的地址放入某元素中后,即可通过该元素对相应的量进行间接访问。,2、指针数组的定义,类型名*指针数组名常量表达式;如:int*ap3;char*s10;,3、指针数组的初始化,(1)inta15,a25,a35,*ap3=a1,a2,a3;(2)char*sp=“abc”,“123”,“Hello”;,4、指针数组的赋值,上面的情况中,可以先定义变量,再进行赋值,即(1)inta15,a25,a35,*ap3;ap0=a1;ap1=a2;ap2=a3;(2)char*sp=“abc”,“123”,“Hello”;sp0=“abc”;sp1=“123”;sp2=“Hello”;,指针数组与指向指针的指针,例:显示多个字符串voidmain()/指针数组实现char*ap3=“CPU”,“Computer”,“Microprocessor”;for(inti=0;i3;i+)puts(api);voidmain()/二维字符数组实现charaa315=“CPU”,“Computer”,“Microprocessor”;for(inti=0;i=0,指针数组与指向指针的指针,intgetchoice(char*menu,intn)inti,choice;for(i=0;ib?a:b);intmin(inta,intb)return(ab?a:b);,动态内存分配,由变量的作用域和存储类别知道,内存变量都有生存期,以前接触的变量,其内存的分配及释放都是由系统统一管理的。这一节我们介绍如何实现自己对变量空间的申请和释放。动态内存分配可以提高内存的使用效率。,1)void*malloc(unsignedintsize);该函数实现对内存的申请,申请大小为size,返回值为指针类型,指向所申请空间的首地址。2)void*calloc(unsignedn,unsignedsize);在内存动态存储区分配n个长度为size的连续空间3)voidfree(void*block);该函数实现对由malloc函数申请到的内存的释放4)void*realloc(void*p,unsignedintsize);将p所指向的动态空间大小改变为size5)voidexit(intstatus);该函数终止程序的执行。说明:这5个函数都在头文件stdlib.h中。,动态内存分配(使用的函数),调用形式:(类型说明符*)malloc(size)功能:在内存的动态存储区中分配一块长度为size字节的连续区域。函数返回值为该区域的首地址。“类型说明符”表示把该区域用于何种数据类型。(类型说明符*)表示把返回值强制转换为该类型指针。“size”是一个无符号数。例如:pc=(char*)malloc(sizeof(char);强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。,分配内存空间函数malloc,调用形式:(类型说明符*)calloc(n,size)功能:在内存动态存储区中分配n块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。例如:ps
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2022-2023学年上海建平中学高三语文试题及答案
- 2025年济南九年级中考数学考试试题 以及答案
- 2025重庆城市科技学院单招《英语》真题【全优】附答案详解
- 2024-2025学年焊工考试题库试题附完整答案详解(夺冠)
- 新生儿胎粪吸入综合征急救流程与护理要点
- 原始股转让合同合同(标准版)
- 招行担保合同(标准版)
- 合同银行担保合同(标准版)
- 和朋友开店合同(标准版)
- 中老年羊奶粉改建项目建议书
- 分析包容型领导风格对团队绩效和员工创新绩效的作用
- T/CCS 071-2023井工煤矿智能化带式输送机运维管理规范
- 排水管道工程施工组织设计
- 客服岗位职责培训
- 高一下学期《学生宿舍卫生和内务》主题班会课件
- 露营基地管理制度调查
- 食品防护知识培训
- 格拉斯哥(GCS)昏迷评估量表(详xi操作)
- 2025年北京中考英语阅读考纲外高频词汇(复习必背)
- 电网工程设备材料信息参考价(2024年第四季度)
- 数据中心运维服务投标方案(技术标)
评论
0/150
提交评论