C语言10学习教程.pptx
《C语言10学习教程.pptx》由会员分享,可在线阅读,更多相关《C语言10学习教程.pptx(77页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、1第十章 指针直接访问:按变量地址存取变量值 int k;编译时系统为整型变量k分配地址(假设)3000和3001 k=10;将10送到地址为3000开始的整型存储单元中 printf(“%d”,k);根据k与地址的对应关系,找到地址3000,从由3000开始的两个字节中取出数据10输出。30003000:1010k k第1页/共77页2第十章 指针间接访问:将变量k的地址放在另一个变量中 int *p;p是一个指针变量,专门存放变量的地址,编译时系统也为p分配地址(假设)4010和4011 p=&k;将k的地址存放到p中,即p里的值为3000。要取k中的值,可先从p中找到k的地址3000,再
2、从3000始取出k(2个字节)的值10第2页/共77页340104010:30003000k kp p1010强调:强调:p p是一个指针变量,指针变量的值是指针(地址)是一个指针变量,指针变量的值是指针(地址)第3页/共77页4第十章 指针变量的指针和指向变量的指针变量定义指针变量 基类型 *指针变量名举例int *px;指向整型变量的指针变量char*ch;指向字符型变量的指针变量float*p4;p是指向实型数据的指针数组,该数组中有4个指针元素,每个指针元素都指向一个实型数int*p1,k=10;float*p2,m=3.2;p1=&k;/*p1指向整型变量k*/p2=&m;/*p2指
3、向实型变量m*/第4页/共77页5第十章 指针指针变量的引用&:取地址运算符 *:指针运算符举例 int *p,num;p=#scanf(“%d”,p);printf(“num=%dn”,*p);不允许出现 p=2000 的形式指针须初始化才能使用 区分int*p 和 printf 语句中的*p的不同含义第5页/共77页6第十章 指针举例main()int*p1,*p2,a,b;a=100;b=200;p1=&a;p2=&b;printf(“%d,%dn”,a,b);printf(“%d,%dn”,*p1,*p2);100,200 100,200第6页/共77页7第十章 指针指针运算指
4、针与整数的加减运算指针+1 或 1 代表一个存储单元的长度,而一个单位长度占多少字节,则要根据指针的基类型而定。int*p,a4=2,4,6,8;p=&a0;(或p=a;)1010:1010:1011:1011:1012:1012:1013:1013:1014:1014:1015:1015:2 24 46 6p p:指向数组指向数组a a的首地址的首地址1010(&1010(&a0)a0)p+1p+1:指向指向a1a1的地址的地址1012(&1012(&a1)a1)p+3 p+3:指向指向a3a3的地址的地址10161016(&a3a3)*p*p:是是2 2*(p+1)*(p+1):是是4 4
5、*(p+3)*(p+3):是是8 88 81016:1016:1017:1017:第7页/共77页8第十章 指针 char *pchar *p,a=“yellow”a=“yellow”;p=a;/*p p=a;/*p指向了地址指向了地址1010*/1010*/p p:指向字符指向字符y y的地址的地址1010(&1010(&a0)a0)p+1p+1:指向字符指向字符e e的地址的地址1011(&1011(&a1)a1)p+4 p+4:指向字符指向字符o o的地址的地址1014(&1014(&a4)a4)*p*p:是是y y*(p+1)*(p+1):是是e e*(p+4)*(p+4):是是o o
6、1010:1010:1011:1011:1012:1012:1013:1013:1014:1014:1015:1015:y yl lo oe el lw w 结论:对于不同数据类型的指针结论:对于不同数据类型的指针p p,p p+n n表示的实际位表示的实际位 置的地址是:置的地址是:(p)p)+n n 数据类型字节长度数据类型字节长度第8页/共77页9第十章 指针指针和 运算 int *p,y,a6=12,21,35,10 52,15;p=a;p=p+1;/*p指向了地址1012*/y=*p+;y y=*p+;y 的值为的值为2121,p p的值为的值为10141014y=(*p)+;y y
7、=(*p)+;y 的值为的值为2121,10121012中的值为中的值为2222,p p的值仍是的值仍是10121012y=*(+p);py=*(+p);p的值为的值为10141014 ,y y 的值为的值为3535y=*+p;y=*+p;同上同上y=+(*p);y y=+(*p);y 的值为的值为2222,10121012中的值为中的值为2222,p p的值仍是的值仍是10121012 注意:以上各题的前提是注意:以上各题的前提是p p的值为的值为10121012,即即p p 指向指向a1a1的地址。的地址。1010:1010:1012:1012:1014:1014:1016:1016:10
8、18:1018:1020:1020:121235355252212110101515第9页/共77页10例:已知int x;则下面的说明指针变量pb的正确语句是A)int pb=&x B)int*pb=xC)int*pb=&x D)*pb=*xC C 例:已知例:已知int a=1,2,3,4,y,*p=&a1;int a=1,2,3,4,y,*p=&a1;则执行语则执行语句句y=(*-p)+;y=(*-p)+;后,变量后,变量y y的值为的值为A A)1 B1 B)2 C2 C)3 D3 D)4 4A A,之后之后a0=2a0=2第10页/共77页11 例:已知例:已知int x=1,3,5
9、,7,9,11,*p=x;int x=1,3,5,7,9,11,*p=x;则不则不能正确引用数组元素的语句是能正确引用数组元素的语句是 A A)*(p-)B*(p-)B)*(-p)*(-p)C C)*(p+)D*(p+)D)*(+p)*(+p)答案:答案:B B,A)1 A)1,B)B)不确定数,不确定数,C)1C)1,D)3 D)3第11页/共77页12第十章 指针main()int *p,k,s,t,m,n;int a=1,2,3,4,5,6;p=a;/*p指向1*/s=*p+;/*p指向2*/p=p+2;/*p指向4*/t=*(p-1);m=-(*p);p+;/*p指向5*/n=*+p;
10、/*p指向6*/printf(“s=%d,t=%d,m=%d,n=%dn”,s,t,m,n);for(p=a,k=0;k6;k+)printf(“%2d”,*p+);/*ak*/s=1,t=3,m=3,n=6s=1,t=3,m=3,n=61 2 3 3 5 61 2 3 3 5 6例:例:第12页/共77页13例:执行下列程序后:a的值为,b的值为,n的值为main()int a,b,k=2,m=4,n=6,*pk=&k,*p2=&m,*p3;a=pk=&k;b=4*(-*pk)/(*p2)+5;*(p3=&n)=*pk*(*p2);printf(“%d%d%dn”,a,b,n);A)1 B)
11、1 C)0 D)2A)3 B)5 C)7 D)8A)4 B)6 C)8 D)10 B B A A C Cb=4*(-k)/m+5;n=k*mb=4*(-k)/m+5;n=k*m第13页/共77页14例:写出运行结果main()int a=20,b=30,*pa,*pb;pa=&a;pb=&b;*pa=a+;*pb=b+;printf(“%d,%dn”,a,b);printf(“%d,%dn”,*pa,*pb);(*pa)+;(*pb)+;printf(“%d,%dn”,a,b);printf(“%d,%dn”,*pa,*pb);答案:答案:21,31 21,31 21,31 21,31 22,
12、32 22,32 22,32 22,32 第14页/共77页15第十章 指针例2:字符串复制函数cstrcpy(char*s,char*t)while(*s+=*t+);main()char a40,b40;char*p1,*p2;p1=a;p2=b;scanf(“%s”,p1);cstrcpy(p2,p1);puts(p2);cstrcpy(char s,char t)cstrcpy(char s,char t)int i=0;int i=0;for(i=0;i+)for(i=0;i+)si=ti;si=ti;if(ti=0)if(ti=0)break;break;第15页/共77页16第十
13、章 指针指针相减p 和 q 是指向同一数组、同一类型的指针,则p-q运算的结果值是两指针指向的地址位置之间的数据个数。可按下面公式计算:举例统计输入字符串的字符个数第16页/共77页17第十章 指针main()char str20;char*p;printf(“请输入一个字符串”);scanf(“%s”,str);p=str;while(*p!=0)p+;printf(“字符串的长度是:%n”,p str);第17页/共77页18第十章 指针指针变量作为函数参数先看一个例子:交换2个变量中的值swap(int x,int y)int temp;temp=x;x=y;y=temp;在主程序中调用
14、此函数的实参值是简单变量,传递方式是值传递,可见此函数不能实现两个变量值的交换。第18页/共77页19第十章 指针把上面的函数改造一下(见P208图10.9):swap(int*p1,int*p2)int temp;temp=*p1;*p1=*p2;*p2=temp;main()int a,b,*pa,*pb;scanf(“%d,%d”&a,&b);pa=&a;pb=&b;if(a b)swap(pa,pb);/*或 swap(&a,&b)*/printf(“n%d,%d n”,a,b);第19页/共77页20第十章 指针注意:swap函数不能写成下面的形式:swap(int*p1,int*p
15、2)int*p;*p=*p1;/*指针p 没有初始化*/*p1=*p2;*p2=*p;或swap(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;(见p210 图10.11)第20页/共77页21第十章 指针指针变量作函数参数也遵循单向的“值传递”方式,调用函数不能改变实参指针变量的值,但可以改变实参指针变量所指变量的值。指针变量作为参数,可以得到多个返回值。第21页/共77页22第十章 指针数组的指针和指向数组的指针变量指向数组元素的指针int a10,*p;p=a;或 p=&a0;也可写成:int a10,*p=a;用指针引用数组元素表示ai的地址:p+i 或 a+
16、i表示ai元素:*(p+i)或 *(a+i)指向数组的指针变量可以带下标 pi 与 *(p+i)等价第22页/共77页23第十章 指针下标法下标法 ai ai&aiai 指针法指针法 *(*(p+i)p+i)或或*(*(a+i)a+i)、pipi p+i p+i 或或 a+ia+i元素元素aiai的值的值元素元素aiai的地址的地址用指针法输入数组用指针法输入数组a a的的1010个元素个元素:for(p=a,i=0;i10;i+)for(p=a,i=0;i10;i+)scanf(“%d”,p+);scanf(“%d”,p+);或或 for(p=a;p a+10;p+)for(p=a;p a+
17、10;p+)scanf(“%d”,p);scanf(“%d”,p);或或 for(p=a,i=0;i 10;i+)for(p=a,i=0;i 10;i+)scanf(“%d”,p+i);scanf(“%d”,p+i);第23页/共77页24第十章 指针用指针法输出数组a的10个元素 for(p=a,i=0;i10;i+)printf(“%3d”,*p+);/*不必每次算地址,省时*/for(p=a;p a+10;p+)printf(“%d”,*p);/*同上*/for(p=a,i=0;i 10;i+)printf(“%d”,*(p+i);for(i=0;i 10;i+)printf(“%d”,
18、*(a+i);注意:指针变量注意:指针变量 p p 可以做自增和自减运算可以做自增和自减运算(p+p+、p-)p-),数组名数组名 a a 可以做可以做 a+a+或或 a-a-吗吗?第24页/共77页25 例:有以下语句例:有以下语句0=0=k6k6,则正确表示数组元素则正确表示数组元素地址的语句是地址的语句是static int x=1,3,5,7,9,11,*ptr=x,k;static int x=1,3,5,7,9,11,*ptr=x,k;A A)x+Bx+B)&ptr C&ptr C)&ptrk D&ptrk D)&(x+1)&(x+1)C C第25页/共77页26已知char s1
19、00;int i;则在下列引用数组元素的语句中,错误的表示形式是A.si+10B.*(s+i)C.*(i+s)D.*(s+)+i)答案:答案:D D,s s是数组名,是常量,所是数组名,是常量,所以以s+s+是错的是错的第26页/共77页27int a=1,2,3,4,5,6,*p=a;下列表达式中其值为5的是 A.p+=4,*(p+)B.p+=5,*p+C.p+=4,*+pD.p+=4,+*p答案:答案:A A第27页/共77页28在下面的程序中若第一个printf语句的输出为ffe2,则其余语句的输出结果分为_main()static int a=1,2,3,4,5,6,7,8,9,0,p
20、=a;printf(“%xn”,p);/*输出ffe2*/printf(“%xn”,p+9);/*/printf(“%dn”,*p+9);/*/printf(“%dn”,*(p+9);/*/printf(“%dn”,*+p+9);/*/A.ffeb B.ffed C.fff2 D.fff4A.9 B.10 C.11 D.0A.9 B.10 C.11 D.0A.9 B.10 C.11 D.0答案:答案:D D B B D D C Cp+9=ffe2+(2p+9=ffe2+(2 9)9)1010=ffe2+12=ffe2+1216 16=fff4=fff4第28页/共77页29第十章 指针数组名作
21、函数参数(p216)实参与形参的对应关系有以下4种情况:形参和实参都是数组名 main()f(int x,int n)int a10;.f(a,10);.传递的是a数组首地址,a 和 x 数组共用同一段内存单元 第29页/共77页30第十章 指针实参是数组名,形参用指针变量 main()f(int*x,int n)int a10;.f(a,10);.当调用函数时,做 x=&a0,通过x值的改变,可以指向 a 数组的任一元素。第30页/共77页31第十章 指针实参形参都用指针变量 main()f(int*x,int n)int a10,*p p=a;.f(p,10);.当调用函数时,p的值&a0
22、 传给形参指针变量x,x也指向了数组a 的起始地址,x值的改变可以使x指向数组a的任一元素。第31页/共77页32第十章 指针实参用指针变量,形参为数组名 main()f(int x ,int n)int a10,*p p=a;.f(p,10);.当调用函数时,是将x作为指针变量处理的第32页/共77页33第十章 指针指向多维数组的指针和指针变量多维数组的地址 int a34=1,3,5,7,9,11,13,15,17,19,21,23;a 是一个二维数组名,包含3个元素:a0,a1,a2。每一个元素又是一个一维数组,各包含4个元素。a a1 13 35 57 79 9111113131515
23、1717191921212323(2000)(2000)(2008)(2008)a+1a+1(2016)(2016)a+2a+2a0a0a1a1a2a2第33页/共77页34第十章 指针数组a=a0,a1,a2 每个元素ai的字节长度=4 2=8(B)而ai=ai0,ai1,ai2,ai3 每个元素aij的字节长度=1 2=2(B)由上可见,数组名a是二维数组的首地址,也是第0行的首地址;a+1指向a1(第1行的首址),1个元素 的 字 节 长 度 为 8,即 a+1=2000+8=2008;a+2=2000+28ai(i=0,1,2)是一维数组名,代表了各数组的首地址,a0表了第0行一维数组
24、中第0列元素地址,即&a00第34页/共77页35第十章 指针a0+1指向a0数组中第1个元素a01的地址&a01,一个元素的字节长度为2,所以a0+1=2000+12=2002 ai+j 指向第i行第j列的地址&aij综上所述,对整型数组a 二维数组a首址:a 第 i 行的首址:a+i 第 i 行第j列的地址:ai+j注意:a 与 ai 是基类型不同的指针 a+1 与 ai+1 中的1,单位字节长度不等第35页/共77页36由一维数组知道由一维数组知道 /*a=a0,a1,a2*/a0等价于*(a+0)/*一维数组:*(a+0)为元素值;二维数组:*(a+0)是地址*/a1等价于*(a+1)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 10 学习 教程
限制150内