《C语言程序设计》 课件09 指针_第1页
《C语言程序设计》 课件09 指针_第2页
《C语言程序设计》 课件09 指针_第3页
《C语言程序设计》 课件09 指针_第4页
《C语言程序设计》 课件09 指针_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言程序设计

2023翻转课堂实用教程第09章指针指针9.1指针与函数9.2

指针与数组9.39.1指针123指针的概念指针变量的定义与使用指针变量的运算知识点指针的案例分析案例分析指针相关练习题练习题9.1.1指针知识点程序在运行时,会为变量分配内存空间。分配的内存空间会有一个唯一的地址编号,在C语言中又叫做指针。通过指针可以找到该内存单元。地址取值范围:(32位系统为例)32位系统的内存条,32个元件,232个组合=4*230,4GB内存。内存地址编号从0X00000000到0XFFFFFFFF(十六进制表示)指针的概念指针变量保存某个内存空间的地址,并对该内存空间中的值进行操作。指针变量的定义方式为:数据类型名*指针变量名;或者数据类型名*指针变量名=地址值;1.指针变量的定义与使用指针变量指向的变量的数据类型指针变量声明符保存的是某个变量的地址int*pInt;//指向int型变量的指针char*pStr=NULL;//NULL为空指针,stdio.hint*pInt1,*pInt2;9.1.1指针知识点举例:doublenum=3.14;double*pDouble=#//定义一个指向double型变量num的指针pDouble1.指针变量的定义与使用指针变量pDouble指向num示意图&num3.14pDoublenum&取地址运算符,num的地址pDouble指向num9.1.1指针知识点指针变量占用的内存大小,仅与地址信息的大小有关,与类型无关。#include<stdio.h>intmain(){inta=100;charc='C';doubled=3.14;int*pInt=&a;char*pStr=&c;double*pDouble=&d;//分别输出int指针、字符指针、浮点型指针占用的字节数printf("%d%d%d",sizeof(pInt),sizeof(pStr),sizeof(pDouble));return0;}1.指针变量的定义与使用运行结果(64位系统,8个字节)8889.1.1指针知识点(1)取内容与取地址通过变量的地址/指针,同样可以访问到该变量的值。#include<stdio.h>intmain(void){ int*p,a=3; p=&a;

//两种获取变量a的方式,*p和a等价。 printf("*p的值为:%d,a的值为:%d\n",*p,a); *p=6;//通过指针p可以修改a的值 printf("*p的值为:%d,a的值为:%d\n",*p,a); return0;}2.指针变量的运算取内容,*p:p指向的变量a的值,等价取地址,&a:a的地址运行结果:*p的值为:3,a的值为:3*p的值为:6,a的值为:6&a3

pa*p9.1.1指针知识点(2)赋值运算doublenum=3.14,value=0.618;double*pDouble1=&num,pDouble2;//(a)pDouble1=&value;//(b)修改pDouble1的值,让其指向value变量pDouble2=pDouble1;//(c)2.指针变量的运算(a)(b)(c)9.1.1指针知识点(3)加法、减法和比较运算指针变量还可以进行加法、减法和比较运算,一般当指针变量指向数组中的元素时,才有实际的含义。2.指针变量的运算9.1.1指针知识点指针变量只能与整数常量i进行加减法运算,加或减同类型数据长度的i倍,指针往后或往前移动i个同类型的数据。指针pI的加减运算图#include<stdio.h>intmain(){

inta=30,*p=&a,*pI=&a;

doubleb=3.14,*pD=&b;

charc='C',*pC=&c;

//前3个输出语句,输出各个类型占用的字节数

printf("sizeof(int)is%d\n",sizeof(int));

printf("sizeof(double)is%d\n",sizeof(double));

printf("sizeof(char)is%d\n",sizeof(char));

printf("初始值,pI:%#X,pD:%#X,pC:%#X\n",pI,pD,pC);//第4个输出,先输出各个指针的最初值

pI--;pD=pD-1;pC--;//第5个输出,输出-1后的值

printf("地址-1后,pI:%#X,pD:%#X,pC:%#X\n",pI,pD,pC);

pI+=2;pD+=2;pC+=2;//第6、7个输出

printf("地址+2后,pI:%#X,pD:%#X,pC:%#X\n",pI,pD,pC);

printf("*pI:%d,*pD:%f,*pC:%c\n",*pI,*pD,*pC);

if(p==pI)printf("p和pI值相同,指向同一变量。");//第8个输出,比较p和pI指针

