版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、指针与指针变量8.18.2指针与数据8.3指针与函数指针与字符串8.48.5指针数组与指向指针的指针8.1 指针与指针变量8.1.1 指针的概念 为了说清楚什么是指针,必须弄清楚数据在内存中是如何存储的,又是如何读取的。 内存区的每一个字节有一个编号,这就是“地址” 。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。 按变量地址存取变量值的方式称为“直接访问”方式(,);(,); 例如:返回8.1 指针与指针变量8.1.1 指针的概念 另一种存取变量值的方式称为“间接访问”的方式。即,将变量的地址存放在另一个变量中8.1 指针与指针变量8.1.1 指针的概念 在
2、语言中,指针是一种特殊的变量,它是存放地址的。假设我们定义了一个指针变量i_pointer用来存放整型变量的地址,它被分配地址为(3010)、(3011)的两个字节。可以通过语句:i_pointer ;将的地址(2000)存放到i_pointer中。这时, i_pointer的值就是(2000) ,即变量所占用单元的起始地址。要存取变量的值,可以采用间接方式:先找到存放“的地址”的变量i_pointer ,从中取出的地址(2000),然后到2000 、 2001字节取出的值()。8.1 指针与指针变量8.1.1 指针的概念 8.1 指针与指针变量8.1.2 指针的定义、初始化与应用 基本类型
3、*指针变量名;定义指针变量的一般形式为:1.指针变量的定义“先定义,后使用”下面都是合法的定义:float *op3; /*定义了一个实型指针变量*/char *op4; /*定义了一个字符型指针变量*/8.1 指针与指针变量8.1.2 指针的定义、初始化与应用 定义指针变量时应注意以下几点: 2定义指针变量时必须指定其类型。指针数据都是地址,原本是没有区别的。但不同的变量占据的内存大小不同,其适合的操作也不同,在使用指针变量进行间接访问操作时,必须知道其数据长度及适合运算,因此必须指定其类型。1指针变量前面的*表示要定义的是指针变量,而不是算术运算中的乘号,指针变量名是*后面的标识符。每定义
4、一个指针变量,就要写一个*。8.1 指针与指针变量8.1.2 指针的定义、初始化与应用 3各类型的指针变量只能指向同类型的变量。2.指针变量的初始化和引用 C语言中有两个地址运算符,分别对应指针变量的两种运算: &:取地址运算符,运算对象为变量,运算结果为运算对象的内存地址。 例如:int i,*pi;pi=&i; /*pi指向i*/8.1 指针与指针变量8.1.2 指针的定义、初始化与应用 *:间接访问运算符,运算对象为指针变量,在一个指针变量前加*,表示该指针所指向的内存单元的值。也就是说,指针变量保存的是一个内存的起始地址,指针变量加*后表示该地址所对应的存储单元的值。 例如:*pi=5
5、; /*间接访问pi,即以pi的内容1000为地址的存储单元的内容为5*/8.1 指针与指针变量8.1.2 指针的定义、初始化与应用 定义了指针 pi 并赋值后,内存的分配情况如图所示: i(1000)10005*pipi 指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予具体的值。在定义指针变量时,可以给指针变量赋一个初始值,这一过程称为初始化。未经赋值的指针变量不能使用。指针变量只能赋予地址,不能赋予其它任何数据,否则将引起错误,这时就用到了指针运算符&和*。8.1 指针与指针变量8.1.2 指针的定义、初始化与应用 (1) Pf 是一个指针变量,存放了变量f的指针(也就是变量f
6、的内存地址)。*pf 表示指针所对应的内存单元的值,实际上就是变量f的值。因此,对*pf 的赋值会直接改变变量f的值。(2) *运算符的优先级比算术运算符高,因此,*pf+1.0等价于(*pf)+1.0。8.1 指针与指针变量8.1.2 指针的定义、初始化与应用 【例】输入两个整数 x 和 y,比较后降序输出。include void main()int *op1,*op2,*op,x,yscanf(%d%d,&x,&y);op1=&x;op2=&y; if(xy)op=op1;op1=op2;op2=op;/*两个指针变量交换,交换以后,op1指向存放大数的单元,op2指向存放小数的单元*/
7、printf(x=%d,y=%dn,x,y);printf(max=%d,min=%dn,*op1,*op2);8.1 指针与指针变量8.1.2 指针的定义、初始化与应用 运行结果:128365a=365,b=128Max=365,min=128128365opop1op2128365opop1op2op1op2xy8.1 指针与指针变量8.1.3 指针变量作为函数参数 用指针变量作为函数的参数,形参和实参都应当为指针类型数据。使用指针变量作参数,在函数执行过程中能够使指针变量所指向的变量值发生变化,从而在函数调用结束后这些变化后的值得以保存,并在主调函数中使用它们。 【例】 指针作为函数参数
8、示例。参考程序:void Doub(float *pNum)*pNum=*pNum*2;main()float f=10.0;Doub (&f);printf(nn=%f,f); 运行结果:n=20.0000008.1 指针与指针变量8.1.3 指针变量作为函数参数 传递指针的过程是值由实参向形参的单向传递过程,形式参数的变化不会影响到实际参数的值。需要注意的是,不能企图通过改变指针形参的值而使指针实参的值也改变 。8.2 指针与数据8.2.1 指针数据元素的指针 所谓数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。 一个数组是由连续的一块内存单元组成的,数组名就是这块连续内存单
9、元的首地址。一个数组也是由各个数组元素(下标变量)组成的,每个数组元素按其类型不同占有几个连续的内存单元。一个数组元素的首地址也是指它所占有的几个内存单元的首地址。返回8.2 指针与数据8.2.1 指针数据元素的指针 &a0pa013151719:a9p9*(a+9) 或*(p+9)8.2 指针与数据8.2.1 指针数据元素的指针 下面两个语句等价:op=&a0; op=a;在定义指针变量时可以赋给初值:int *op=&a0;它等效于:int *op; op=&a0;当然定义时也可以写成:int *op=a;数组指针变量说明的一般形式为:基类型 *指针变量名;8.2 指针与数据8.2.2 通
10、过指针引用数据元素通过下标的引用通过指针的引用 即用ai来引用数组a的第i个元素。在前面介绍数组时都是采用这种方法。 即采用*(a+i)或*(op+i)形式,用间接访问的方法来访问数组元素,其中a是数组名,op是指向数组的指针变量,其初值op=a。方法引用一个数组元素可以采用以下两种方法:8.2 指针与数据8.2.2 通过指针引用数据元素 【例】 输出数组中的全部元素(用指针变量指向元素)。 参考程序:#include void main()int a10,i,*op;op=a;for(i=0;i10;i+)*(op+i)=i;for(i=0;i10;i+)oprintf(a%d=%dn,i,
11、*(op+i);8.2 指针与数据8.2.2 通过指针引用数据元素1) 指针变量可以实现本身的值的改变。如op+是合法的,而a+是错误的。因为a是数组名,它是数组的首地址,是常量。2)3) 指针变量的当前值。 虽然定义数组时指定它包含10个元素,但指针变量可以指到数组以后的内存单元,系统并不认为非法。对指针变量值进行改变时应注意以下几点:8.2 指针与数据8.2.2 通过指针引用数据元素4) *op+,由于+和*同优先级,结合方向自右而左,等价于*(op+)。6)5) (op+)与*(+op)作用不同。若op的初值为a,则*(op+)等价a0,*(+op)等价a1 。 (*op)+表示op所指
12、向的元素值加1 。7) 如果op当前指向a数组中的第i个元素,则:*(op-)相当于ai-;*(+op)相当于a+i;*(-op)相当于a-i。8.2 指针与数据8.2.3 数组名作为函数参数 如果有一个实参数组,想在函数中改变此数组的元素值,则实参与形参的对应关系有以下4种: 1.形参和实参都是数组名void main()int a10;f(a,10)f(int x,int n)和指的是同一个数组。例如:8.2 指针与数据8.2.3 数组名作为函数参数2. 实参用数组名,形参用指针变量void main()int a10;f(a,10)f(int *x,int n)实参a为数组名,形参x为指
13、针,通过x指针值的变化,可以指向数组a的任意元素。例如:8.2 指针与数据8.2.3 数组名作为函数参数3. 形参和实参都用指针变量void main()int a10,*p;p=a;f(p,10);f(int *x,int n)实参p和形参x都是指针变量,通过指针p将数组a的地址传给x,再通过x指针值的变化指向数组a的任意元素。例如:8.2 指针与数据8.2.3 数组名作为函数参数void main()int a10,*p;p=a;f(p,10);f(int x,int n)实参p为指针变量,通过p将数组的首地址传给形参x,而x是数组名,虽然把x当做指针处理,但实际上x的使用与基本数组类型的
14、使用方法是一样的。例如:4. 实参用指针变量,形参用数组名8.3 指针与函数8.3.1 指针作为函数参数 使用指针作函数的形参时,要求实参用地址值,实现变量地址的传递,这种调用称为传址调用。它的特点是可以在被调用函数中通过改变形参的内容(即形参所指的变量的值)来改变调用函数中实参的值。 1. 基本数据类型的指针作为函数参数 它是指针作为函数参数是最常用的一种方式,它可以实现函数之间的数据传递,即可将被调函数中的值通过参数传递给主调函数,这种传递既安全可靠,又可一次实现多个数据传递。返回8.3 指针与函数8.3.1 指针作为函数参数2. 数组名作为函数参数 在C语言中,数组名实质上是一个指针,是
15、首元素的地址值。用数组名作为函数参数,实现的是传址调用。数组名可以作为函数的形参,也可以作为函数的实参;另外,可用数组名作为实参,用指针作为形参;还可用数组名作为形参,指针作为实参。8.3 指针与函数8.3.1 指针作为函数参数3.指向数组的指针作为函数参数 字符指针是指向字符串的指针。该指针实际上是指向一维字符数组首元素的指针,即指向字符串的首字符的指针。4.字符指针作为函数参数8.3 指针与函数8.3.1 指针作为函数参数5.指向指针的指针作为函数参数 指向指针的指针是一个二级指针,该指针所指向的变量还是一个指针,而这个指针指的是一个非指针变量,如果这个指针所指的仍然是一个指针,则该指针为
16、三级指针。8.3 指针与函数8.3.1 指针作为函数参数6.指向数组作为函数参数 指针数组作为函数参数实际上与数组名作为函数参数和指向指针的指针作为函数参数是相同的。8.3 指针与函数8.3.2 指针函数 前面所用到的函数中,实参或形参都可以是指针变量,但返回值都不是指针,而是某一实际值。实际上,不同类型的指针是可以作为函数返回值的。指针函数就是返回值指针的函数。 类型说明符 函数名(参数列表);指针函数的定义格式如下:char *linkstr(str1,str2);这是一个指针函数,函数名是linkstr,该函数有两个参数 str1和 str2,该函数的返回值是一个char型指针。例如:8
17、.3 指针与函数8.3.3 指向函数的指针变量 变量是与其存储单元相联系的,通过变量名可以得到变量的存储地址。一个函数包含一组指令序列,存储在某一段内存中,这段内存空间的起始地址为函数的入口地址,通过该地址也可以找到这个函数,故称函数的入口地址为函数的指针。在实际应用中,可以定义一个指针变量,其值等于该函数的入口地址,使其指向这个函数,这样通过这个指针变量也可以调用这个函数。这种指针变量成为指向函数的指针变量。而这种调用函数的方式与前面用函数名来调用函数的方式是不一样的。定义指向函数的指针变量的一般格式如下: 类型说明符 (*指针变量名)();8.3 指针与函数8.3.3 指向函数的指针变量
18、用一个函数名给指向函数的指针赋值,则该指针指向该函数所存放在内存中的入口地址,即一个函数存放在内存中的入口地址是用函数名来表示的,而不必给出参数,也不要圆括号。用指向函数的指针调用函数时,只需使用如下格式:*(指针变量名)(实参表)8.4 指针与字符串8.4.1 字符串的表示形式1.用字符数组实现2.用字符指针实现 可以不定义字符数组来实现字符串的操作,而通过字符指针来访问字符串中的存储区。 char *ps;ps=modi string;此时,字符指针ps指向该字符串常量中的首字符“m”,使用指针ps的加、减运算即可移动指针,以便能访问到该字符串的任何一个字符,并进行存取操作。例如:返回8.
19、4 指针与字符串8.4.2 字符指针作为函数参数 将一个字符串从一个函数传递到另一个函数,可以用地址传递的方法,即用字符数组名作为参数或用指向字符串的指针作为参数。在被调函数中可以改变字符串的内容,在主调函数中可以得到改变了的字符串。8.4 指针与字符串8.4.3 使用字符指针变量与字符数组的区别(1)字符数组由若干元素组成,每个元素中存放一个具体的字符,而字符指针变量中存放的是地址即字符串的首地址,通过指针指向相应的字符,而不是用指针变量去存放字符串中的每一个字符。(2)赋初值的方式不同。对数组赋初值要用static存储类型,例如:static str1=I will do my best!
20、;而对字符指针变量赋初值不必加static存储类型,例如:char *ps=I will do my best!;这是因为并没有对数组初始化,只是对指针变量初始化。8.4 指针与字符串8.4.3 使用字符指针变量与字符数组的区别(3)赋值方式不同。字符数组只能对各个元素赋值,不能用以下方法对字符数组赋值:char str14;str=I will do my best!;而对字符指针变量,可以采用下面的方法赋值:char *a;a=I will do my best!;但赋给a的不是字符,而是字符串的首地址。8.4 指针与字符串8.4.3 使用字符指针变量与字符数组的区别(4)指针变量赋初值时
21、方法灵活多样。例如,对以下的变量定义和赋初值:char *a=I will do my best!;等价于:char *a;a=I will do my best!;而对数组初始化时,可以在变量定义时整体赋初值,但不能在赋值语句中整体赋值,例如:static char str114=I will do my best!;不等价于:char str114;str1=I will do my best!;8.4 指针与字符串8.4.3 使用字符指针变量与字符数组的区别(5)定义一个数组,在编译时即已分配内存单元,有确定的地址。而定义一个字符指针变量,给指针变量分配内存单元,在其中可以放一个地址值,即该指针变量可以指向一个字符型数据,但如果未赋予它一个地址,则它并不具体指向哪一个字符数据。(6)指针变量的值是可以改变的,而数组名代表的是字符串的首地址,不能改变。8.5 指针数组与指向指针的指针8.5.1 指针数组 指针数组是指数组元素为指针的数组。前面介绍过数组元素可以为int型、float型和double型数值,称为数值数组;数组元素为char型的称为字符数组。由若干指向同一数据类型的指针构成的数组,则称为指针数组,即每个元素都是指针的数组。最常用的是一维一级指针数组,即该数组是一维的,它的每个
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 公务员宪法考试题及答案
- 妊娠合并哮喘的孕期营养支持策略
- 病理标本管理试题及答案
- 妇科肿瘤微创术后感染的多因素Logistic回归分析
- 女职工职业健康筛查标准制定
- 大数据驱动的慢性病精准防控路径
- 多重耐药菌感染暴发的早期识别与干预策略
- 会计考试答案及题目分值
- 2025年中职(机械加工技术)冲压工艺与模具试题及答案
- 多组学技术在精准医疗中的技术发展趋势
- 边坡支护安全监理实施细则范文(3篇)
- 6.1.3化学反应速率与反应限度(第3课时 化学反应的限度) 课件 高中化学新苏教版必修第二册(2022-2023学年)
- 北京市西城区第8中学2026届生物高二上期末学业质量监测模拟试题含解析
- 2026年辽宁轻工职业学院单招综合素质考试参考题库带答案解析
- 2026届北京市清华大学附中数学高二上期末调研模拟试题含解析
- 2026年马年德育实践作业(图文版)
- 医院实习生安全培训课课件
- 四川省成都市武侯区西川中学2024-2025学年八上期末数学试卷(解析版)
- 2026年《必背60题》抖音本地生活BD经理高频面试题包含详细解答
- 土方回填工程质量控制施工方案
- 2025年湖南城建职业技术学院单招职业适应性测试题库附答案
评论
0/150
提交评论