【文档说明】C语言程序设计-PPT-单元八使用指针访问数据.pptx,共(54)页,610.347 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-2205.html
以下为本文档部分文字说明:
C语言程序设计单元八导学【问题1】【问题2】一维数组是占用连续存储空间的数据,如何通过指针变量对这段内存空间进行操作?有一个整型变量a,如何知道该变量的存储地址?如何通过指针变量对a进行操作?目录2用指针操作一维数组3用
指针操作二维数组4用字符指针操作字符串1地址与指针地址与指针5返回地址的函数1地址与指针——内存地址编号就是内存地址变量m变量a占1字节占4字节20002001200220032004………………………………2011#include"stdio.h"
voidmain(){charm;inta;scanf(“%c”,&m);scanf(“%d”,&a);……}内存是以字节为单位的连续的存储空间。b1输入:b输入:11地址与指针——变量的存储地址20002001200220032004………………………………2011b1变量存储空间的第一个
字节对应的内存地址可看作是存储地址。变量m变量a存储地址根据存储地址就可找到相应的存储单元,所以通常也把地址称为指针。“路标上的地址”可用指针表示。1地址与指针——指针变量C语言允许用一种类型的变量来存放指针。指针变
量指针变量的值就是某个内存单元的存储地址。设指针变量pm、pa分别存放变量m、a的存储地址。pa=&apa的存储地址为200120002001200220032004………………………………2011b1
变量m变量a存储地址pm=&mpm的存储地址为20001地址与指针——指针变量的定义a*a普通变量指针变量inta;普通变量a的定义inta;指针变量a的定义*类型标识符*指针变量名;【形式】⑴“指针变量名”前的“*”表示该变量是指针变量
,不能省略。⑵“类型标识符”表示该指针变量所指向的变量的数据类型。⑶一个指针变量只能指向同一类型的变量。【说明】1地址与指针——指针变量的定义——示例int*p;//定义int型指针变量,变量名为pfloat*pf;//定义float型指针变量,变量名为pfchar*pc;//
定义char型指针变量,变量名为pcint*p;intn;p=&n;等价于int*p=&n;&npnnp指针表示简化的指针表示1地址与指针——指针变量的定义——示例charstr[20];//定义char型变量名为str的一维字符数组gets(ps);//为ps所指向的内存空间输入字符串
char*ps;ps=str;等价于char*ps=str;等价于gets(str);【注意】指针变量也可以被初始化为NULL,它的值为0。当指针值为零时,指针不指向任何有效数据,也称为空指针。1地址与指针——指针变量的基本使用intn=
10;int*p=&n;如何引用指针变量p输出n的值?printf("%d",*p);等价于printf("%d",n);*指针变量名⑴“*”为指针运算符,表示指针变量所指向内存单元的内容。⑵引用时的“*”不同于指针变量定义语句中的“*”。int*p;“
*”是指针标志符printf("%d",*p);“*”是指针运算符【格式】【说明】1地址与指针——指针变量的基本使用——示例通过指针变量访问的方式计算两个整数之和。#include"stdio.h"voidmain(){inta,b,s
;int*pa,*pb;pa=&a;pb=&b;scanf("%d%d",pa,pb);s=*pa+*pb;printf("s=%d\n",s);}//定义两个整型指针变量pa、pb//使pa指向a//使pb指向b//为pa,pb所指向的内存单元输
入值(10、20)//通过指针变量访问的方式求和(30)//输出求和结果//定义整型变量a、b代表两个加数,整型变量s存求和结果&apaa&bpbbs102030输入:1020301地址与指针——指针变量的基本使用——示例利用自定义函数ad
d()计算两个整数之和。#include"stdio.h"intadd(int*pa,int*pb){intsum;sum=*pa+*pb;returnsum;}voidmain(){inta,b,s;scanf("%
d%d",&a,&b);s=add(&a,&b);printf("s=%d\n",s);}//输入a、b的值(10、20)//求和结果通过return语句返回主函数//add()是自定义函数,形参pa、pb是指针变量//调用add函数,将&a→pa、&b→pb//
形参pa→a,形参pb→b,实现两个整数求和//输出求和结果&apaa&bpbbs102030&a&bsum30输入:1020301地址与指针——指针变量的基本使用——随堂练习#include<stdio.h
>voidadd(int*pa,int*pb,int*psum){*psum=*pa+*pb;}voidmain(){inta,b,s;scanf("%d%d",&a,&b);add(&a,&b,&s);printf("s=%d\n
",s);}试分析如下程序,看看是否能实现“利用自定义函数计算两个整数的和”?目录1地址与指针3用指针操作二维数组4用字符指针操作字符串5返回地址的函数2用指针操作一维数组用指针操作一维数组2用指针操作一维数组p=a;inta[5];int*p;//建立数组a
与指针p之间的关系等价于p=&a[0];如何建立数组a与指针p之间的关系?pp+1a+1p+2a+2p+3a+3p+4a+4a[1]a[0]a[2]a[3]a[4]a数组a内存单元2用指针操作一维数组pa+1a[1]a[0]a[2]a[3]a
[4]a数组a内存单元若有如下定义:inta[5],*p;p=a;a+1是a[1]的地址,a+i就是a[i]的地址。a+i………………关于地址:a+i&(a[i])p+i*(p+i)关于元素:a[i]*(a+i)等价关系如下:2用指针操作一维数组——示例利用两种方法,
输出一维数组各元素地址。#include"stdio.h"voidmain(){inta[5],*p,i;p=a;printf("⑴获取数组元素地址:\n");for(i=0;i<5;i++)printf("&a[%d]=%p\n",i,&a[i]);printf("⑵利用指针表示数
组元素地址:\n");for(i=0;i<5;i++)printf("p+%d=%p\n",i,p+i);}⑴获取数组元素地址:⑵利用指针表示数组元素地址:&a[0]=0018FF34&a[3]=0018FF40&a[4]=0018FF44&a[1]=0018FF38&a[2]=0018FF3
Cp+0=0018FF34p+1=0018FF38p+2=0018FF3Cp+3=0018FF40p+4=0018FF442用指针操作一维数组——示例输出一维数组各元素的值。#include"stdio.h"voidmain(){inta[5]={10,31,52,3,68},*p,i;p
=a;printf("⑴输出数组元素的值(下标法):\n");for(i=0;i<5;i++)printf("a[%d]=%d\n",i,a[i]);printf("⑵输出数组元素的值(下标法):\n"
);for(i=0;i<5;i++)printf("p[%d]=%d\n",i,p[i]);printf("⑶输出数组元素的值(指针法):\n");for(i=0;i<5;i++)printf("*(p+%d)=%d\n",i,*(p+i));
}⑴输出数组元素的值(下标法):⑵输出数组元素的值(下标法):a[0]=10a[3]=3a[4]=68a[1]=31a[2]=52*(p+4)=68p[0]=10p[3]=3p[4]=68p[1]=31p[2]=52⑶输出数组元
素的值(下标法):*(p+1)=31*(p+0)=10*(p+2)=52*(p+3)=32用指针操作一维数组——数组名作函数参数利用函数处理批量数据时,若实参是数组,形参可是数组也可是指针,实参、形参之间传递的是地址。#include"stdio.h"intsum(intp[],i
ntn){inti,t=0;for(i=0;i<n;i++)t+=p[i];returnt;}voidmain(){inta[5]={0,1,2,3,4},s;s=sum(a,5);printf("数组元素之和为:%d.\n",s);}形参(pn)实参(a5)数组元素之和为:10.用函数计算整型
数组各元素之和。2用指针操作一维数组——数组名作函数参数#include"stdio.h"intsum(int*p,intn){inti,t=0;for(i=0;i<n;i++)t+=*(p+i);returnt;}voidmain(){inta[5]={0,1,2,3
,4},s;s=sum(a,5);printf("数组元素之和为:%d.\n",s);}数组元素之和为:10.指针表示地址,它可作函数的参数。参数传递后指针指向数组的首地址。01234paa[1]a[0]a[2]a[3]a[4]参数传递过程:用指针作形参,计
算整型数组各元素之和。2用指针操作一维数组——数组名作函数参数⑴数组名作实参,对应的形参可是数组也可是指针,形参、实参的数据类型应一致。#include"stdio.h"intsum(intp[],intn){……}voi
dmain(){inta[5]={0,1,2,3,4},s;s=sum(a,5);……}#include"stdio.h"intsum(int*p,intn){……}voidmain(){inta[5]={0,1,2,3,4},s;s=su
m(a,5);……}形参是数组形参是指针数组名作实参数组名作实参【说明】2用指针操作一维数组——数组名作函数参数⑵进行函数调用时,将数组的首地址传给形参,形参的改变对实参产生影响。实参与形参共同占用一段内存,在函数执行过程中形参元素值发生变化,实参元素
值也会随之改变。#include"stdio.h"intsum(int*p,intn){……*(p+2)=10;……}voidmain(){inta[5]={0,1,2,3,4},s;s=sum(a,5);printf("数组元素之和为:%d.\n",s)
;printf(“a[2]=%d\n”,a[2]);}a[0]a[1]a[2]a[3]a[4]pa相当于:p=a;24310for(i=0;i<n;i++)t+=*(p+i);returnt;10数组元素之和为:18.a[2
]=10数组元素求和并返回【说明】目录1地址与指针2用指针操作一维数组4用字符指针操作字符串5返回地址的函数3用指针操作二维数组用指针操作二维数组3用指针操作二维数组——二维数组中所蕴含的地址关系inta[4][3]={{0,1,2},{3,4,5},{6,7,8},
{9,10,11}};a[0]a[1]a[2]a[3]a数组a由4个元素组成:a[0]、a[1]、a[2]、a[3]a[0]包含有3个元素:a[0][0]、a[0][1]、a[0][2],……a[0]a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]a[2][0]
a[2][1]a[2][2]a[1]a[2]210543876a[3][0]a[3][1]a[3][2]a[3]910113用指针操作二维数组——二维数组中所蕴含的地址关系aa+1a+2a代表二维数组的首地址,也是二维数组第0行的首地址。a+1代表第1行的首地址,……。由于第0行有3个整型元素
,所以第1行的首地址为1012,……。100010121024设此二维数组的首地址为1000。inta[4][3]={{0,1,2},{3,4,5},{6,7,8},{9,10,11}};a[0][0]a[0]
[1]a[0][2]a[1][0]a[1][1]a[1][2]a[2][0]a[2][1]a[2][2]210543876a[3][0]a[3][1]a[3][2]91011a+310361个整型变量占4个字节3用指针操作二维数组——二维数组中所
蕴含的地址关系得出a[0]a[1]a[2]⑴a[0]、a[1]、a[2]、a[3]分别代表二维数组各行的首地址⑵a[0]代表第0行中第0列元素的地址→&a[0][0];a[0]+1即代表第0行第1列元素的地址→&a[0][1];……a[i]+j即代表第i行第
j列元素的地址,即&a[i][j]inta[4][3]={{0,1,2},{3,4,5},{6,7,8},{9,10,11}};a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1
][2]a[2][0]a[2][1]a[2][2]210543876a[3][0]a[3][1]a[3][2]91011a[3]【说明】3用指针操作二维数组——二维数组中所蕴含的地址关系二维数组元素a[i][j]可
表示成⑶可用指针形式表示各元素的地址。a[0]等价于*(a+0),a[1]等价于*(a+1)。得出a[i]+j等价于*(a+i)+j,即代表第i行第j列元素的地址a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]a[2][0]a[2][1]a[2][2
]210543876a[3][0]a[3][1]a[3][2]91011inta[4][3]={{0,1,2},{3,4,5},{6,7,8},{9,10,11}};a[0]a[1]a[2]a[3]*(a[i]+j)、*(*(a+i)+j)、(*(a+i))[j]【说明】3用指针操作二维数
组——二维数组中所蕴含的地址关系①&a[i][j]②a[i]+j③*(a+i)+j二维数组元素a[i][j]的地址表示方式有:a[0]a[1]a[2]a[3]a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]a[2][0]a[
2][1]a[2][2]a[3][0]a[3][1]a[3][2]ainta[4][3];①a[i][j]②*(a[i]+j)③*(*(a+i)+j)④(*(a+i))[j]二维数组元素a[i][j]的表示方式有:3用指针操作二维数组——建立指针与二维数组的关系数组中的每个元素都是指针变量,根
据数组的定义,指针数组中每个元素都为指向同一数据类型的指针。指针数组,就是用指向同一数据类型的指针来构成一个数组。int*p[3],i;//定义指针数组p,包含3个指针变量p[0],p[1],p[2]inta[3][4]={{12,
3,5,61},{60,54,13,8},{71,9,19,24}};for(i=0;i<3;i++)p[i]=a[i];建立指针数组与二维数组之间的关系【示例】3用指针操作二维数组——建立指针与二维数组的关系12356160541387191924a[0]a[1]
a[2]a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]p[0]p[1]p[2]pint*p[3],i;inta[3][4]=
{{12,3,5,61},{60,54,13,8},{71,9,19,24}};for(i=0;i<3;i++)p[i]=a[i];3用指针操作二维数组——建立指针与二维数组的关系int*p[3],i;inta[3][4]=
{{12,3,5,61},{60,54,13,8},{71,9,19,24}};for(i=0;i<3;i++)p[i]=a[i];【通过指针p引用二维数组行地址a[i]的等价关系】p[i]*(p+i)a[i](*(p
+i))[j]p[i][j]*(p[i]+j)【通过指针p引用二维数组元素a[i][j]的等价关系】*(*(p+i)+j)3用指针操作二维数组——建立指针与二维数组的关系行指针变量--即指向的元素的数据类型为一维数组的指针变量。行指针每移动一个单位将移动一行的位置。
int(*p)[4];//定义行指针p,[4]代表指针所指向的行包含的元素个数。inta[3][4]={12,3,5,61,60,54,13,8,71,9,19,24};p=a;建立行指针与二维数组之间的关系【示例】3用指针操作二维数组——建立指针与二维数组的关系1235616054
1387191924a[0]a[1]a[2]a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]paint(*p)[4],i;inta[3][4
]={{12,3,5,61},{60,54,13,8},{71,9,19,24}};p=a;3用指针操作二维数组——建立指针与二维数组的关系【通过指针p引用二维数组行地址a[i]的等价关系】p[i]*(p+i)a[i](*(p+i))[j]p
[i][j]*(p[i]+j)【通过指针p引用二维数组元素a[i][j]的等价关系】*(*(p+i)+j)int(*p)[4],i;inta[3][4]={{12,3,5,61},{60,54,13,8},{71,9,19,2
4}};p=a;利用“指针数组”与“行指针”引用二维数组元素的实质是相同的。3用指针操作二维数组——通过普通指针变量引用二维数组元素可定义一个与二维数组元素类型相同的指针变量来访问二维数组元素。inta[3][4]={
12,3,5,61,60,54,13,8,71,9,19,24};int*p;p=a[0];//或者p=&a[0][0];建立普通指针与二维数组之间的关系【示例】3用指针操作二维数组——通过普通指针变量引用二维数组元素inta[3][4]={1
2,3,5,61,60,54,13,8,71,9,19,24};int*p;p=a[0];12356160541387191924a[0]a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2]
[1]a[2][2]a[2][3]p这种引用方式看不出指针变量p与二维数组各维存在什么样的关系。可通过指针的移动,再使用*p或p[i]来访问指针所指向的数组元素。3用指针操作二维数组——二维数组元素或数组名作函数参数二维数组元素作函数
实参,同前面所讲的一维数组元素或普通基类型数据做函数实参一样。二维数组元素作函数实参函数调用时,主调函数向被调函数单向数值传递,被调函数中的形参为同类型的形参变量,形参变量的值的改变不会影响实参的值。3用指针操作二维数组——二维数组元素或数组名作函数参数voi
dmain(){ints[5][6];……fun(s);//实参为二维数组名,即二维数组起始地址……}二维数组名作函数参数二维数组名作函数实参时,对应的形参可以是同情形的二维数组,也可以是一个行指针变量,并且要求类型一致。3用指针操作二维数组——二维
数组元素或数组名作函数参数⑵fun(inta[5][6])//形参为同情形的二维数组{…}或fun(inta[][6]){…}函数fun()可以是以下两种形式:⑴fun(int(*p)[6])//形参为行指针{…}当进行函数调用时,将二维数组的首地址传给形参,此时只为形参开辟一
个存放地址的存储单元,而不会在调用函数时为形参开辟一系列存放数组的存储单元。目录1地址与指针2用指针操作一维数组5返回地址的函数4用字符指针操作字符串用字符指针操作字符串3用指针操作二维数组4用字符数组操作字符串——字符串常量回顾“apple"由双引号括起来的字符序列--字符串常量。该字
符串由5个字符组成。但在内存单元中占用6个字节。在字符串存储中,C编译系统自动给字符串的末尾加上一个字符串结束符‘\0’。apple\04用字符数组操作字符串——字符指针charstr[]=“apple";字符串是存放在某存储区域的一串
字符序列,字符数组可表示字符串,也可用字符指针指向字符串,通过字符指针访问该存储区域。char*str;str=“apple";char*str=“apple";等价于apple\0strstr被定义为一个字符指针,它指向字符串常量。【示例】4用字符数组操作字符串——示例自定义函数rep
lace()实现字符替换功能。voidreplace(char*p,charoldc,charnewc){inti;for(i=0;p[i]!='\0';i++)if(p[i]==oldc)p[i]=newc;}指针p--访问要操作的字符串形参oldc--替换前的字符形参n
ewc--替换后的字符从p指向的第一个元素开始,依次判断p[i]是否与参数oldc所表示的字符相同,若是,则用newc替换oldc,当p所指向的字符为字符串结束标志'\0'时为止。【设计思想】4用字符数组操作字符串——示例#include"stdio.h"voidrepl
ace(char*p,charoldc,charnewc){inti;for(i=0;p[i]!='\0';i++)if(p[i]==oldc)p[i]=newc;}voidmain(){chars[]=“apple“,c1,c2;printf("\n原字符串为%s",s);printf("\n请
指定一个被替换字符:");c1=getchar();fflush(stdin);//清空输入缓冲区函数printf("请输入一个新字符:");c2=getchar();replace(s,c1,c2);printf("新字符串为%s\n",s);}pc1c2p
原字符串为apple请指定一个被替换字符:a请输入一个新字符:A新字符串为Appleoldcnewc4用字符数组操作字符串——随堂练习函数功能:计算一个字符串的实际长度。请填空。intstrlen(char*s){intlen=0;;;return(len);}while(*s++!='\0'
)len++;//字符指针s指向字符串的首地址//变量len实现计数目录1地址与指针2用指针操作一维数组3用指针操作二维数组5返回地址的函数返回地址的函数4用字符指针操作字符串5返回地址的函数——定义形式函数返回值可以是地址(指针)类型。char*str
cpy(char*dest,constchar*src)字符串复制用户也可根据需要编写返回值为地址(指针)的函数。类型标识符*函数名([形参列表]);int*f(int*x,int*y);函数的返回值为字符指针▲f是函数名,x、y是形参。▲函数的返回值为整型指针类型,也就是地址类型。【形式】【示
例】5返回地址的函数——示例自定义函数f(),实现返回两个整数中较大数的地址。#include"stdio.h"int*f(int*x,int*y){if(*x>*y)returnx;elsereturny;}voidmain(
){int*p,i,j;printf("请输入两个整数:");scanf("%d%d",&i,&j);p=f(&i,&j);printf("第一个数为%d,存储地址为:%p.\n",i,&i);printf("第二个数为%d,存储地址为:%p.\n",j,&j);printf("较
大的数为%d,存储地址为:%p.\n",*p,p);}//函数返回值是指针类型//返回变量x的地址//接收返回值的变量p是指针类型请输入两个整数:5010第一个数为50,存储地址为:0018FF40第一个数为10,存储地址为:0018FF3C较大的数为50,存储地址为:0018FF
405返回地址的函数【正确使用返回值为地址(指针)的函数,需做到三点】⑶主调函数中返回值的接收者也为指针类型。⑴函数定义时,在函数名前加“*”指明函数返回值为地址值。⑵函数返回值语句return中指明返回的是地址值。int*f(in
t*x,int*y){if(*x>*y)returnx;elsereturny;}voidmain(){int*p,i,j;……p=fun(&i,&j);……}5返回地址的函数——随堂练习下面函数的功能是:获取第n个数组元素的地址。getadd
(int*p,intn){return();}intp+n-1*//指针p指向数组首地址p表示第1个元素的地址p+1表示第2个元素的地址p+2表示第3个元素的地址……p+n-1表示第n个元素的地址目录1地址与指针2用指针操作一维数组3用指针操作二维数组4用字符指针操作字符串5返回地址的函数总
结指针与地址用指针操作一维数组用指针操作二维数组◆内存地址可看作存储地址◆地址可用指针表示◆inta[5],*p;数组名a是常量,指针p是变量◆通过语句p=a;建立指针p与数组a之间的关系◆数组名作函数实参,传递的是数组的首地址◆inta[4][3];数组名a代表数组的首地址◆各行首地址可表
示为a[i]或a+i◆各元素地址可表示为&a[i][j]或a[i]+j或*(a+i)+j总结用字符指针操作字符串返回地址的函数◆字符指针可操作字符串◆操作不确定字符串长度时使用字符指针更方便◆函数定义为指针型即可返回地址◆接收“返回地址的函数值”的
变量应设为指针型