版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章指针目录CONTENTS指针与指针变量指针的运算指针与数组8.18.28.38.4指针与字符串指针与函数8.5
指针与指针变量8.1指针与指针变量指针的概念指针变量的定义指针的概念01内存单元
在计算机中所有的数据都是存放在存储器中的。一般把存储器中的一个字节称为一个内存单元。指针
为了方便管理,为每个内存单元编号。根据内存单元的编号就可以找到所需的内存单元。内存单元编号也叫地址,通常也把这个地址称为指针。指针变量
存放指针的变量指针变量的值
某个内存单元的地址单元地址存储单元00000H00001H00002H00003H00004H00005H…………FFFFEHFFFFFH
指针变量就是专门来存放内存地址的变量,它是一种特殊的变量,其特殊之处在于它的变量值是地址,而不是普通的数据。
定义指针变量的一般形式:
类型说明符*指针变量名;
其中:
*---表示这是一个指针类型的变量;
类型说明符---表示本指针变量所指向的变量的数据类型,即本指针变量中存放的是什么数据类型变量的地址。
指针变量名---为定义的指针变量的名字
例如:
int*p;指针变量的定义02指针的运算8.2
有关指针的两个运算符指针的运算赋值运算两个指针变量之间的运算加减算术运算pb&b31、取地址运算符&
取地址运算符&是单目运算符,其结合性为自右至左,其功能是取变量的地址,其操作数必须是变量。其一般形式为:
&变量名;
如:&a表示变量a的地址,&b表示变量b的地址。变量本身必须先定义。
若一指针变量p的值为另一变量a的地址,我们称该指针变量p指向了变量a。如若有: intb=3,*p; p=&b;
我们称p指向了b有关指针的两个运算符012、取内容运算符*
单目运算符,其结合性为自右至左,用来表示指针变量所指的变量。在*运算符之后的操作数必须是指针变量或指针常量。如: intb=3,*p;p=&b;
我们称*p得到的是变量b(或3)。
注意:在指针变量定义中,“*”是类型说明符,表示其后的变量是指针类型。而表达式中出现的“*”则是一个运算符用以表示指针变量所指的变量赋值运算02(1)把一个变量的地址赋予指向相同数据类型的指针变量。
inta,*pa; pa=&a;/*把整型变量a的地址赋予整型指针变量pa*/(2)把一个指针变量的值赋予指向相同类型变量的另一个指针变量。
inta,*pa,*pb;pa=&a;pb=pa;/*把a的地址赋予指针变量pb*/(3)把数组的首地址赋予指向数组的指针变量。
inta[5],*pa; pa=a;
也可写为:pa=&a[0];(4)把字符串的首地址赋予指向字符类型的指针变量。 char*pc; pc="clanguage";
或用初始化赋值的方法写为:
char*pc="cLanguage";指针的算术运算03
对指针变量,可以加上或减去一个整型量,也可以进行自增、自减运算。即下面的运算是合法的(p是指针变量)。 p+n,p-n,p++,++p,p--,--p(1)p=p+n:表示p向高地址方向移动n个存储单元(一个存储
单元是指指针变量所占的存储空间)。(2)p=p-n:表示p向低地址方向移动n个存储单元(一个存储单元是指指针变量所占的存储空间)。(3)p++、++p:
表示当前指针p向高地址移动1个存储单元。其中,p++表示先引用p,再将p向高地址方向移动一个存储单元,++p表示先移动指针再引用p。(4)p--、--p:表示当前指针p向低地址移动1个存储单元。其中,p--表示先引用p,再将p向低地址方向移动一个存储单元,--p表示先移动指针再引用p。
只有指向同一数组的两个指针变量之间才能进行运算,否则运算毫无意义。两指针变量相减
两指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。
如:inta[10],*p=&a[1],*q=&a[5];
则q-p的值为4。注意:两个指针变量不能进行加法运算。两指针变量进行关系运算
指向同一数组的两指针变量进行关系运算可表示它们所指数组元素之间的关系。例如: pf1==pf2表示pf1和pf2指向同一数组元素 pf1>pf2表示pf1处于高地址位置 pf1<pf2表示pf1处于低地址位置两个指针变量之间的运算04指针与数组8.3
指针与数组二维数组的指针表示一维数组的指针表示指针数组一维数组的指针表示01
一个数组的元素在内存中是连续存放的,数组第一个元素的地址称为数组的首地址。C语言规定数组名是该数组的首地址。
例如,有如下定义语句:
inta[10],*p;
则语句p=a;和p=&a[0]是等价的,都表示指针p指向数组a的首地址。注意:*C语言规定,数组首地址即数组名是一个地址常量,是不能改变的,a++;是非法的。
由于a+i为a[i]的地址,因此用指针给出数组元素的地址和内容有以下几种表示形式:
(1)p+i和a+i都表示a[i]的地址,它们都指向a[i]。
(2)*(p+i)和*(a+i)都表示p+i或者a+i所指向对象的内容,即a[i]。
(3)指向数组元素的指针,也可以表示成数组的形式,也就是说指针变量也可以带有下标,如p[i]与*(p+i)等价。例8.2:利用指针实现数组中的元素输入和输出。#include<stdio.h>intmain(){inta[10],*p,i;p=a;printf("请输入10个整数:");for(i=0;i<10;i++) scanf("%d",p+i);printf("输出10个整数:");for(i=0;i<10;i++) printf("%3d",*(p+i));return0;
}
一维数组的指针表示01二维数组的指针表示02二维数组元素的地址
对于一个具有n行m列的二维数组a,可以将a看成是一个长度为n的一维数组,数组中的每一个元素又是一个长度为m的一维数组。
从二维数组的角度来看,a代表二维数组的首地址,当然也可看成是二维数组第0行的首地址。a+1就代表第1行的首地址,a+2就代表第2行的首地址。 a[i]是一个一维数组名,即a[i]代表第i行的首地址,a[i]+j即代表第i行第j列元素的地址,即&a[i][j]。
可用指针的形式来表示二维数组各元素的地址。如前所述,a[0]与*(a+0)等价,a[1]与*(a+1)等价,因此a[i]+j就与*(a+i)+j等价,它表示数组元素a[i][j]的地址。
二维数组元素a[i][j]可表示成*(a[i]+j)或*(*(a+i)+j),它们都与a[i][j]等价,或者还可写成(*(a+i))[j]。即有如下关系成立。
a+i↔a[i]↔*(a+i)↔&a[i][0] *(*(a+i)+j)=a[i][j]用一级指针引用二维数组元素
由于二维数组在存储时是线性存储的,因而可以用一级指针来引用二维数组的元素。其一般形式为:
设有如下定义(其中M和N是已经定义了的符号常量): inta[M][N],*p=a[0];
则有: p+i*N+j表示了数组元素a[i][j]的地址;*(p+i*N+j)表示了数组元素a[i][j]。即有:
p+i*N+j↔&a[i][j] *(p+i*N+j)↔a[i][j]例8.4:求5阶方阵的主对角元素之和。#include<stdio.h> #defineM5 intmain() { inta[M][M],*p,i,j,sum=0; p=a[0]; printf("请输入方阵的各个元素:\n"); for(i=0;i<M;i++) for(j=0;j<M;j++) scanf("%d",p+i*M+j); for(i=0;i<M;i++) sum=sum+*(p+i*M+i); printf("主对角元素之和=%d\n",sum); return0; }
用指向由n个元素构成的一维数组的指针表示二维数组的元素
指向一个由n个元素所组成的数组指针的定义格式为:
类型说明符(*指针变量名)[大小];此指针也称为行指针。例如: int(*p)[5];
指针p为指向一个由5个元素所组成的整型数组指针。用行指针表示二维数组的一般形式为:
设有如下定义(其中M和N是已经定义了的符号常量): inta[M][N],(*p)[N]=a;则有:
p+i↔a+i↔a[i] *(p+i)+j↔&a[i][j] *(*(p+i)+j)↔a[i][j]例8.5:用行指针方式求5阶方阵的主对角元素之和。#include<stdio.h> #defineM5 intmain() {
inta[M][M],(*p)[M],sum=0; inti,j; p=a; printf("请输入方阵的各个元素:\n"); for(i=0;i<M;i++) for(j=0;j<M;j++) scanf("%d",*(p+i)+j); for(i=0;i<M;i++) sum=sum+*(*(p+i)+i); printf("主对角元素之和=%d\n",sum); return0; }
指针数组03
一个数组的若干元素均为指针型数据类型,称为指针数组。即每个元素都是指针类型的数组。
指针数组的定义形式为:
类型名*数组名[数组长度];
例如:int*p[6];
p是数组名,这个数组包括6个元素,p[0]-p[5],每个元素都是指向整型数据的指针,及p可以用于保存6个整型数据的地址。指针与字符串8.4
对字符串的操作有两种方法:一种方法是使用字符数组,另一种是使用字符指针。在字符串处理中,使用字符指针往往比使用字符数组更方便。
将字符串的指向数组名赋给一个字符串指针变量,让字符串指针变量指向字符串的首地址,这样就可以通过指向字符串的指针变量操作字符串,例如:
charstr[]="WelcomeToChina“,*p;
p=str;
printf("%s\n",p);
也可以不定义字符数组,而定义一个字符指针,用字符指针指向字符串中的字符。例如:
char*p="WelcomeToChina";
printf("%s\n",p);
还可以按以下形式赋值:
char*p;
p="WelcomeToChina";例:利用字符指针变量的方法,完成字符串的复制。#include<stdio.h>intmain(){charstr1[]="WelcometoWuhan!",str2[80];char*p1,*p2;inti;p1=str1;p2=str2;for(;*p1!='\0';p1++,p2++) *p2=*p1;*p2='\0';printf("str1is%s\n",str1);printf("str2is%s\n",str2);return0;
}
指针与函数8.5
指针与函组返回指针的函数指针作函数参数指向函数的指针指针作函数参数01指针变量既可以作为函数的形参,也可以作函数的实参。指针变量作参数时,参数传递是“地址传递”,即将实参(一个地址)传递给被调用函数的形参(必须是一个指针变量)。特点:共享内存,“双向”传递例:从键盘输入两个数,再从大到小输出#include<stdio.h>voidswap(int*p1,int*p2){intp;p=*p1;*p1=*p2;*p2=p;}intmain(){inta,b;int*pa,*pb;scanf("%d,%d",&a,&b);pa=&a;pb=&b;swap(pa,pb);printf("%d,%d\n",a,b);return0;}
例8.11:从键盘输入10个数,按从小到大的顺序输出。分析:要完成本题,我们需要完成下面4步:s1:输入10个数据;
s2:输出排序前的数据;s3:将数据进行排序;s4:输出排序后的数据。对于每一步我们用一函数来完成,为此,我们需要编写3个函数分别完成数据输入、数据排序、数据输出,再编写1个主函数调用这3个函数完成题目的要求。
一个函数可以返回一个整型值,实型值等,在有的情况下,我们希望通过函数返回一个指针值。返回指针值的函数称为返回指针的函数(或称指针函数)。定义返回指针的函数形式为:
类型说明符*函数名(类型
形参1,类型
形参2,…) {
函数体 }
函数名前面的“*”表示该函数是返回指针的函数,“类型说明符”是函数返回的指针所指向的数据类型。
返回指针的函数在被调用的时候必须注意:调用该函数给指针变量赋值,该指针变量的基类型必须与该函数返回的指针的基类型相同。返回指针的函数02例8.13:有若干学生的成绩(每个学生有5门成绩),要求在用户在输入学生序号以后,能输出该学生的全部成绩(要求用指针函数来实现)。#include<stdio.h> int*search(int(*pointer)[5],intn) { int*ptr; ptr=*(pointer+n); return(ptr); } intmain() { intscore[][5]={{60,70,80,90,87},{56,89,79,67,88},{34,78,82,90,66}}; int*search(int(*pointer)[5],intn);//函数声明
int*p,i,m; printf("请输入学生的序号:"); scanf("%d",&m); printf("序号为%d的学生的成绩是:\n",m); p=search(score,m); for(i=0;i<5;i++) printf("%3d\t",*(p+i)); printf("\n"); return0; }
指向函数的指针的定义
函数指针变量定义的一般形式为:
类型说明符(*指针变量名)();
其中“类型说明符”表示被指向的函数的返回值的类型。“(*指针变量名)”表示“*”后面的变量是定义的指针变量。最后的空括号表示指针变量所指的是一个函数。
例如:
int(*pf)();
表示pf是一个指向函数入口的指针变量,该函数的返回值(函数值)是整型。使用函数指针变量还应注意以下两点:(1)函数指针变量不能进行算术运算。(2)函数调用中"(*指针变量名)"的两边的括号不可少,其中的*不应该理解为求值运算,在此处它只是一种表示符号。03指向函数的指针
指向函数的指针变量的赋值
指向函数的指针变量名=函数名;
如:intfunc(inta,intb); int(*p)(inta,intb); p=func;
通过指向函数的指针变量调用函数
(*指针变量名)(实参表);例8.15:用指向函数的指针的方法求两个数的最大值。
#include<stdio.h> intMax(inta,intb) { if(a>b) returna; else returnb;} intmain() { intMax(inta,intb); int(*p
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026北京机械科学研究总院博士研究生招生47人模拟笔试试题及答案解析
- 地下室负二层底板补漏堵漏施工方案范例
- 深度解析(2026)《GBT 26110-2010锌铝涂层 技术条件》(2026年)深度解析
- 深度解析(2026)《GBT 26044-2010信号传输用单晶圆铜线及其线坯》(2026年)深度解析
- 深度解析(2026)《GBT 25930-2010红外线气体分析器 试验方法》
- 深度解析(2026)《GBT 25896.3-2010设备用图形符号 起重机 第3部分:塔式起重机符号》
- 2025重庆云阳县平安镇中心卫生院招聘1人备考笔试题库及答案解析
- 深度解析(2026)《GBT 25830-2010高温合金盘(环)件通 用技术条件》(2026年)深度解析
- 2025年铜陵市义安区检察院公开招聘编外聘用人员4名考试笔试备考题库及答案解析
- 功利主义与权利论视角下人脸识别门禁的伦理边界
- 2025大理州强制隔离戒毒所招聘辅警(5人)笔试考试备考题库及答案解析
- 2025年安全培训计划表
- 2026年榆林职业技术学院单招职业技能测试题库参考答案详解
- 2025年沈阳华晨专用车有限公司公开招聘笔试历年参考题库附带答案详解
- 2026(苏教版)数学五上期末复习大全(知识梳理+易错题+压轴题+模拟卷)
- 2024广东广州市海珠区琶洲街道招聘雇员(协管员)5人 备考题库带答案解析
- 垃圾中转站机械设备日常维护操作指南
- 蓄电池安全管理课件
- 建筑业项目经理目标达成度考核表
- 2025广东肇庆四会市建筑安装工程有限公司招聘工作人员考试参考题库带答案解析
- 第五单元国乐飘香(一)《二泉映月》课件人音版(简谱)初中音乐八年级上册
评论
0/150
提交评论