资源描述
第9章 指针主讲教师:孙运雷计算机与通信工程学院 计算机科学系 18853283536教学要求理解地址与指针的概念熟悉指针变量的定义与使用理解数组与指针的关系P27利用指针返回多个值了解指针的应用本章主要内容地址与指针的概念指针变量的定义与使用一维数组与指针的关系指针的应用 引子swap函数的例子值传递:修改的只是副本那么传地址可行么?#include void swap(int a,int b)int temp=a;a=b;b=temp;int main()int a=3,b=6;swap(a,b);传地址swap(&a,&b);问题:思路可行否?怎么改?1)swap函数形参2)如何根据地址取到值?#include void swap(int x,int y)printf(调用时:x地址为:%p,值为:%dn,&x,x);printf(调用时:y地址为:%p,值为:%dn,&y,y);int temp;temp=x;x=y;y=temp;int main()int a=3,b=6;printf(a地址为:%p,值为:%dn,&a,a);printf(b地址为:%p,值为:%dn,&b,b);swap(a,b);printf(交换后:a地址为:%p,值为:%dn,&a,a);printf(交换后:b地址为:%p,值为:%dn,&b,b);return 0;void swap(int*x,int*y)printf(调用时:x地址为:%p,值为:%dn,x,*x);printf(调用时:y地址为:%p,值为:%dn,y,*y);int temp;temp=*x;*x=*y;*y=temp;变化:1)形参用*表示传递了地址!2)x和y是地址类型3)从地址取值用了*操作符swap(&a,&b);本章主要内容地址与指针的概念指针变量的定义与使用一维数组与指针的关系指针的应用 地址与指针的概念一一、地、地址址在计算机中,把内存区划分为一个一个的存储单元,每个单元为一个字节(bit),它们都有一个编号,这个编号就是内存地址。提示:1、程序中的执行代码和变量在执行前都在内存里保存。2、数据所占有的存储单元个数是由其类型决定的。3、首地址:第1个单元(0号)的地址如定义:char c=A;int k;.2000200120022005内存020030100000101000001k编译或函数调用时为其分配内存单元地址注意:注意:c和和k的地址可能相邻,也可的地址可能相邻,也可能不相邻,是由系统分配的,编程能不相邻,是由系统分配的,编程人员不用关心。人员不用关心。变量变量是对程序中数据是对程序中数据存储空间的抽象存储空间的抽象 二、变量与地址的关系 三、指针与指针变量 指针:在C语言中将变量的地址形象化地称为指针。指针变量:专门存放变量地址的变量.2000200820122010定义整型变量i10定义指针i_pointer指向i(=&i)2002200420062000指针指针指针变量指针变量 变量i的内容 变量i的地址指针变量指针变量i_pointer指向指向整型变量整型变量 i指针变量指针变量i_pointer变量变量i 变量值变量值指向指向地址存入地址存入指针变量指针变量变量变量i地址地址四、指针与指针变量的关系 本章主要内容地址与指针的概念指针变量的定义与使用一维数组与指针的关系指针的应用 前瞻(变量应用三阶段,定义、初始化+引用)定义int*aPointer;初始化int*aPointer;aPointer=NULL;/空指针,其实是0或者合并:int*aPointer=NULL;引用int a=3,b=6,tmp;int*pa=NULL,*pb=NULL;pa=&a;pb=&b;tmp=*pa;*pa=*pb;*pb=tmp;指针就是“标着门牌号门牌号的钥匙钥匙”用“&”记录了地址用“*”当钥匙使用指针时“*”有两个作用:定义时:标志标志一下,这是个指针 引用时:从该地址取出值取出值一、指针变量的定义一般形式:类型说明 *指针变量名;指针变量指向的变量的数据类型指针说明符*表示定义指针变量例如:int*p1,*p2;float x,*q;char *c;注意:指针变量定义后,其内容不确定,应用前必须先赋值如:int a,*p;p=&a;如:int a,*p1,*p2;p1=&a;p2=p1;如:int*p;p=NULL;表示空指针,即不指向任何单元,在头文件stdio.h中定义define NULL 0二、指针变量的赋值1.用变量的地址给指针变量赋值(使用求地址运算符&)注:只能用同类型变量的地址进行赋值!如定义:int *s;float f;则 s=&f;是非法的2.用相同类型的指针变量赋值3.赋空值若不需要指向某个特定的存储地址,或不确定指向时则赋空值。注意:下面赋值是非法的 int a,*p;p=2000;a=p;变量必须变量必须已定义已定义且且类型类型应一致应一致用用已初始化过已初始化过的指针变量作初值的指针变量作初值三、指针变量的初始化格式:类型说明 *指针变量名=初始地址;例int a,*p=&a;例int *p=&a,a;例int a;int *p=&a;int *q=p;【示例1】本例输出结果?#include int main()int a,b,*p_1=&a,*p_2=&b;a=100;b=10;printf(%d,%dn,a,b);printf(%d,%dn,*p_1,*p_2);printf(%p,%pn,p_1,p_2);return 0;【示例2】分析语句若有:int a=5,*p=&a;则(1)a*p&ap a=3*p=3(2)&与*互为逆运算&(*p)p *(&a)a(3)(*p)+a+不定pa不定5&a表示等价表示等价【示例3】指针变量可以进行的操作1)赋值:int a,*p1=&a;scanf(“%d”,p1);2)输出:printf(“%x”,p1);3)增减:(*p1)+;p1-;p1+=4;4)取内容:*p1=5;a=5;printf(“%d”,*p1);5)比较:通常与指针常量NULL进行比较,两指针变量值的大小比较往往是无意义的。【示例4】关于指针的增减运算假设&a1=0 x28ff18#include int main()int a1=3;int *p1;p1=&a1;printf(%xn,p1);p1+;printf(%xn,p1);return 0;p1+a10000001100000000000000000000000028ff1828ff1928ff1a28ff1bp128ff1c28ff1828ff1c变量的存取方式直接访问:通过变量本身对变量进行存取的方式。间接访问:通过指针变量实现对变量的访问方式。间接访问的过程是:由指针变量得到变量的地址,根据该地址找到变量的存储区,再对该存储区的内容进行存取,从而实现了对变量的间接访问int a,*p=&a;a=10;/*直接访问,结果a的值为10*/*p=*p+10;/*间接访问,结果a的值为20*/【示例5】找出具有等价关系的式子 int a=5,*p=&a;&*p *&a (*p)+&a a *p+*(p+)a+【示例6】读程序写结果#include int main()int a=2,*p=&a,*q=&a;printf(%d%dn,*p+,*(q+);p=&a;q=&a;printf(%d%dn,*p,(*q)+);printf(%dn,*q);return 0;222 23【例1】使两个指针变量交换指向#include int main()int a1=11,a2=22;int *p1,*p2,*p;p1=&a1;p2=&a2;printf(“%d,%dn”,*p1,*p2);p=p1;p1=p2;p2=p;printf(“%d,%dn”,*p1,*p2);return 0;p1&a11122a1p2a2&a2*p1*p2&a1&a2【例2】通过指针变量交换其所指向的变量的值#include int main()int a1=11,a2=22,t;int *p1,*p2;p1=&a1;p2=&a2;printf(“%d,%dn”,a1,a2);t=*p1;*p1=*p2;*p2=t;printf(“%d,%dn”,a1,a2);return 0;p1&a11122a1p2a2&a22211t 11*p2*p1【例3】用指针实现求1100的累加和#include int main()int i,sum=0;int *p1=&i;int *p2=∑for(i=1;i=100;i+)*p2+=*p1;printf(1+2+100=%dn,*p2);return 0;int i,sum=0;for(i=1;i=100;i+)sum=sum+i;printf(1+2+.+100=%dn,sum);【例4】用指针实现求10个数的和#include int main()int i,x,sum;int*p1=&x;/p1指向x int*p2=∑/p2指向sum*p2=0;/即sum=0 printf(输入10个整数:);for(i=0;i10;i+)scanf(%d,p1);*p2=*p2+*p1;printf(累加和为%dn,*p2);return 0;【例5】用指针实现求10个整数的累加和及平均值(用函数返回这两个值)#include#define N 10int fun(int x,int m,double*avg);int main()int a=1,2,3,4,5,6,7,8,9,10,sum;double average;sum=fun(a,N,&average);printf(%d,%.2fn,sum,average);return 0;int fun(int x,int m,double*avg)int i,sum=0;for(i=0;im;i+)sum=sum+xi;*avg=(double)sum/m;return sum;本章主要内容地址与指针的概念指针变量的定义与使用一维数组与指针的关系指针的应用 一维数组与指针一、一维数组的地址l数组名是表示数组首地址,即第一个数组元素的地址,a即为&a0l数组元素ai的地址是&ai,&a0,&a1l数组元素ai的地址可表示为a+i,即:a+i就是&ail数组元素ai可用*(a+i)表示#include int main()int i,a5=5,3,1,2,4;for(i=0;i5;i+)printf(“%d n”,*(a+i);508A 508E 5092 5096 509Aa0 a1 a2 a3 a4 a a+1+1 a+2+2 a+3+3 a+4+4如:int a5=3,5,2,1,4;二、指向数组元素的指针变量如定义:int a10,*p=a;则:p=&a0;若令:p=&ai 则:*p就是ai可见,当p=a时,有:&a0=a=p&ai=a+i=p+i=&piai=*(a+i)=*(p+i)=pia0a1a2a3a9.整型指针整型指针p&a0p指向数组的指针变量可以带下标指向数组的指针变量可以带下标二、指向数组元素的指针变量#include int main()int i,a5=5,3,1,2,4,*p;for(i=0;i5;i+)printf(%d,*(a+i);printf(n);/*地址法*/for(p=a;pa+5;p+)printf(%d,*p);printf(n);/*指针法*/注意:p是指针变量,取值可变,可指向各个数组元素a是数组名,是地址(指针)常量,其值不可变如定义:int a10,*p=a;则:p=&a0;若令:p=&ai 则:*p就是ai可见,当p=a时,有:&a0=a=p&ai=a+i=p+iai=*(a+i)=*(p+i)*a+三、指向数组元素的指针的算术运算运算含义p+p指向后一个数组元素p-p指向前一个数组元素p+i指向当前元素后第i个数组元素p-i指向当前元素前第i个数组元素p-q两个指针之间相差的元素个数关系运算pq:p在后p=q:指向同一元素a+i数组a中下标为i的元素如定义:int a10,*p=a,*q=a;p=ap+1/a+1*(p+i)a数组数组a0a1a2aia9p+i/a+ip+9/a+9四、数组元素的引用方法下标法a0a1a2a3a4指针法*a*(a+1)*(a+2)*(a+3)*(a+4)*p*(p+1)*(p+2)*(p+3)*(p+4)各元素地址&a0&a1&a2&a3&a4aa+1a+2a+3a+4pp+1p+2p+3p+4(1)下标法:如ai形式;(2)指针法:如*(a+i)或*(p+i)。如定义:int a5,*p=a;通过改变p的值,也可使p指向任意数组元素例:四种输出方法#include int main()int a5=1,2,3,4,5,*p=a,i;for(i=0;i5;i+)printf(%dt,ai);printf(n);for(i=0;i5;i+)printf(%dt,*(a+i);printf(n);for(i=0;i5;i+)printf(%dt,*(p+i);printf(n);p=a;for(i=0;i5;i+,p+)printf(%dt,*p);return 0;更常用方法更常用方法常用,直观常用,直观例:int a=1,2,3,4,5,6,7,8,9,10,*p=a,i=5;选择:数组元素地址的正确表示:(A)&(a+i)(B)a+(C)&p (D)p+I例:指出程序输出结果(略)int main()int a =5,8,7,6,2,7,3;int y,*p=&a1;y=(*-p)+;printf(“%d,”,y);printf(“%dn”,a0);pp58762730123456a6y=55 65 6例:指出程序中的错误,设a=5,8,7,6,2,7,3int main()int i,*p,a7;p=a;for(i=0;i7;i+)scanf(%d,p+);printf(n);for(i=0;i7;i+)printf(%2d,*p+);printf(n);p=a;【例1】用指针实现将数组倒置/*用下标变量实现*/#include#define N 5int main()int aN=5,4,3,2,1;int i=0,j=N-1,t;while(ij)t=ai;ai=aj;aj=t;i+;j-;for(i=0;iN;i+)printf(“%5dn,ai);/*用指针实现*/#include#define N 5int main()int aN=5,4,3,2,1;int *p=a,*q=a+N-1;int i,t;while(pq)t=*p;*p=*q;*q=t;p+;q-;for(p=a,i=0;iN;i+)printf(%5dn,*p+);本章主要内容地址与指针的概念指针变量的定义与使用一维数组与指针的关系指针的应用【例1】设10个整数的数组,求最大数的位置#include#define N 10int main()int i,aN,*p,*pMax;printf(输入%d个整数:,N);for(p=a;pa+N;p+)scanf(%d,p);pMax=a;for(p=a;p*pMax)pMax=p;i=pMax-a+1;printf(第%d个数最大,为%dn,i,*pMax);return 0;【例2】输入10个数,用选择法由小到大排序并输出#include#define N 10int main()int i,j,t,aN;printf(顺序输入%d个整数:,N);for(i=0;iN;i+)scanf(%d,&ai);for(i=0;iN-1;i+)/*控制比较的趟数*/for(j=i+1;jaj)t=ai;ai=aj;aj=t;printf(n排序后的序列为:n);for(i=0;iN;i+)printf(%d,ai);printf(n);return 0;下标下标法法交换法交换法【例2】输入10个数,用选择法由小到大排序并输出#include#define N 10int main()int aN,*p1,*p2,*pMin,t;printf(输入%d个整数:,N);for(p1=a;p1a+N;p1+)scanf(%d,p1);for(p1=a;p1a+N-1;p1+)pMin=p1;for(p2=p1+1;p2a+N;p2+)if(*p2 *pMin)pMin=p2;t=*pMin;*pMin=*p1;*p1=t;printf(排序后:);for(p1=a;p1a+N;p1+)printf(%d,*p1);return 0;指针指针法法选择法选择法Q&A
展开阅读全文