C语言程序设计基础(通识版 慕课版) 课件 第7章 指针及其应用_第1页
C语言程序设计基础(通识版 慕课版) 课件 第7章 指针及其应用_第2页
C语言程序设计基础(通识版 慕课版) 课件 第7章 指针及其应用_第3页
C语言程序设计基础(通识版 慕课版) 课件 第7章 指针及其应用_第4页
C语言程序设计基础(通识版 慕课版) 课件 第7章 指针及其应用_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

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

文档简介

第7章指针及其应用哈尔滨工业大学7.1指针的概念指针是C语言中的如意金箍棒“稀饭(CFans)”最挚爱的武器强转与指针,并称C语言的两大神器0x0037b0000x0037b0010x0037b0020x0037b003ainta=1;某存储区域1000ContentsContentsContents00b03700直接到变量名标识的存储单元中读取变量的值——直接寻址通过其他变量间接找到变量的地址读取变量的值——间接寻址&a7.1.1变量的地址和变量的寻址方式

printf("&a=%p\n",&a);变量首字节的地址

&a7.1.2指针变量的定义、初始化及其解引用指针(Pointer)类型的变量——指针变量int

*pa;//pa可以指向一个int型数据,但指向哪里不确定inta=1;pa=&a;int

*pa=&a;指针变量指向的数据类型,称为指针的基类型指针变量只能指向同一基类型的变量a某存储区域1000ContentsContentsContents????0x0037b000&apa00b037007.1.2指针变量的定义、初始化及其解引用

int*pa;

指针变量使用之前必须初始化若你不知把它指向哪里,那就指向NULL

int*pa=NULL;warning:'pa'isuseduninitialized空指针——无效指针(在stdio.h中定义为0)

7.1.2指针变量的定义、初始化及其解引用

如何访问指针变量指向的数据?间接寻址运算符——访问(引用)指针变量指向的变量的值指针的解引用(PointerDereference)#include<stdio.h>intmain(void){ inta=0; int*pa=&a; *pa=7; printf("a=%d\n",a); printf("*p=%d\n",*pa); return0;}*pa是a的别名(alias)解引用空指针

程序崩溃*pareturnsa(becausepapointstoa)7.2指针变量做函数参数如何在被调函数中改变实参的值?按地址调用(CallbyReference)为什么用指针变量作函数参数能改变主调函数中的变量的值?7.2指针变量做函数参数【例7.1】运行下面程序并分析程序的运行结果#include<stdio.h>voidReplace1(intvar);voidReplace2(int*var);voidDisplay(intvar);intmain(void){intoriginal=1;printf("beforereplace:");Display(original);Replace1(original);//第一次替换

printf("afterfirstreplace:");Display(original);Replace2(&original);//第二次替换

printf("aftersecondreplace:");Display(original);return0;}voidReplace1(intvar){var=0;}voidReplace2(int*var){*var=0;}voidDisplay(intvar){if(var==0){printf("0\n");}elseif(var==1){printf("1\n");}}7.2指针变量做函数参数7.2指针变量做函数参数7.2指针变量做函数参数7.2指针变量做函数参数7.2指针变量做函数参数【例9.2】从键盘任意输入两个整数,编程实现将其交换后再重新输出。请通过单步执行的方式运行下面程序,并分析哪个两数交换函数能够真正实现两数的交换。#include<stdio.h>voidSwap1(intx,inty);voidSwap2(int*x,int*y);intmain(void){ inta=15,b=8; printf("Beforeswap1:a=%d,b=%d\n",a,b); Swap1(a,b); printf("Afterswap1:a=%d,b=%d\n",a,b);a=15;b=8; printf("Beforeswap2:a=%d,b=%d\n",a,b); Swap2(&a,&b); printf("Afterswap2:a=%d,b=%d\n",a,b);return0;}voidSwap1(intx,inty){ inttemp; temp=x; x=y; y=temp;}voidSwap2(int*x,int*y){ inttemp; temp=*x; *x=*y; *y=temp;}7.2指针变量做函数参数【例9.2】从键盘任意输入两个整数,编程实现将其交换后再重新输出。请通过单步执行的方式运行下面程序,并分析哪个两数交换函数能够真正实现两数的交换。voidSwap1(intx,inty){ inttemp; temp=x; x=y; y=temp;}7.2指针变量做函数参数【例9.2】从键盘任意输入两个整数,编程实现将其交换后再重新输出。请通过单步执行的方式运行下面程序,并分析哪个两数交换函数能够真正实现两数的交换。voidSwap2(int*x,int*y){ inttemp; temp=*x; *x=*y; *y=temp;}7.2指针变量做函数参数思考:下面两个Swap()函数能否实现两数互换呢?voidSwap(int*x,int*y){int*pTemp;pTemp=x;x=y;y=pTemp;}voidSwap(int*x,int*y){int*pTemp;*pTemp=*x;*x=*y;*y=*pTemp;}例如,若有函数原型为:

intFun(inta,intb);则可定义函数指针

int(*f)(int,int);令f=Fun;就是让f指向函数Fun()编译器将不带()的函数名解释为该函数的入口地址函数指针变量存储的是函数在内存中的入口地址函数指针(FunctionPointer)就是指向函数的指针变量数据类型(*指针变量名)(形参列表);7.3.1函数指针的概念函数指针的定义而若有函数原型为:

floatFun(floata,floatb);则需定义函数指针

float(*f)(float,float);令f=Fun;定义时的参数类型与指向的函数参数类型不匹配

float(*f)(int,int);//错误 float(*f)();//不建议7.3.1函数指针的概念定义函数指针时的常见错误

int(*f)(int,int);忘了写前一个() int*f(int,int);

声明了一个函数名为f、返回值是整型指针类型的函数忘了写后一个() int(*f);

定义了一个整型指针变量7.3.1函数指针的概念7.3.1函数指针的概念【例7.3】下面程序仅用于演示函数指针的应用#include<stdio.h>voidFun(intx,inty,int(*f)(int,int));intMax(intx,inty);intMin(intx,inty);intmain(void){inta,b;scanf("%d,%d",&a,&b);Fun(a,b,Max);Fun(a,b,Min);return0;}voidFun(intx,inty,int(*f)(int,int)){intresult=(*f)(x,y);

printf("%d\n",result);}intMax(intx,inty){printf("max=");returnx>y?x:y;}intMin(intx,inty){printf("min=");returnx<y?x:y;}7.3.1函数指针的概念【例9.3】下面程序仅用于演示函数指针的应用7.3.1函数指针的概念【例9.3】下面程序仅用于演示函数指针的应用【例7.4】计算函数的定积分。采用如图9-22所示的梯形法编程计算如下两个函数在积分区间[a,b]内的定积分7.3.2函数指针的应用n为区间等分数floatIntegralF1(floata,floatb){floats,h;intn=100,i;s=(F1(a)+F1(b))/2;h=(b-a)/n;for(i=1;i<n;i++){s=s+F1(a+i*h);}returns*h;}floatF1(floatx){return1+x*x;}y1=IntegralF1(0.0,1.0);floatIntegralF2(floata,floatb){floats,h;intn=100,i;s=(F2(a)+F2(b))/2;h=(b-a)/n;for(i=1;i<n;i++){s=s+F2(a+i*h);}returns*h;}floatF2(floatx){returnx/(1+x*x);}y1=IntegralF2(0.0,3.0);7.3.2函数指针的应用y1=Integral(F1,0.0,1.0);y2=Integral(F2,0.0,3.0);floatIntegral(float(*f)(float),

floata,floatb){floats,h;intn=100,i;s=((*f)(a)+(*f)(b))/2;h=(b-a)/n;for(i=1;i<n;i++){ s=s+(*f)(a+i*h);}returns*h;}floatF1(floatx){return1+x*x;}floatF2(floatx){returnx/(1+x*x);}floatIntegralF1(floata,floatb){floats,h;intn=100,i;s=(F1(a)+F1(b))/2;h=(b-a)/n;for(i=1;i<n;i++){s=s+F1(a+i*h);}returns*h;}y1=IntegralF1(0.0,1.0);7.3.2函数指针的应用7.4指针和一维数组之间的关系int*p=a;inta[10];a[0]a[1]a[2]a[3]a[4]apaint*p=&a[0];a[5]a[6]a[7]a[8]a[9]当指针变量指向数组元素时可以使用指针代替数组下标进行操作对指针变量执行算术运算访问数组的其他元素对指针可以进行哪些算术运算?加上整数,减去整数,两个指针相减*p=5;57.4指针和一维数组之间的关系int*p;inta[10];a[0]a[1]a[2]a[3]a[4]aa[5]a[6]a[7]a[8]a[9]指针的算术运算允许通过对指针变量重复自增来访问数组的元素for(p=a;p<a+10;p++){printf("%4d",*p);}p7.4指针和一维数组之间的关系char*p,*q;chara[10];a[0]a[1]a[2]a[3]a[4]aa[5]a[6]a[7]a[8]a[9]两个指针指向同一个数组时,指针比较才有意义比较的结果依赖于数组中两个元素的相对位置p>=q为真(q>=p为假)p=&a[i];q=&a[j];pq7.4指针和一维数组之间的关系数组名代表数组的首地址&a[0]&a[i]↔(a+i)a+1不是加上1个字节,取决于a的基类型a+1