elseprintf("p和pI值不同。");

return0;}9.1.1指针知识点运行结果:sizeof(int)is4sizeof(double)is8sizeof(char)is1初始值,pI:0X62FE04,pD:0X62FDF8,pC:0X62FDF7地址-1后,pI:0X62FE00,pD:0X62FDF0,pC:0X62FDF6地址+2后,pI:0X62FE08,pD:0X62FE00,pC:0X62FDF8*pI:6487544,*pD:0.000000,*pC:p和pI值不同。(3)加法、减法和比较运算%#X是输出以0X开头的十六进制地址。9.1.2指针案例分析案例9.1.1指针变量运算案例分析#include<stdio.h>intmain(void){ int*p,*pI,a=3; double*pD,num=0.618; pI=&a;//p指向a printf("*pI的值为:%d,a的值为:%d\n\n",*pI,a);

//修改a变量的值,*p的值也跟着改变 a=33; printf("*pI的值为:%d,a的值为:%d\n\n",*pI,a);

//修改*p变量的值,a的值也跟着改变 (*pI)++; printf("*pI的值为:%d,a的值为:%d\n\n",*pI,a); //同类型的指针可以相互赋值,两者指向同一个变量a p=pI; printf("*p的值为%d,*pI的值为%d,a的值为%d\n",*p,*pI,a); //以十六进制形式输出p和pI的值,均为a的地址 printf("a的地址为%#0X;",&a); printf("p和pI的值为%#0X和%#0X\n\n",p,pI);

pD=# //*pD就是num的值0.618,*p就是a的值34 *pD=*pD+*p; //执行完上面代码后,*pD和num的值均变为了34.618 printf("*pD的值为:%f,num的值为:%f",*pD,num);return0;}*pI的值为:3,a的值为:3*pI的值为:33,a的值为:33*pI的值为:34,a的值为:34

*p的值为34,*pI的值为34,a的值为34a的地址为0X62FE04;p和pI的值为0X62FE04和0X62FE04

*pD的值为:34.618000,num的值为:34.618000课堂练习题9.1.1写出执行下面程序后的输出结果#include<stdio.h>intmain(){ inta=2,b=3; int*p1=&a,*p2=&b; printf("p1指向的值为:%d,p2指向的值为%d\n",*p1,*p2); p2=p1; *p2=b; printf("p1指向的值为:%d,a的值为%d",*p1,a); return0;}9.1.3指针课堂练习题课堂练习题9.1.2查找下面程序中的2处错误。输入a和b,并定义指针p1和p2分别指向a和b,通过取指针值的方式计算a和b的和,并输出和。#include<stdio.h>intmain(){ inta,b; int*p1,*p2; p1=&a,p2=&b; scanf("%d%d",&a,&p2); printf("a+b=%d",p1+*p2); return0;}课堂练习题9.1.3参照案例9.1.1,自行设计一个对指针操作的程序,并分析程序运行的结果。9.1.3指针课堂练习题9.2指针与函数123指针变量作为函数参数数组名作为函数参数知识点指针与函数案例分析案例分析指针与函数相关练习题练习题指针变量作为函数的参数时:将函数外部某些变量的地址传递到函数内部,在函数内部通过这些外部变量的地址操作这些外部变量。1.指针变量作为函数的参数9.2.1指针与函数知识点案例9.2.1编写calculate函数来计算两个double类型变量a和b的和与差,并将和sum与差diff返回给main函数。9.2.1指针与函数知识点对于需要函数返回多个值的情况:可以将这两个变量sum和diff定义为全局变量(案例8.2.1);还可以将这两个变量作为函数的入参。参数该如何传递?9.2.1指针与函数知识点#include<stdio.h>voidcalculate(intsum,intdiff,inta,intb){ sum=a+b; diff=(a>b?a-b:b-a); printf("Incalculate,sumis%d,diffis%d\n",sum,diff);}intmain(){ inta,b,sum=0,diff=0; printf("请输入整型a和b的值:"); scanf("%d%d",&a,&b); calculate(sum,diff,a,b); printf("Inmain,sumis%d,diffis%d",sum,diff); return0;}请输入整型a和b的值:2310↙Incalculate,sumis33,diffis13Inmain,sumis0,diffis0案例9.2.1程序代码(错误实例)calculate()函数中计算出来sum和diff的值,这个结果并没有返回给calculate()函数的调用者main()。分析原因(1)calculate与main中的sum和diff,不同变量,作用域不同、所占内存空间不同。(2)sum、diff、a、b的值单向依次传给了calculate()的形式参数。以值传递,传递的是数值。9.2.1指针与函数知识点#include<stdio.h>voidcalculate(int*pSum,int*pDiff,inta,intb){ *pSum=a+b; *pDiff=(a>b?a-b:b-a);}intmain(){ inta,b,sum=0,diff=0; printf("请输入整型a和b的值:"); scanf("%d%d",&a,&b); calculate(&sum,&diff,a,b); printf("sumis%d,diffis%d",sum,diff); return0;}请输入整型a和b的值:2310↙sumis33,diffis13案例9.2.1程序代码(正确实例)main()函数将sum和diff的地址值传给形参calculate中的pSum、pDiff;calculate中*pSum和*pDiff就是sum和diff。以值传递,传递的是地址信息。总结,通过函数调用改变某个变量的值,需要满足三个条件:①首先在主调函数中,传入函数的实际参数需要是该变量地址;②其次函数的形参需要是与该变量同类型的指针;③最后在函数内部,改变形参所指向的变量的值。用指针变量作为函数参数的方式,也可以实现函数返回多个变量的情况1.指针变量作为函数的参数9.2.1指针与函数知识点数组名实际上就是一个指针常量,主调函数将数组名传递给被调函数时,仅仅是数组的首地址,在被调函数中无法获得数组元素的个数,还需要一个整型参数来表示数组的元素个数。2.数组名作为函数的参数9.2.1指针与函数知识点要求:输入两个整数a,b,编写swap函数,通过调用swap函数实现a和b的交换。问题分析:如果希望通过函数调用改变a和b的值,需要满足三个条件:①首先在主调函数中,传入函数的实际参数需要是a和b的地址;②其次函数的形参需要是同类型的指针;③最后在函数内部,改变形参所指向的变量的值。案例9.2.2定义函数交换两个变量的值9.2.2指针与函数案例分析扫码观看视频9.2.1指针与函数知识点#include<stdio.h>voidswap(int*pA,int*pB){ inttmp; tmp=*pA; *pA=*pB; *pB=tmp;}intmain(){ inta,b; printf("请输入整型a和b的值:"); scanf("%d%d",&a,&b); swap(&a,&b); printf("Afterswap,ais%d,bis%d",a,b); return0;}案例9.2.2

