《浙江大学C颜晖原版课件C8.pptx》由会员分享,可在线阅读,更多相关《浙江大学C颜晖原版课件C8.pptx(88页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、8.1 指针变量地址内容int x;x=3;printf(“%d”,x;)x20013px30002001直接访问:通过变量名直接访问地址间接访问:把变量的地址放到另一变量中,使用时先找到后者的地址,从中取出前者的地址指针变量地址另一变量的地址第1页/共88页变量地址内容x20013px30002001指针变量地址另一变量的地址指针变量:存放地址的变量某个变量的地址指向指向int x;x=3;printf(“%d”,x;)第2页/共88页8.1.1 指针变量的定义指针变量所指向变量的类型int *px;px 是整型指针,指向整型变量float*pf;pf 是浮点型指针,指向浮点型变量char*
2、pc;pc 是字符型指针,指向字符型变量类型名 *指针变量名;第3页/共88页类型名 *指针变量名;int *p1,*p2;等价于 int*p1;int*p2;int *px;注意:指针变量名是 px,不是*px 第4页/共88页8.1.2 指针的基本操作*p:p所指向的变量 aa3&ap*p1、&和*&取地址运算符 *指针运算符(间接访问运算符)int*p,a=3;p&a;把 a 的地址赋给 p,即 p 指向 a第5页/共88页a3&ap*p输入 5 7输出:3,35,57,710,10main()int a=3,*p;p=&a;printf(“%d,%dn”,a,*p);scanf(“%d
3、”,&a);printf(“%d,%dn”,a,*p);scanf(“%d”,p);printf(“%d,%dn”,a,*p);*p=10;printf(“%d,%dn”,a,*p);例8.1指针运算第6页/共88页b10&bp2*p2输出:100,10100,10a100&ap1*p1main()int a,b;int*p1,*p2;a=100;b=10;p1=&a;p2=&b;printf(“%d,%dn”,a,b);printf(“%d,%dn”,*p1,*p2);例8.2指针运算第7页/共88页a3&ap*p指针运算注意事项(1)当 p&a 后,*p 与 a 相同。(2)int*p;定
4、义 *p=10;p所指向的变量(3)&*p 与&a 相同,是地址 *&a 与 a 相同,是变量第8页/共88页a3&ap*p当 p&a 时(4)(*p)+等价于 a+将p所指向的变量值加1 *p+等价于*(p+)先取*p,然后 p 自加,此时p不再指向a第9页/共88页2、赋值=a3&ap1p2p1;p2 也指向 a&ap2*p1*p2int*p1,*p2,a=3;p1&a;把 a 的地址赋给 p1,即 p1 指向 a第10页/共88页输出:10,100例8.3指针赋值main()int a,b;int*p1,*p2;a=100;b=10;p1=&a;p2=p1;p1=&b;printf(“%
5、d,%dn”,*p1,*p2);b10p1a100p2第11页/共88页8.1.3 指针变量的初始化例8.4-1 void main()int a=1,b=2;int*p1=&a,*p2=&b,*pt;printf(“%d,%dn”,*p1,*p2);pt=p1;p1=p2;p2=pt;printf(“%d,%dn”,*p1,*p2);b2&bp2a1&ap1b2&ap2a1&bp1第12页/共88页8.1.3 指针变量的初始化例8.4-2void main()int a=1,b=2;int*p1=&a,*p2=&b,t;printf(“%d,%dn”,*p1,*p2);t=*p1;*p1=*
6、p2;*p2=t;printf(“%d,%dn”,*p1,*p2);b2&bp2a1&ap1b1&bp2a2&ap1第13页/共88页8.1.4 指针作为函数的参数swap1(int x,int y)int t;t=x;x=y;y=t;输出:3,5a35bx35yx53y例 8.5main()int a=3,b=5;swap1(a,b);printf(“%d,%dn”,a,b);第14页/共88页swap2(int*p1,int*p2)int t;t=*p1;*p1=*p2;*p2=t;输出:5,335abp1p25335值传递,地址未变,但存放的变量的值改变了main()int a=3,b=
7、5;swap2(&a,&b);printf(“%d,%dn”,a,b);第15页/共88页swap3(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;35abp1p2值传递,形参指针的改变不会影响实参main()int a=3,b=5;swap2(&a,&b);printf(“%d,%dn”,a,b);输出:3,5第16页/共88页swap2(int*p1,int*p2)int t;t=*p1;*p1=*p2;*p2=t;main()int a=3,b=5;swap2(&a,&b);要使某个变量的值通过函数调用发生改变(1)在主调函数中,把该变量的地址作为实参(2)在被
8、调函数中,用形参(指针)接受地址(3)在被调函数中,改变形参(指针)所指向变量的值第17页/共88页例8.6-1 指针作为函数的参数void p(int*a,int b)*a=*a-1;b+;void main()int x=3,y=5;p(&x,y);printf(%d,%dn,x,y);调用前 main:x=3,y=5调用p:*a b 3 5 2 6调用后 main:x=2,y=5将变量的地址作为实参,调用后,该变量的值可能改变第18页/共88页例8.6-2void p(int*a,int b)*a=*a-1;b+;void main()int x=3,y=4;p(&y,x);printf
9、(%d,%dn,x,y);调用前 main:x=3,y=4调用p:*a b 4 3 3 4调用后 main:x=3,y=3第19页/共88页例8.6-3void p(int*a,int b)*a=*a-1;b+;void main()int x=3,y=5;p(&x,y);printf(%d,%dn,x,y);p(&y,x);printf(%d,%dn,x,y);调用前 main:x=3,y=5第1次调用p:*a b 3 5 2 6调用后 main:x=2,y=5第2次调用p:*a b 5 2 4 3调用后 main:x=2,y=4第20页/共88页例7-9自定义函数dayofyear(yea
10、r,month,day),返回该年的第几天。dayofyear(2000,3,1)返回61dayofyear(1981,3,1)返回60分析:月 0 1 2 311 12非闰年 0 31 28 31 30 31闰年 0 31 29 31 30 31int tab213=0,31,28,31,30,31,30,31,31,30,31,30,31 0,31,29,31,30,31,30,31,31,30,31,30,31第21页/共88页例7-9void dayofyear(int year,int month,int day)int k,leap;int tab213=0,31,28,31,30
11、,31,30,31,31,30,31,30,31 0,31,29,31,30,31,30,31,31,30,31,30,31;leap=(year%4=0&year%100!=0)|year%400=0;for(k=1;ktableapk;k+)yearday=yearday-tableapk;*pmonth=k;*pday=yearday;第24页/共88页8.2 指针和数组8.2.1 指针、数组、地址间的关系8.2.2 数组名做为函数的参数第25页/共88页8.2.1 指针、数组、地址间的关系指针和数组有密切的关系任何由数组下标来实现的操作都能用指针来完成。int a10;a0a1a9ai
12、数组名是一个指针它的值是数组首元素的地址即它指向数组的首元素a第26页/共88页int*ap;ap=&a0;ap 指向数组a的首元素a0a1a9aiaa+1a+ia+9*(a+i)&ai或:ap=a;ap,ap+i,*(ap+i)ai的地址&ai a+i、ap+iai 相当于*(a+i)*(ap+i)、api第27页/共88页a0a1a9aiaa+1a+ia+9*(a+i)&aiap,for(i=0;i10;i+)printf(”%d”,*(a+i)for(ap=a;apa+10;ap+)printf(”%d”,*ap)注意:数组名 a 是指针常量,不能 a+for(i=0;i10;i+)pr
13、intf(”%d”,ai)例:输出数组a所有元素第28页/共88页1、数组元素作为函数实参 函数形参为变量 (与变量作为函数实参相同,值传递)2、数组名作为函数参数由于数组名是指针常量,相当于指针作为函数的参数数组名做为实参 形参是指针变量(数组)8.2.2 数组名作为函数的参数第29页/共88页float average(float*array)int i;float aver,sum=0;for(i=0;i10;i+)sum+=arrayi;aver=sum/10;return(aver);main()float score10,aver;int i;for(i=0;i 10;i+)sca
14、nf(“%f”,&scorei);aver=average(score);printf(%fn,aver);(1)实参是数组名(2)形参是指针变量 可以写成数组形式 可以不指定长度float array10例 8.8 求平均分float array 第30页/共88页float average(float*array)int i;float aver,sum=0;for(i=0;i10;i+)sum+=arrayi;aver=sum/10;return(aver);main()float score10,aver;int i;for(i=0;i 10;i+)scanf(“%f”,&scorei
15、)aver=average(score);printf(%fn,aver);score score0score9array*(array+i)第31页/共88页(3)若在函数中只处理部分数组元素,用参数指定个数float average(float *array,int n)int i;float aver,sum=0;for(i=0;in;i+)sum+=arrayi;aver=sum/n;return(aver);main()float score20,aver;int i;for(i=0;i aj+1j=0 to 4j=0 to 3j=0 to 2j=0 to 6-1-i9 8 8 8
16、8 8 5 4 4 0 8 9 5 5 5 5 4 5 0 45 5 9 4 4 4 6 0 54 4 4 9 6 6 0 66 6 6 6 9 0 80 0 0 0 0 9 第35页/共88页 9 8 5 4 6 0i=1j=0:8 9 5 4 6 0j=1:8 5 9 4 6 0j=2:8 5 4 9 6 0j=3:8 5 4 6 9 0j=4:8 5 4 6 0 9main()int i,j,n,t,a10;n=6;for(i=0;in;i+)scanf(%d,&ai);for(i=1;in;i+)for(j=0;j aj+1)t=aj;aj=aj+1;aj+1=t;第36页/共88页m
17、ain()int i,a10;for(i=0;i10;i+)scanf(%d,&ai);sort(a,10);for(i=0;i10;i+)printf(%d,ai);printf(n);void sort(int*array,int n)int i,j,t;for(i=1;in;i+)for(j=0;jarrayj+1)t=arrayj;arrayj=arrayj+1;arrayj+1=t;第37页/共88页8.3 指针和字符串8.3.1 常用的字符串处理函数8.3.2 字符串的指针表示8.3.3 字符数组和字符指针第38页/共88页8.3.1 常用的字符串处理函数1、使用printf函数和
18、scanf函数输入输出字符串用%s格式,将字符串一次性输入输出static char str20=“Hello”;输出printf(%s,Hello);printf(%s,str);注意:遇到 0,输出结束for(i=0;stri!=0;i+)putchar(stri);字符数组名输出:HelloHello第39页/共88页 输入 scanf(%s,str);注意:输入参数使用数组名,不加地址符。遇到回车或空格,输入结束,并自动在末尾加0。H o w 0输入 How are you?str中:while(stri=getchar()!=)i+;si=0;第40页/共88页 输入多个用空格分隔的
19、字符串 char s120,s220,s320;scanf(%s%s%s,s1,s2,s3);s1:H o w 0a r e 0Y o u?0s2:s3:字符串可以一次性输入输出一般的字符数组只能逐个字符输入输出输入 How are you?第41页/共88页2、字符串输出函数puts static char str20=“hello”;puts(str);输出:Helloputs(“World!”);输出:World!第42页/共88页输出:Hello World!puts(str)与 printf(“%s”,str)的区别:puts(str);=printf(%sn,str);自动将结束符
20、 0 转换成 nputs(“Hello”);puts(“World!”);输出:HelloWorld!printf(“%s”,“Hello”);printf(“%s”,“World!”);第43页/共88页 static char str20;gets(str);字符数组名3、字符串输入函数gets输入遇空格不结束,只有遇回车才结束。gets(str);输入:hello!str中:hello!0第44页/共88页gets(str)与 scanf(“%s”,str)的区别:遇到回车或空格,输入结束例:gets(str);输入:How are you?Str:How are you?0 scanf
21、(“%s”,str);输入:How are you?Str:How0遇回车,输入结束第45页/共88页strcpy(str1,str2);将字符串 str2 复制到 str1 中 static char str120;static char str220=“happy”;4、字符串复制函数strcpyh a p p y 00strcpy(str1,str2);h a p p y 0str1中strcpy(str1,“world”);str1中:world0第46页/共88页#include“stdio.h”#include“string.h”main()char str120,str220;g
22、ets(str2);strcpy(str1,str2);puts(str1);输入:1234输出:1234第47页/共88页 strcat(str1,str2);连接两个字符串str1和str2,并将结果放入str1中。5、字符串连接函数strcat 第48页/共88页#include“stdio.h”#include“string.h”main()char str180,str220;gets(str1);gets(str2);strcat(str1,str2);puts(str1);输入:Let us go.输出:Let us go.str1中:Let us 0 str2中:go.0str
23、1中:Let us go.0第49页/共88页strcmp(str1,str2)比较 两个字符串str1和str2的大小。规则:按字典序(ASCII码序)如果 str1 和 str2 相等,函数值是 0;如果 str1 大于 str2,函数值是正整数;如果 str1 小于 str2,函数值是负整数;6.字符串比较函数strcmp第50页/共88页如果 str1 和 str2 相等,函数值是 0;如果 str1 大于 str2,函数值是正整数;如果 str1 小于 str2,函数值是负整数;static char s120=“china”;strcmp(“China”,“China”)strcm
24、p(s1,“china”)正整数负整数0strcmp(s1,“China”)第51页/共88页#include“stdio.h”#include“string.h”main()int res;char s120,s220;gets(s1);gets(s2);res=strcmp(s1,s2);printf(“%d”,res);输入:1234 5 输出:-4第52页/共88页利用字符串比较函数比较字符串的大小 strcmp(str1,str2);为什么定义这样的函数?因为 str1 str2 str1 0strcmp(str1,“hello”)s1strcat(s1,s2)s1+s2=s1str
25、cmp(s1,s2)若 s1=s2,函数值为0 若 s1 s2,函数值 0 string.h 若 s1 s2,函数值0strlen(str)计算字符串的有效长度,不包括0字符串处理函数小结第55页/共88页8.3.2 字符串的指针表示1、用字符数组表示字符串static char sa=“This is a string.”;printf(“%s”,sa);printf(“%s”,“Hello”);sa0sa1saisa2、用字符指针表示字符串字符串是一个指针常量它的值就是该字符串的首地址第56页/共88页由于字符串是一个指针常量定义一个字符指针,接收字符串指针常量char*sp=This i
26、s a string.;printf(%s,sp);8.3.2 字符串的指针表示static char sa=“This is a string.”;printf(“%s”,sa);printf(“%s”,“Hello”);第57页/共88页1、使用字符指针进行字符串操作实现字符串复制函数 strcpy(s1,s2)8.3.3 字符数组和字符指针void strcpy(char s1,char s2)int i;for(i=0;s2i!=0;i+)s1i=s2i;s1i=0;void strcpy(char s1,char s2)int i=0;while(s1i=s2i)i+;第58页/共8
27、8页用字符指针实现字符串复制函数 strcpy(s1,s2)void strcpy(char s1,char s2)int i=0;while(s1i=s2i)i+;void strcpy(char*s1,char*s2)while(*s1=*s2)s1+;s2+;void strcpy(char*s1,char*s2)while(*s1+=*s2+);数组:改变下标指针:直接改变指针第59页/共88页实现字符串长度函数strlen(str)int strlen(char str)int i=0;while(stri!=0)i+;return i;int strlen(char*str)cha
28、r*t=str;while(*str!=0)str+;return str-t;第60页/共88页实现字符串比较函数strcmp(s1,s2)int strcmp(char s1,char s2)int i;for(i=0;s1i!=0;i+)if(s1i!=s2i)break;return s1i-s2i;strcmp(char*s1,char*s2)for(;*s1!=0;+s1,+s2)if(*s1!=*s2)break;return(*s1-*s2);第61页/共88页static char sa=“This is a string.”;字符数组sa由若干元素组成的,每个元素放一个字符
29、,有确定的地址。char*sp=“This is a string.”;字符指针是一个接收字符串首地址的变量,不能将字符串放到字符指针变量中去。在对指针赋值前,它的值是不确定的。2、字符指针和字符数组的区别第62页/共88页static char sa=“This is a string.”;char*sp=“This is a string.”;static char sa80;char*sp;数组,指针常量,有确定的地址指针,变量strcpy(sa,“This is a string.”)sa=“This is a string.”;sp=“This is a string.”;第63页/
30、共88页#include stdio.hmain()static char sa=“string”;/*设sa的值 2000*/char*sp;/*设sp的值 1fff*/printf(n sa=%x,sp=%xn,sa,sp);sp=sa;printf(sa=%x,sp=%xn,sa,sp);printf(%s,sa);printf(%sn,sp);输出:2000,1fff 2000,2000 string,string例8.10第64页/共88页#include stdio.hmain()char sa80;/*设sa的值 2000*/char*sp=“This is a string”;
31、/*设sp的值 1fff*/printf(nsa=%x,sp=%xn,sa,sp);strcpy(sa,sp);printf(sa=%x,sp=%xn,sa,sp);printf(%s,sp);printf(%sn,sp);输出:2000,1fff 2000,1fff string,string第65页/共88页指针变量必须先定义,后使用。例如:char*p;scanf(%s,p);可能出现难以预料的结果而 char*s,str20;s=str;scanf(%s,s);是正确的.第66页/共88页8.4 指针数组和二级指针8.4.1 指针数组8.4.2 二级指针8.4.3 指针数组和字符串第6
32、7页/共88页int i;int a10;a是一个数组,它有10个元素,每个元素的类型都是整型。int*p;int*pa10;pa是一个数组,它有10个元素,每个元素的类型都是整型指针。8.4.1 指针数组第68页/共88页int a10;a0a9aiaint *pa10;pa0pa9paipa第69页/共88页int i,j,k,m;int *pa4;pa0=&i;pa1=&j;pa2=&k;pa3=&m;pa0papa1pa2pa3ijkm*pa0*pa1*pa2*pa3第70页/共88页int i=1,j=2,k=3,m=4;int*pa4=&i,&j,&k,&m;pa0papa1pa2
33、pa3ijkm*pa0*pa1*pa2*pa31234for(n=0;n4;n+)printf(“%x”,pan);for(n=0;n4;n+)printf(“%d”,*pan);第71页/共88页int i=1,j=2,k=3,m=4;int*pa4=&i,&j,&k,&m;for(pp=pa;pppa+4;pp+)printf(“%x”,*pp);pp,*pp*pppa0papa1pa2pa3ijkm*pa0*pa1*pa2*pa31234for(pp=pa;pppa+4;pp+)printf(“%x”,*pp);第72页/共88页int i=1,j=2,k=3,m=4;int*pa4=&
34、i,&j,&k,&m;如何定义 pp*pp*pppp,pa0papa1pa2pa3ijkm*pa0*pa1*pa2*pa31234int *pp;8.4.2 二级指针(指向指针的指针)第73页/共88页main()int a=10;int*p=&a,*pp=&p;printf(a=%d,*p=%d,*pp=%dn,a,*p,*pp);*p=20;printf(a=%d,*p=%d,*pp=%dn,a,*p,*pp);*pp=30;printf(a=%d,*p=%d,*pp=%dn,a,*p,*pp);&apa10&ppp*p*pp&a*pp输出:a=10,*p=10,*pp=10 a=20,*
35、p=20,*pp=20 a=30,*p=30,*pp=30第74页/共88页main()int a=10,b=80;int*p=&a,*pp=&p;printf(a=%d,b=%d,*p=%d,*pp=%dn,a,b,*p,*pp);p=&b;printf(a=%d,b=%d,*p=%d,*pp=%dn,a,b,*p,*pp);&apa10&ppp*p*pp&a*pp输出:a=10,b=80,*p=10,*pp=10 a=10,b=80,*p=80,*pp=80&bpa10&ppp*pp&bb80*pp*p第75页/共88页char *name4=“Wang”,“Li”,“Zhao”,“Jin
36、”;8.4.3 指针数组和字符串name0name“Wang”name1“Li”name2“Zhao”name3“Jin”printf(“%sn”,name0);printf(“%c”,*name0);输出:WangW第76页/共88页 char *name4=“Wang”,“Li”,“Zhao”,“Jin”;name0name“Wang”name1“Li”name2“Zhao”name3“Jin”输出:Wang Li Zhao Jin for(i=0;i4;i+)printf(“%s”,namei);for(i=0;i4;i+)printf(“%c”,*namei);输出:W L Z J 第
37、77页/共88页输入月,输出相应的英文名称。#include main()int month;scanf(%d,&month);if(month=1&month=12)prnname(month);例8.11第78页/共88页prnname(int m)char*name=January,February,March,April,May,June,July,August,September,October,November,December;printf(%3d:%sn,m,namem-1);name0name“January”name1“February”name11“December”第7
38、9页/共88页char *name4=“Wang”,“Li”,“Zhao”,“Jin”;char *pp=name;printf(“%sn”,*pp);printf(“%c”,*pp);name0name“Wang”name1“Li”name2“Zhao”name3“Jin”*pppp输出:WangW第80页/共88页char *name4=“Wang”,“Li”,“Zhao”,“Jin”;char *pp=name;printf(“%sn”,*pp);输出:Wangname0name“Wang”name1“Li”name2“Zhao”name3“Jin”*pppppp=pp+2;printf
39、(“%sn”,*pp);printf(“%c”,*pp);Zhao Z第81页/共88页 char *name4=“Wang”,“Li”,“Zhao”,“Jin”;char *pp;for(pp=name;ppname+4;pp+)printf(“%s”,*pp);输出:Wang Li Zhao Jin name0name“Wang”name1“Li”name2“Zhao”name3“Jin”*pppp第82页/共88页char *name4=“Wang”,“Li”,“Zhao”,“Jin”;char *pp;for(pp=name;ppname+4;pp+)printf(“%c”,*pp);
40、name0name“Wang”name1“Li”name2“Zhao”name3“Jin”*pppp输出:W L Z J 第83页/共88页 char *name4=“Wang”,“Li”,“Zhao”,“Jin”;char *pp;for(pp=name;ppname+4;pp+)printf(“%s”,*pp+1);输出:ang i hao in name0name“Wang”name1“Li”name2“Zhao”name3“Jin”*pppp第84页/共88页8.5 指针和函数指针作为函数的返回值函数 match 在一个字符串 中寻找某个字符,如找到,返回第一次找到的该字符在字符串的位
41、置;否则,返回空指针NULL。char*match(char c,char*s)while(*s!=0)if(*s=c)return(s);/*返回指针*/else s+;return(0);第85页/共88页#include main()char*cp=ABCDEFGHIJK;printf(%sn,match(B,cp);printf(%sn,match(H,cp);printf(%sn,match(a,cp);输出:BCDEFGHIJK HIJK第86页/共88页字符串复制函数 strcpy(s1,s2),返回s1char*strcpy(char*s1,char*s2)char*ss=s1;while(*s1+=*s2+);return ss;void strcpy(char*s1,char*s2)while(*s1+=*s2+);第87页/共88页谢谢您的观看!第88页/共88页