a+sizeof(基类型)a+i

a+i*sizeof(基类型)一维数组元素的等价引用形式a[i]↔*(a+i)用下标形式访问数组元素的本质计算该元素在内存中的地址inta[5];7.4指针和一维数组之间的关系为什么一个int型指针能指向一个int型的一维数组呢?int*p=a;int*p=&a[0];&a[0]是int型元素的地址p是int型指针,基类型是intp的基类型与它指向的元素类型相同a[i]↔*(a+i)&a[i]↔(a+i)inta[5];7.4指针和一维数组之间的关系a[i]↔*(a+i)&a[i]↔(a+i)#include<stdio.h>intmain(){

inta[5],i; for(i=0;i<5;i++) { scanf("%d",&a[i]); } for(i=0;i<5;i++) { printf("%4d",a[i]); } printf("\n"); return0;}#include<stdio.h>intmain(){

inta[5],i; for(i=0;i<5;i++) { scanf("%d",a+i); } for(i=0;i<5;i++) { printf("%4d",*(a+i)); } printf("\n"); return0;}9.4.2指针和一维数组的前世之缘a[i]↔*(a+i)int*p=a;inta[5];p[i]↔*(p+i)#include<stdio.h>intmain(){

inta[5],i,*p=NULL;

p=a; for(i=0;i<5;i++) { scanf("%d",&p[i]); }

p=a; for(i=0;i<5;i++) { printf("%4d",p[i]); } printf("\n"); return0;}7.4指针和一维数组之间的关系p++不是增加1字节,取决于p的基类型int*p=a;inta[5];#include<stdio.h>intmain(){

inta[5],*p=NULL; for(p=a;p<a+5;p++) { scanf("%d",p); } for(p=a;p<a+5;p++) { printf("%4d",*p); } printf("\n"); return0;}7.4指针和一维数组之间的关系被调函数的形参声明为数组类型,用下标法访问数组元素voidInputArray(inta[],intn){

inti; for(i=0;i<n;i++) { scanf("%d",&a[i]); } }voidOutputArray(int

a[],intn){

inti; for(i=0;i<n;i++) { printf("%4d",a[i]); } printf("\n");}【例7.5】编程分别用数组和指针变量作函数参数,先输入10个整型数,然后输出这10个整型数。#include<stdio.h>voidInputArray(inta[],intn);voidOutputArray(inta[],intn);intmain(void){ inta[10]; printf("Inputtennumbers:"); InputArray(a,10);

OutputArray(a,10);

return0;}7.4指针和一维数组之间的关系被调函数的形参声明为数组类型,用指针算术运算访问数组元素voidInputArray(inta[],intn){

inti; for(i=0;i<n;i++) { scanf("%d",a+i); } }voidOutputArray(int

a[],intn){

inti; for(i=0;i<n;i++) { printf("%4d",*(a+i)); } printf("\n");}【例7.5】编程分别用数组和指针变量作函数参数,先输入10个整型数,然后输出这10个整型数。#include<stdio.h>voidInputArray(inta[],intn);voidOutputArray(inta[],intn);intmain(void){ inta[10]; printf("Inputtennumbers:"); InputArray(a,10);

OutputArray(a,10);

return0;}7.4指针和一维数组之间的关系【例7.5】编程分别用数组和指针变量作函数参数,先输入10个整型数,然后输出这10个整型数。#include<stdio.h>voidInputArray(inta[],intn);voidOutputArray(inta[],intn);intmain(void){ inta[10]; printf("Inputtennumbers:"); InputArray(a,10);

OutputArray(a,10);

return0;}voidInputArray(int*p,intn){

inti; for(i=0;i<n;i++) { sc

温馨提示

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

评论

0/150

提交评论