代码请输入整型a和b的值:2350↙afterswap,ais50,bis23ab2350pApB*pA*pBtmp2350239.2.3指针与函数课堂练习题课堂练习题9.2.1运行下面的代码,查看swap1函数是否可以交换a和b变量的值?并分析原因。#include<stdio.h>voidswap1(int*pA,int*pB){ int*tmp; tmp=pA; pA=pB; pB=tmp;}intmain(){ inta,b; printf("请输入整型a和b的值:"); scanf("%d%d",&a,&b); swap1(&a,&b); printf("Afterswap,ais%d,bis%d",a,b); return0;}9.2.3指针与函数课堂练习题课堂练习题9.2.2编写函数,求两个整数的和与差,可采用传入和与差的指针的形式。输入两个整数a和b,编写函数calc来计算a-b和a+b。课堂练习题9.2.3:编写函数,通过身份证号计算年龄。函数有两个形式参数:一个是存储身份证号的字符数组,另一个为整型指针,指向的是保存年龄的变量。9.3指针与数组123采用指针访问数组指针间的比较运算知识点指针与数组案例分析案例分析指针与数组相关练习题练习题9.3.1指针与数组知识点数组名:数组的首地址,第一个元素的地址。若数组array元素类型为Type,则array值就和&array[0]一致,array的类型为Type*类型的指针常量。系统在为数组分配一块连续的内存空间后,数组的首地址就已经确定了,除非销毁,不会改变,所以为指针常量。为什么数组名是一个指针常量?9.3.1指针与数组知识点举例:int*p,array[5]={30,20,50,10,40};p=array;p的值为&array[0],*p为array[0]p+i表示相对于当前指针p往后偏移i个整数的位置(1)采用指针访问数组

array[0]array[1]array[2]array[3]array[4]3020501040

arrayarray+1

array+2array+3array+4p

p+1p+2p+3

