




已阅读5页,还剩43页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章指针,8.1指针概念,指针是C的一个重要概念。其特点是:能有效地表示复杂的数据结构;能动态地分配内存,直接处理内存地址;能方便、有效地使用字符串和数组;能在调用函数后获得多个值。C中定义的变量,在编译时按变量的类型来分配一定长度的内存单元。在运行时,根据变量名与地址的对应关系,相应地存取变量的数据。这种按变量地址存取变量值的方法称为“直接访问”方式。如果变量的地址也存放在某一个内存单元,则存取方式为先找到存放变量的地址单元,再取变量的值,这种方式称为“间接访问”方式。如:将变量i的地址保存到p中;依据p当然可以访问到i,8.1.1.变量的指针和指向变量的指针变量,变量的指针就是变量的地址,即p的值。也就是说,指针变量的值就是该指针变量所指变量的内存首地址。在p的前面加上一个“*”(称其为“间接引用运算符”),即*p就表示指针变量p所指向的变量。从右图可知:*p也是一个变量,且与变量i是同一回事。i=3;与p=是同一回事/将3赋给指针变量p所指向的变量/,8.1.2指针变量的定义,定义形式:类型标识符*标识符;指针变量必须定义指针所指数据类型。如:inti,j;int*p1,*p2;p1=非法。,与指针有关的运算符:是将变量j的值赋给目标变量*p(即i)。*运算和int*p1,*p2;a=100;b=10;p1=/*p1和*p2就是变量a和b/,若先执行p1=是什么意思?这里“scanf(“%d,%d”,运行情况:5,9a=5,b=9max=9,min=5,8.2指针的运算8.2.1指针的算术运算主要为+-+-P+、p分别表示向后、向前移一个单元。P+n、p-n分别表示向后、向前移n个单元。8.2.2指针的关系运算主要为=、!=两种。当两个指针p1与p2指向同一地址时,p1=p2为真,当两个指针p1与p2不指向同一地址时,p1!=p2为真。,8.3.1指向一维数组的指针例:inta10,*p;p=则*(p+i)或*(a+i)就是p+i或a+i所指向的数组元素,即ai。也就是说*(p+i)=*(a+i)=ai。指向数组的指针变量可以带下标,如:pi与*(p+i)是等价的。,8.3指针与数组,也可写成如下:main()inta10,*p=a,i;for(i=0;i10;i+)scanf(“%d”,p+);printf(“n”);p=a;/此语句必不可少/for(i=0;i10;i+,p+)printf(“%d”,*p);,例8.3输出有10个元素的整型数组a的元素值。main()inta10,*p,i;for(i=0;i10;i+)scanf(“%d”,要注意指针变量的运算。如果p指向数组a(即p=a),则:p+(或p+=1)表示p指向下一个元素;*p表示取得当前所指元素之值。*p+等价于*(p+),相当于ai+,表示先*p,再p+1p。*p等价于*(p),相当于ai,表示先*p,再p1p。*(+p)相当于a+i,表示p+1p,再*p。*(p)相当于ai,表示p1p,再*p。(*p)+表示p所指之元素的值加1,不是指针值加1。即ai+1。,要注意指向数组的指针变量的当前值,因为指针可以指向数组最后一个元素以后的内存单元。,设二维数组a定义如下:staticinta34=1,3,5,7,9,11,13,15,17,19,21,23;a代表整个二维数组的首地址,也就是0行的首地址。a+1、a+2分别代表1行和2行的首地址。同样,a0或int(*p)4,i,j;p=a;scanf(“i=%d,j=%d”,运行情况:i=1,j=2/*注意这里的输入格式*/a1,2=13,程序中的“int(*p)4”表示p是一个指向包含4个元素的一维数组的指针变量,即p是一个行指针,指向一维数组的首地址。由于运算符优先级的关系,这里的(*p)4不能写成*p4。,一、字符串的表示形式用字符数组实现staticcharstr=“IloveChina!”;stri表示字符数组中的第i+1个字符。如:str8为字符h用字符指针实现char*a=“IloveChina!”;尽管没有定义为字符数组,但实际在内存开辟了一个字符数组用来存放字符串常量。同样,a8为字符h。注意:a不是字符串变量,只是将“IloveChina!”的首地址赋给指针变量a。,8.3.3字符串的指针,二、字符串指针作函数参数,可以用地址传递的方式,即用字符数组名作参数或用指向字符串的指针变量作参数,将一个字符串从一个函数传递到另一个函数。,例8.5用函数调用实现字符串的复制。,用字符数组作参数,voidcopy_string(from,to)charfrom,to;inti=0;while(fromi!=0)toi=fromi;i+;toi=0;main()chara=“Iamateacher.”;charb=“youareastudent.”;copy_string(a,b);printf(“string_a=%snstring_b=%sn”,a,b);,运行结果:string_a=Iamateacher.string_b=Iamateacher.,形参用字符指针变量,voidcopy_string(from,to)char*from,*to;for(;*from!=0;from+;to+)*to=*from;*to=0;main()char*a=“Iamateacher.”;char*b=“youareastudent.”;copy_string(a,b);printf(“string_a=%snstring_b=%sn”,a,b);,用字符数组和字符指针变量都能实现字符串的存储和运算,但二者之间是有区别的,不要混为一谈,必须注意以下几点:字符数组由若干个元素组成,每个元素可存放1个字符,而字符指针变量存放的是字符串的首地址,绝不是将字符串存放到字符指针变量中。对字符数组赋初值要用static存储类别,如:staticstr=“IloveChina!”;而对字符指针变量不必加static,如:char*a=“IloveChina!”;这是因为它只是对指针变量初始化,而不是对数组初始化。对字符数组只能对各个元素赋值,下列方式是错误的charstr15;str=“IloveChina!”;,三、字符指针变量与字符数组,对字符指针变量赋初值时:,char*a=“IloveChina!”;等价于:char*a;a=“IloveChina!”;,而对于字符指针变量,可采用如下方法:char*a;a=“IloveChina!”;这里赋给a的是字符串的首地址,而不是字符串。,即数组可以在变量定义时整体赋初值,但不能在赋值语句中整体赋值。,注意:对数组初始化时:staticcharstr14=“IloveChina!”;不等价于:charstr14;str=“IloveChina!”;,charstr14;scanf(“%s”,str);是可以的。但如果写成如下形式:char*a;scanf(“%s”,a);是非常危险的。因为指针变量没有确定的地址而指向程序区或其它数据区,从而会造成系统“冲突”。应当写成如下形式:char*a,str10;a=str;scanf(“%s”,a);,数组在编译时被分配内存单元,有确定的地址。而指针变量必须赋给一个确定的地址值,否则,在程序运行时会发生意想不到的后果。如:,main()char*a=“IloveChina!”;a=a+7;printf(“%s”,a);运行结果如下:China!下面的写法是错误的:charstr=“IloveChina!”;str=str+7;printf(“%s”,str);若定义一个指针变量使它指向一个字符串后,可以用下标形式引用指针变量所指字符串中的字符。,指针变量的地址值是可以改变的,而数组名的地址值是不能改变的。如:,例8.6main()char*a=“IloveChina.”;inti=5;printf(“%cn”,ai);for(i=7;ai!=0;i+)printf(“%c”,ai);,运行结果如下:eChina.,可以用指针变量指向一个格式字符串来代替printf函数中的格式字符串。也可以在定义字符数组赋初值时赋予一个格式字符串代替printf函数中的格式字符串。如:char*format;format=“a=%d,b=%fn”;printf(format,a,b);它相当于:printf(“a=%d,b=%fn”,a,b);,例8.7顺读和倒读都一样的字符串称为“回文”,如:LEVEL。试编写一个判断输入的字符串是否为回文的程序。#include“stdio.h”#include“string.h”main()chars81,*pi,*pj;inti,j,n;gets(s);n=strlen(s);pi=s;pj=s+n-1;while(*pi=)pi+;/跳过输入时的前导空格/while(*pj=)pj-;/跳过输入时的尾随空格/while(pipop参数1参数2参数n1,#includemain(argc,argv)intargc;charargv;printf(argc=%d,argc);while(argc1)+argv;printf(%sn,argv);argc;,例:8e_3编写main()函数,将后面的参数输出(演示),file1ChinaBeijingChangshaargc=4ChinaBeijingChangsha,上述文件设为file1则运行时:,指向指针数据的指针变量称为指向指针的指针。如:char*p;*运算符的结合性是从右至左,因此,*p相当于*(*p)。,8.8指向指针的指针,例8.11main()staticinta5=1,3,5,7,9;staticint*num5=/*此处*p改为*p行吗?*/,注意:不得将第2、3行错写为如下的一行:staticint*num5=1,3,5,7,9;,例8.12输入一行字符,统计其中有多少个单词。#include“stdio.h”main()charc,string81;inti,num=0,word=0;gets(string);for(i=0;(c=stringi)!=0;i+)if(c=)word=0;elseif(word=0)word=1;num+;printf(“Thereare%dwordsinthelinen”,num);,运行结果:IamaboyThereare4wordsintheline,关于()*三个声明符的补充说明:,()具有最高优先级和从左向右的结合性;*具有次高优先级和从右向左的结合性;当声明语句中含有两个以上的上述声明符时,往往造成声明语句的难理解性.理解它们的关键是要搞清楚它们的优先级关系与结合性.请看下面例题:例e1:int*a3;a是一个具有3个元素的数组(的优先级最高,遇到数组运算符,就要在数组名的前面找数组的类型);它的每个元素都是指向int型数据的指针.例e2:int(*pa)5;pa是一个指针(括号的优先级最高,遇到指针运算符,就要到指针名前找它指向的类型);它指向一个具有5个int型元素的数组.,例e3:float(*input)(int,int);input是指针;它指向一个float型函数,该函数有两个int型参数,函数的返回值为
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 应急安全教育培训制度课件
- 应急安全培训师课件
- 2025山东省肥城市中考数学能力检测试卷及答案详解(考点梳理)
- 2024-2025学年度反射疗法师大赛理论通关题库附答案详解【基础题】
- 买房煤气合同(标准版)
- 传染病疑似病例早期识别与护理观察要点
- 中药面膜合同(标准版)
- 2025年乐山马边彝族自治县事业单位考核招聘18人笔试备考题库及答案详解一套
- 2024年自考专业(汉语言文学)题库及参考答案详解【基础题】
- 2025年新零售环境下实体书店数字化转型成功案例研究报告
- 新转型九年一贯制学校三年发展规划(2025年-2028年)
- 期神丁鹏期货交易课件
- 反走私课件教学课件
- 大货车闯红灯安全培训课件
- 变电站SVG培训课件
- 2025秋教科版(2024)科学三年级上册教学设计(附目录)
- 2025年人教版三年级数学上册全册教案
- 《中国人首次进入自己的空间站》导学案 部编语文八年级上册
- Unit 2 My friends (Period 3) 课件2025-2026学年人教版英语四年级上册
- 烟花爆竹经营安全管理知识培训考核试题及答案
- 西游记第16回课件
评论
0/150
提交评论