p+49.3.1指针与数组知识点(1)采用指针访问数组采用指针获取数组元素、地址的方式元素获取内容array[0]array[1]array[2]array[3]array[4]获取元素的值array[0]*array*pp[0]array[1]*(array+1)*(p+1)p[1]array[2]*(array+2)*(p+2)p[2]array[3]*(array+3)*(p+3)p[3]array[4]*(array+4)*(p+4)p[4]获取元素的地址&array[0]arrayp&array[1]array+1p+1&array[2]array+2p+2&array[3]array+3p+3&array[4]array+4p+4参见9.3.2章节中案例9.3.1的代码及运行结果数组名可以作为指针来使用,指针变量可以作为数组形式来使用。9.3.1指针与数组知识点(1)采用指针访问数组指针变量与数组名,两者有什么区别呢?(1)p为指针变量,数组array是指针常量。p=array+i,array=array+i。(2)作为sizeof运算符的操作数时sizeof(array):为array所代表的整个数组占用的总字节数。sizeof(p):为p指针占用的字节数数组名不可以作为赋值=左边的操作数。9.3.1指针与数组知识点(1)采用指针访问数组举例:intarray[5]={30,20,50,10,40},*p=array+2;p-1

是?p+2是?利用指针p,可以随机从某一个元素开始往前往后访问数组元素。array[2]前面一个元素,p-1为&array[1]p+2为&array[4]9.3.1指针与数组知识点(2)指针间的比较运算当两个指针均指向同一个数组中的元素时,两个指针可以进行两类运算:

关系运算:

><≠相减的运算9.3.1指针与数组知识点(2)指针间的比较运算举例:intarray[5]={30,20,50,10,40};int*p1=&array[3],*p2=array,*p;3020501040arrayp1p2①

以下式子成立:p1>p2、p2<p1、p1≠p2p1-p2为3基于上面的比较运算,使用指针p作为循环变量,p:[array,&array[4]],p++,可以遍历数组array的所有元素。for(p=array;p<=&array[N-1];p++){ printf("%d",*p);}或for(p=array;p<array+N;p++){ printf("%d",*p);}9.3.2指针与数组案例分析案例9.3.1指针与数组关系的应用#include<stdio.h>#defineN10intmain(){

int*p,array[N],i;

p=array;

for(i=0;i<N;i++){

scanf("%d",array+i);

}

//输出元素的地址,每两个一行

for(i=0;i<N;i++){

printf("%#X",(array+i));

if((i+1)%2==0&&i!=9)printf("\n");

}

printf("\n");

//三种通过p指针来获取元素值的代码

for(i=0;i<N;i++){

printf("%d",*(p+i));

}

printf("\n");

for(i=0;i<N;i++){

printf("%d",p[i]);

}

printf("\n");

for(p=array;p<=&array[N-1];p++){

printf("%d",*p);

}

return0;}运行结果:2310458913572861↙0X62FDE00X62FDE40X62FDE80X62FDEC0X62FDF00X62FDF40X62FDF80X62FDFC0X62FE000X62FE042310458913572861231045891357286123104589135728619.3.2指针与数组案例分析案例9.3.2编写函数求解数组a中的最大元素值,并验证函数的正确性。#include<stdio.h>/*入参inta[]等价与int*a,为一个整型指针变量*/intgetMin(inta[],intn){/*等价于intgetMin(int*a,intn)*/ inti,min=a[0]; for(i=1;i<n;i++){ if(min>a[i])min=a[i]; } returnmin;}intmain(){ intarray[9]={3,5,2,9,6,8,7,4,0};

//数组名a为整数指针常量,作为getMin的第一个实际参数,将a的首地址传进去 printf("getMinis%d",getMin(array,9)); return0;}运行结果:getMinis09.3.2指针与数组案例分析案例9.3.2编写函数求解数组a中的最大元素值,并验证函数的正确性。#include<stdio.h>/*入参inta[]等价与int*a,为一个整型指针变量*/intgetMin(inta[],intn){/*等价于intgetMin(int*a,intn)*/ inti,min=a[0]; for(i=1;i<n;i++){ if(min>a[i])min=a[i]; } returnmin;}intmain(){ intarray[9]={3,5,2,9,6,8,7,4,0};

//数组名a为整数指针常量,作为getMin的第一个实际参数,将a的首地址传进去 printf("getMinis%d",getMin(array,9)); return0;}运行结果:getMinis09.3.2指针与数组案例分析案例9.3.3使用指针操作数组的案例分析要求:分析下面的代码,理解数组名作为函数参数,转化为同类型指针的用法。#include<stdio.h>intgetMin(inta[],intn){ inti,min

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论