版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第十章第十章 指针指针第十章 指 针指针的概念一变量的指针和指向变量的指针变量二数组与指针三指针函数六函数的指针和指向函数的指针变量五字符串与指针四指针数组和指向指针的指针七指针小结八2022-4-2012022-4-20第十章 指针2第一节第一节 指针的概念指针的概念一、变量的地址和内容一、变量的地址和内容: 设程序中定义了变量设程序中定义了变量a: int a=3; 执行时为执行时为a开辟开辟2个字节的个字节的空间空间(设开辟设开辟2000和和2001),并赋值为,并赋值为3 320002001a则变量则变量a的地址是的地址是2000, 变量变量a 的内容的内容(值值)是是32022-4-
2、20第十章 指针3二、直接寻址和间接寻址二、直接寻址和间接寻址: (1)直接寻址直接寻址:按址存取按址存取 a=3; b=a; (2)间接寻址间接寻址:某变量的地址存放在另外的内某变量的地址存放在另外的内存单元中存单元中 (3001开始开始)存取时存取时,先到先到3001开始的内存开始的内存单元中将变量的地址单元中将变量的地址(2000)取出取出,再按该地址存取内容再按该地址存取内容(3)320002001300120003002p如:如:*p=3;2022-4-20第十章 指针4三、存放地址的变量三、存放地址的变量: 可以定义一种变量用来存放可以定义一种变量用来存放另外一个变量的地址另外一个
3、变量的地址 如如: int *i_pointer; i_pointer=&a;定义变量定义变量 i_pointer存放整形存放整形变量的地址变量的地址,系统分配给系统分配给i_pointer相应的存储单元相应的存储单元(设设3001和和3002) 用用i_pointer=&a;语句语句, 将将a的的地址存于变量地址存于变量i_pointer 中中,即即i_pointer中存放地址中存放地址2000通过通过i_pointer可以找到变量可以找到变量a, 称变量称变量i_pointer指向指向a 320002001a30013002i_pointer20002022-4-20第十章
4、 指针5F通过变量的地址可以找到变量通过变量的地址可以找到变量, 或变量的地址或变量的地址对应着变量对应着变量, 故将变量的地址称为变量的指针故将变量的地址称为变量的指针F如如: 2000是变量是变量a的指针的指针, 或说或说, 变量变量a的指针是的指针是2000F存放地址的变量称为指针变量存放地址的变量称为指针变量F如如: i_pointer是指针变量是指针变量(不是指针不是指针)F但但: i_pointer的内容是指针的内容是指针(变量变量a的指针的指针)F若变量若变量i_pointer存放的是变量存放的是变量a的指针的指针, 则可则可用用 * i_pointer表示变量表示变量a (*表
5、示指向表示指向)2022-4-20第十章 指针6第二节第二节 指向变量的指针变量指向变量的指针变量F指针变量的定义指针变量的定义F指针变量的引用指针变量的引用F指针变量作为函数参数指针变量作为函数参数2022-4-20第十章 指针7一、指针变量的定义一、指针变量的定义:格式格式: 类型标识符类型标识符 *标识符标识符如如: int *p1, *p2; float *p3;作用作用:定义定义p1、p2两个指针变量,可用来存储整型两个指针变量,可用来存储整型变量的地址变量的地址 (不能存放其他类型变量的指不能存放其他类型变量的指针针)定义指针变量定义指针变量p3,用来存放实型变量的指针,用来存放实
6、型变量的指针2022-4-20第十章 指针8int main( ) /*wjp20.c*/ int *p1,*p2; int a,b; p1=&a; /*将将a的地址赋与的地址赋与p1*/ p2=&b; *p1=2; /*将将2赋给赋给p1所指的变量所指的变量*/ *p2=3; printf(“a=%d,b=%dn”,a,b); printf(“a=%d,b=%dn”,*p1,*p2); return 0; 注注: 程序中两处的程序中两处的*p1,*p2代表不同的含义代表不同的含义p1p2ab200120052001200523结果:结果:a=2, b=3 a=2, b=320
7、22-4-20第十章 指针9二、指针变量的引用二、指针变量的引用:可以将变量可以将变量(相应类型相应类型)的地址赋给指针变的地址赋给指针变量量,但不能将整型量赋给指针变量但不能将整型量赋给指针变量 如如: p1=&a; 正确正确 但但: p1=2001; 错误错误!可以将数值赋给指针变量所指的变量可以将数值赋给指针变量所指的变量 如如: *p1=36; /*p1必须已指向某个变必须已指向某个变量量*/2022-4-20第十章 指针10“&”和和“*”“&”是取地址符号是取地址符号 如如: p1=&a; “*”是指向的意思是指向的意思 如如: *p1代表代表p1所
8、指的所指的变量变量“*”和和“+”、“-”、 “&”等优先级相同等优先级相同,但但结合性是从右至左结合性是从右至左设已执行设已执行 “p1=&a;”, 则则 &*p1同同&a,即,即p1*&a相当于相当于*p1, 即变量即变量a(*p1)+相当于相当于a+*p1+ 则相当于则相当于*(p1+), 是先取是先取p的值的值(地地址址), 进行进行*运算运算, 得到得到a, 然后使然后使p1指向下指向下一个变量一个变量 2022-4-20第十章 指针11int main() int a=5,b,*p=&a; printf(“%pn”,p); b=*p+
9、; printf(“%d,%pn”,b,p); return 0; 结果:结果:2000 5,2002 pa200020005b520022022-4-20第十章 指针12案例案例1:输入两个整数输入两个整数, 按大小顺序输出按大小顺序输出要求:要求:不允许改变不允许改变a,b的值,只允许再定义指针的值,只允许再定义指针变量变量只允许调用一次只允许调用一次printf() 函数函数 int main() int a,b,*p1,*p2,*p; scanf(“%d,%d”,&a,&b); p1=&a; p2=&b; if(ab) p=p1;p1=p2;p2=p;
10、printf(“%d,%dn”, *p1,*p2); return 0; p1p2pab2000200420002004232022-4-20第十章 指针13p1p2pab20002004200420002000案例案例1:输入两个整数输入两个整数, 按大小顺序输出按大小顺序输出要求:要求:不允许改变不允许改变a,b的值,只允许再定义指针的值,只允许再定义指针变量变量只允许调用一次只允许调用一次printf() 函数函数 int main() int a,b,*p1,*p2,*p; scanf(“%d,%d”,&a,&b); p1=&a; p2=&b; if(a
11、b) p=p1;p1=p2;p2=p; printf(“%d,%dn”, *p1,*p2); return 0; 23定义一个整型定义一个整型变量变量, ,可否可否? ?2022-4-20第十章 指针14三、指针变量作函数参数三、指针变量作函数参数: 案例案例2:主函数中有一个变量:主函数中有一个变量a,请在被调,请在被调函数中存入一个值函数中存入一个值(100)int main() void f(); int a=1; f(); /调用函数调用函数 printf(“%dn”,a); return 0; void f() 2022-4-20第十章 指针15三、指针变量作函数参数三、指针变量作函
12、数参数: 案例案例2错误答案:错误答案:int main() void f(int); int a=1; f(a); /调用函数调用函数 printf(“%dn”,a); return 0; void f(int a) a=100; 运行结果:运行结果:12022-4-20第十章 指针16三、指针变量作函数参数三、指针变量作函数参数: 案例案例2正确答案:正确答案:int main() void f(int*); int a=1; f(&a); /调用函数调用函数 printf(“%dn”,a); return 0;结论:要想改变结论:要想改变a,则必须传,则必须传a的地址的地址 vo
13、id f(int *p) *p=100; 2022-4-20第十章 指针17三、指针变量作函数参数三、指针变量作函数参数: 案例案例3:输入两个数:输入两个数, 按大小顺序输出按大小顺序输出int main() void swap(int*,int *); int a,b; scanf(“%d,%d”,&a,&b); if(ab) swap(&a,&b); printf(“%d,%dn”,a,b); return 0; void swap(int *p,int *q) int t; t=*p; *p=*q; *q=t; 2022-4-20第十章 指针18三、指针
14、变量作函数参数三、指针变量作函数参数: 案例案例3另解:另解:int main() void swap(int*,int*); int a,b,*p1,*p2; p1=&a; p2=&b; scanf(“%d,%d”,p1,p2); if(ab) swap(p1,p2); /*交换交换p1、p2?*/ printf(“%d,%dn”,a,b); return 0;p1p2ab20012005200123.20052022-4-20第十章 指针19void swap(p_1, p_2)int *p_1,*p_2; int t; t=*p_1; *p_1=*p_2; *p_2=t;
15、p1p2ab20012005200123p_2p_120052001t2.2005322022-4-20第十章 指针20p1p2ab200120052001.200532void swap(p_1, p_2)int *p_1,*p_2; int t; t=*p_1; *p_1=*p_2; *p_2=t;返回返回main()函数打印函数打印a、b的值的值2022-4-20第十章 指针21下面的程序有无问题下面的程序有无问题?void swap(int *p_1, int *p_2) int *p; *p=*p_1; *p_1=*p_2; *p_2=*p; p指向?指向?p1p2ab2001200
16、5200123p_2p_120052001p20052022-4-20第十章 指针22下面程序是否正确?下面程序是否正确? void swap(int *p_1, int *p_2) int *p; p=p_1; p_1=p_2; p_2=p;p1p2ab20012005200123p_2p_120052001p2001.200520052001int main() if(ab) swap(p1,p2); printf(“%d,%dn”,*p1,*p2); return 0;下面程序是否正确? void swap(int *p_1, int *p_2) int *p; p=p_1; p_1=p
17、_2; p_2=p;2022-4-20第十章 指针23p1p2ab20012005200123.2005int main() if(a a0 /三维数组名指向二维数组三维数组名指向二维数组 a0 - a00 /二维数组名指向一维数组二维数组名指向一维数组 a00 - a000 /一维数组名指向变量一维数组名指向变量2022-4-20第十章 指针30一、数组名的指针类型一、数组名的指针类型2、数组名的指针类型、数组名的指针类型程序验证:程序验证: int main( ) int a3312; printf(“%u,%un”, a, a+1); printf(“%u,%un”, a0, a0+1)
18、; printf(“%u,%un”, a00, a00+1); return 0; 输出结果(设输出结果(设a的首地址为的首地址为2000):): 2000, 2072 2000,2024 2000,20022022-4-20第十章 指针31第三节第三节 数组和指针数组和指针通过数组名访问下标变量2通过指针变量访用下标变量3数组名作参数4本节主要内容数组名的指针类型12022-4-20第十章 指针32二、通过数组名访问下标变量二、通过数组名访问下标变量1、对于一维数组、对于一维数组设有一维数组定义:设有一维数组定义: int a5; 则它的则它的5个元素可分别表示为:个元素可分别表示为:(1)
19、下标法)下标法 a0, a1, a2, a3, a4(2)指针法)指针法 *a, *(a+1), *(a+2), *(a+3), *(a+4) 写成写成ai实际上在编译时也是被处理成实际上在编译时也是被处理成*(a+i)的的 a0a1a2a3aa+1a+2a+3a+4a42022-4-20第十章 指针33二、通过数组名访问下标变量二、通过数组名访问下标变量2、对于多维数组(以二维为例)、对于多维数组(以二维为例)若若a是二维数组:是二维数组: int a56;(1)下标法:)下标法:aij(2)指针法:如何表示?)指针法:如何表示?a+ia*(a+i)a0aiaij*(*(a+i)+j)*(a
20、+i)+j2022-4-20第十章 指针34第三节第三节 数组和指针数组和指针通过数组名访问下标变量2通过指针变量访用下标变量3数组名作参数4本节主要内容数组名的指针类型12022-4-20第十章 指针35F用指针变量访问下标变量的意义用指针变量访问下标变量的意义F效率高(特定的时候)效率高(特定的时候)F有时候不允许用数组名表示下标变量有时候不允许用数组名表示下标变量F前提:使指针变量指向某下标变量前提:使指针变量指向某下标变量F原理:由于数组是连续的,如果一个指针变量原理:由于数组是连续的,如果一个指针变量指向数组中的某下标变量,我们便可通过该指指向数组中的某下标变量,我们便可通过该指针变
21、量访问数组的所有下标变量针变量访问数组的所有下标变量三、通过指针变量访问下标变量三、通过指针变量访问下标变量2022-4-20第十章 指针36F1、访问一维数组中的下标变量、访问一维数组中的下标变量F int a4,*p;F p=a; /相当于相当于p=&a0; F 此后,可以用此后,可以用*(p+i)表示数组表示数组中任意一个下标变量中任意一个下标变量aiF其实其实p未必赋值为未必赋值为a,也可以这样,也可以这样赋值:赋值:p=&a2; 三、通过指针变量访问下标变量三、通过指针变量访问下标变量a0a1a2a3p-2p-1pp+1p20052001a0a1a2a3pp+1p+2
22、p+3p20012001int a4, *p=a; 2022-4-20第十章 指针37F结论:若结论:若p=a, 则可用则可用*( p+i)表示表示ai F还可以用还可以用pi表示表示ai ,因为,因为pi在编译时被解释在编译时被解释为为*( p+i) 。F所以用指针变量访问下标变量的方法也有两种:所以用指针变量访问下标变量的方法也有两种:F指针法:指针法:*(p+i)F下标法:下标法: pi三、通过指针变量访问下标变量三、通过指针变量访问下标变量前提:前提:p=a2022-4-20第十章 指针38F案例案例4:用多种方法访问一维数组的元素:用多种方法访问一维数组的元素Fint main()F
23、 F int a5=1,3,5,7,9;F int i, *p;F for(i=0;i=4;i+)F printf(“%d”, ai); /第一种方第一种方法最直观法最直观F printf(“n”);F for(i=0;i=4;i+)F printf(“%d”, *(a+i); /第二种方第二种方法法F printf(“n”);2022-4-20第十章 指针39 p=a; /前提条件前提条件 for(i=0;i=4;i+) printf(“%d”, pi); /第三种方法第三种方法 printf(“n”); for(i=0;i=4;i+) printf(“%d”, *(p+i); /第四种方法
24、第四种方法 printf(“n”); for( ; p=a+4; p+) /要考虑能否省略要考虑能否省略 printf(“%d”, *p); /第五种方法最有第五种方法最有效效 printf(“n”); return 0;2022-4-20第十章 指针40F考虑考虑:将上例中程序顺序调整如下将上例中程序顺序调整如下, 可否可否?F F p=a;F for( ; p=a+4; p+)F printf(“%d”, *p); /*第五种方法第五种方法最有效最有效*/F printf(“n”); F for(i=0;i=4;i+)F printf(“%d”, *(p+i); /*第四种方第四种方法法*
25、/F printf(“n”);F return 0;Fp已指向已指向a4后面的单元后面的单元 思考思考1: int main() int a10; _; /让让a5=1,有几种写法?哪种最快?有几种写法?哪种最快? 思考思考2: int main() int a10, *p=a; _; /让让a5=1,共有几种写法?哪种最快?共有几种写法?哪种最快? 思考思考3: int main() int a10=1,2,3,4,5,6,7,8,9,0, *p=a; /以下添加循环,输出所有元素值,共有几种写法?哪种最快以下添加循环,输出所有元素值,共有几种写法?哪种最快? 2022-4-20第十章 指针
26、412022-4-20第十章 指针42F2、访问二维数组中的下标变量、访问二维数组中的下标变量F int a34,*p;F p=&a00;F 此后,便也可用此后,便也可用p表示数组中表示数组中任意一个下标变量任意一个下标变量:F 上面的上面的p =&a00;也可以写也可以写成:成:F p=a; / p指向什么?指向什么?F p=a0; 三、通过指针变量访问下标变量三、通过指针变量访问下标变量a00a01a02a03pp+1p+2p+3p20012001a10p+4*(p+i*4+j)2022-4-20第十章 指针43F2、访问二维数组中的下标变量:、访问二维数组中的下标变量:F
27、案例案例5:用指针变量输出二维数组中各下标变量:用指针变量输出二维数组中各下标变量的值的值F int main()()F F int a34=1,2,3,4,5,6,7,8,9,10,11,12;F int *p; F for(p=a; p=a0+11; p+)F printf(“%3d”, *p);F return 0;F F 结果结果: 1 2 3 4 5 6 7 8 9 10 11 12 三、通过指针变量访问下标变量三、通过指针变量访问下标变量 / /用用p=a+11pa0F p+i-ai *(p+i)即即aiF ai-ai0F ai+j-aij 即即*(p+i)+j-aijF 三、通过
28、指针变量访问下标变量三、通过指针变量访问下标变量a00a01a02a03pp20012001a10思考思考1:int main() int a45; _; /让让a34=1,有有2种写法种写法(通过数通过数组名访问组名访问) printf(“%dn”, a34); return 0;思考思考2:int main() int a45; _; /定义指针变量定义指针变量 _; /让让a34=1,有有4种写法种写法 (通过指通过指针变量访问针变量访问) printf(“%dn”, a34); return 0;2022-4-20第十章 指针452022-4-20第十章 指针46第三节第三节 数组和指
29、针数组和指针通过数组名访问下标变量2通过指针变量访用下标变量3数组名作参数4本节主要内容数组名的指针类型12022-4-20第十章 指针47四、数组名作参数四、数组名作参数F使用场合:需要被调函数处理数组中的数据使用场合:需要被调函数处理数组中的数据F传值还是传地址:传值还是传地址:F传值的问题:(传值的问题:(1)改变不了数据()改变不了数据(2 )麻烦)麻烦F传地址:传地址:F 主调函数主调函数 被调函数被调函数 F sub(int *p)F sub(a); F F 2022-4-20第十章 指针48四、数组名作参数四、数组名作参数F1、数组名做参数的两种方案:、数组名做参数的两种方案:F
30、 案例案例6:F 数组共有十一个元素。数组共有十一个元素。 前十个前十个已存入数据,计算它们的和并把结果已存入数据,计算它们的和并把结果存储到最后一个元素中存储到最后一个元素中F数组定义:数组定义: int a11=1,2,3,4,5,6,7,8,9,10;2022-4-20第十章 指针49方案方案1:数组名:数组名指针变量指针变量int main() void sum(int*,int); /也可以将也可以将int*写作写作int int a11=1,2,3,4,5,6,7,8,9,10; sum(a, 10); printf(“sum is %dn”, a10); return 0;voi
31、d sum(int *p, int n) int s=0; while(n-) /*相当于相当于while(n-)!=0) s+=*(p+); *p=s; /*将和存储到最后一个元素中将和存储到最后一个元素中*/2022-4-20第十章 指针50方案方案2:数组名:数组名数组名数组名int main() void sum(int,int); int a11=1,2,3,4,5,6,7,8,9,10; sum(a, 10); printf(“sum is %dn”, a10); return 0;void sum(int p , int n) /与与int *p等价等价 int s=0; whi
32、le(n-) /*相当于相当于while(n-)!=0) s+=*(p+); *p=s; /*将和存储到最后的元素中将和存储到最后的元素中*/2022-4-20第十章 指针51F关于关于int p和和 int *p 等价的验证:等价的验证:Fint main()FF void sub(int);F int a10=1,3,5,2,7,9,6,8,0,4;F printf(“%d, , sizeof(a);F printf(“%p, , a);F printf(“%pn, &a);F sub(a);F printf(%pn, a);F return 0;Fvoid sub(int x)
33、printf(%d, , sizeof(x); printf(%p, , x); printf(%p, , &x); x+; printf(%pn, x);运行结果:运行结果:20, FFCA, FFCA2, FFCA, FFC8, FFCCFFCA2022-4-20第十章 指针52案例案例7: 一维数组排序一维数组排序int main() int i, a10=4,8,7,5,3,9,6,1,2,0; void sort(int*); sort(a); for(i=0;i10;i+) printf(“%3d”,ai); return 0; void sort(int *p) /对数组
34、排序对数组排序 /代码中写代码中写pi或或*(p+i)2022-4-20第十章 指针53也可以是写成:也可以是写成:int main() int i, a10=4,8,7,5,3,9,6,1,2,0; void sort(int*); sort(a); for(i=0;i10;i+) printf(“%3d”,ai); return 0; void sort(int p) /与前面的写法等价与前面的写法等价 2022-4-20第十章 指针54四、数组名作参数四、数组名作参数F2、数组名做参数特点:、数组名做参数特点:F 236191001实参a1001虚参p1001数组名作参数依然是单向传递数
35、组名作参数依然是单向传递 2022-4-20第十章 指针55案例案例8:二维数组:二维数组, 求总平均分并输出某生的成绩求总平均分并输出某生的成绩 int main() void average(int*, int); void search(int*, int); int a34= 65,67,70,60,80,87,90,81,90,99,100,98; average(a0, 12); /12个成绩的平均值个成绩的平均值 search(a0, 2); /输出第输出第2个人的成绩个人的成绩 return 0; 实参还可以写成实参还可以写成*a或或&a00 ,最好不要写,最好不要写a
36、2022-4-20第十章 指针56 void average(int *p, int n) float sum=0, aver; for( ; p=p+n-1; p+) sum+=*p; aver=sum/n; printf(“aver=%5.2fn”, aver); 上面的程序有没有问题?上面的程序有没有问题?2022-4-20第十章 指针57 void search(int *p , int n) int i; for(i=0;i=3;i+) printf(“%4d”,*(p+n*4+i); printf(“n”); 2022-4-20第十章 指针58可以改为:可以改为:void sear
37、ch(int (*p)4, int n) int i; for(i=0;i=3;i+) printf(“%4d”,*(*(p+n)+i); printf(“n”); 但实参相应地要改为但实参相应地要改为a 思考思考1: int main() int a45; /让让a34=1,共有共有6种写法(有些写法需要定义指针变量),数组种写法(有些写法需要定义指针变量),数组名两种,指针变量名两种,指针变量4种种 /分别写出分别写出6种方法中的每一种种方法中的每一种 printf(“%dn”, a34); return 0; 思考思考2: int main() int a34=7,1,0,9,3,5,4
38、,6,10,2,8,11, *p=a0; _; /调用调用sub函数让数组中每个下标变量值都变成函数让数组中每个下标变量值都变成原来的原来的2倍倍 for(i=0;iy?x:y;int main() int a=7, b=5; int (*p)( )=max; c=(*p)(a,b); /*c=max(a,b);*/ printf(“max=%dn”, c); return 0; 2022-4-20第十章 指针82说明说明:指向函数的指针变量定义格式一般是指向函数的指针变量定义格式一般是: 数据类型数据类型 (*指针变量名指针变量名)( );如如: int (*p)( ); float (*p
39、1)( );其中其中, 数据类型是指函数返回值的类型数据类型是指函数返回值的类型函数调用可以通过函数名函数调用可以通过函数名, 也可以通过指也可以通过指向函数的指针变量向函数的指针变量 如如: c=max(a,b); c=(*p)(a,b);2022-4-20第十章 指针83Fint (*p)(); 表示定义一个指向函数的指针变表示定义一个指向函数的指针变量量, 可以指向返回值为整型量的函数。把哪可以指向返回值为整型量的函数。把哪个函数的入口地址赋给个函数的入口地址赋给p, p就指向哪一个函就指向哪一个函数且数且p可以先后指向不同的函数可以先后指向不同的函数F 如如 :int (*p)();F
40、 p=max; /*max是整型函数是整型函数*/F p=min; /*min也是整型函数也是整型函数*/F给指向函数的指针变量赋值时给指向函数的指针变量赋值时, 不能带参数不能带参数F 如如: p=max; 正确正确! p=max(a,b); 错误错误!F对指向函数的指针变量对指向函数的指针变量, p+、p+n、p- -等运等运算无意义算无意义2022-4-20第十章 指针84二、指向函数的指针变量作参数二、指向函数的指针变量作参数F可作为函数参数的有可作为函数参数的有:F变量变量 F下标变量下标变量 F数组名(一维或多维)数组名(一维或多维) F指向变量的指针变量指向变量的指针变量 F指向
41、数组的指针变量指向数组的指针变量 F指向字符的指针变量指向字符的指针变量 F指向函数的指针变量指向函数的指针变量F 2022-4-20第十章 指针85F指向函数的指针变量作参数的一般用法指向函数的指针变量作参数的一般用法:F实参函数名实参函数名 f1 f2F F void sub ( p1, p2 )F int (*p1)( ), (*p2)( );F int a, b, x, y, z;F a=(*p1)(x); /*设设f1需一个参数需一个参数*/F b=(*p2)(y,z); /*设设f2需两个参数需两个参数*/ F F F作用作用: 根据主调函数传来的函数名根据主调函数传来的函数名,
42、调用相调用相应的函数应的函数 2022-4-20第十章 指针86在在sub中中, 可以直接调用可以直接调用f1、f2,如下所示:,如下所示: sub( ) int a,b,x,y,z; a=f1(x); b=f2(y,z); 但一旦调用的不是但一旦调用的不是f1、f2, 就需修改函数就需修改函数2022-4-20第十章 指针87编程编程: 键盘输入一个表达式键盘输入一个表达式(只能是两个数的加减乘只能是两个数的加减乘除除,如如3*5、5/2、7+8等等),输出结果,输出结果例如:输入例如:输入 8*2 输出输出 8*2=16 输入输入 3-5 输出输出 3-5=-2 2022-4-20第十章
43、指针88int main() wjp26.c float x, y,add( ),sub( ),mul( ),div( ); void cal( ); char c; printf(“输入表达式输入表达式:”); scanf(“%f%c%f”,&x,&c,&y); printf(“%f%c%f=”,x,c,y); switch (c) case +: cal(x,y,add); break; case -: cal(x,y,sub); break; case *: cal(x,y,mul); break; case /: cal(x,y,div); break; def
44、ault: printf(“输入错误输入错误n”); return 0;2022-4-20第十章 指针89 void cal(a,b,p ) float a,b; float (*p)(); float result; result=(*p)(a,b); printf(“%fn”,result);2022-4-20第十章 指针90 float add(x1,x2 ) float x1,x2; return x1+x2; /*/ float sub(x1,x2 )float x1,x2; return x1-x2; /*/float mul(x1,x2 )float x1,x2; return
45、x1*x2; /*/ float div(x1,x2 )float x1,x2; return x1/x2; 2022-4-20第十章 指针91第六节第六节 返回指针值的函数返回指针值的函数F函数的返回值可以是整型、字符型、实函数的返回值可以是整型、字符型、实型,还可以是指针型型,还可以是指针型F返回指针型数据的函数简称指针函数,返回指针型数据的函数简称指针函数,其定义的一般格式是:其定义的一般格式是:F 数据类型数据类型 *函数名函数名(虚参表列虚参表列) F F F 2022-4-20第十章 指针92F已知三人四门课的成绩已知三人四门课的成绩, 根据键盘输入的学号输出根据键盘输入的学号输出
46、该生成绩该生成绩(用指针函数用指针函数)F int main()F F int a 4=67,76,80,78,90,86,70,56,34,50,75,80;F int *search(); /*对要用到的函数进行说明对要用到的函数进行说明*/F int *p; /*p是指向整型变量的指针是指向整型变量的指针*/F int i, m; F scanf(“%d”, &m);F p=search(a, m); /*将将m同学第一门课成绩的地址同学第一门课成绩的地址赋与赋与p*/ F for(i=0;i=3;i+)F printf(“%d”, *(p+i);F return 0;F2022
47、-4-20第十章 指针93F int *search(pointer, n)Fint *pointer; /*传来的地址在该函数中指向变传来的地址在该函数中指向变量量*/Fint n;F F int *pt; F pt=pointer+4*n;F return pt;F677680789086705634507580pointerpointer+1pointer+1*4pointer+2*4pointer+2pointer+32022-4-20第十章 指针94F 函数可改为函数可改为:Fint *search(pointer, n)Fint (*pointer)4; /*传来的地址指向一维数组
48、传来的地址指向一维数组*/Fint n;F F int *pt; F pt=pointer+n;F return pt;F677680789086705634507580pointerpointer+1pointer+22022-4-20第十章 指针95F 函数还可改为函数还可改为:Fint *search(pointer, n)Fint (*pointer)4; /* 传来的地址指向一维数组传来的地址指向一维数组 */Fint n;F F int *pt; F pt=*(pointer+n); /* *(pointer+n)是一维数组是一维数组 */F return pt;F数组名就是地址数
49、组名就是地址思考题思考题:主函数中有一个二维数组,其中存有三个人共主函数中有一个二维数组,其中存有三个人共12个分数,请调用被调函数找出最高分的地址个分数,请调用被调函数找出最高分的地址,然后主函数输出最高分。请编写被调函数并,然后主函数输出最高分。请编写被调函数并完善主函数。完善主函数。int main() _; /声明函数声明函数 int score34=67,87,90,65,45,54,34,20,89,78,76,66; int *p; _; /调用调用search()函()函数数 printf(“%dn”, *p); return 0;2022-4-20第十章 指针962022-4
50、-20第十章 指针97第七节第七节 指针数组和指向指指针数组和指向指针的指针针的指针F指针数组指针数组F指向指针的指针指向指针的指针F指针数组作指针数组作main函数的形参函数的形参2022-4-20第十章 指针98一、一、 指针数组指针数组F指针数组指针数组:由指针变量组成的数组称为指针数组由指针变量组成的数组称为指针数组F定义格式定义格式:F 类型说明类型说明 *数组名数组名数组长度数组长度F如如: int *p4; F /*定义一个指针数组定义一个指针数组, 共有共有4个元素个元素, 每个元每个元F 素都是指针变量素都是指针变量, 指向整型变量指向整型变量*/2022-4-20第十章 指
51、针99F思考思考:字符串的存储字符串的存储F 通过数组:通过数组:char s =“I am a student”;F 通过指针通过指针: char *p= “I am a student”; F字符串数组的存储字符串数组的存储:F 二维数组二维数组: char s38F =“fortran”, “basic”, “ c”;F 指针数组指针数组: char *p3F =“fortran”, “basic”, “ c”;2022-4-20第十章 指针100F通过指针数组存储的优点通过指针数组存储的优点:F1、节省空间、节省空间F二维数组二维数组:F指针数组指针数组:fortran0b asic0
52、0cfortran0b asic00c浪费空间浪费空间2022-4-20第十章 指针101 2、操作方便、操作方便例:将下面的书名按顺序输出:例:将下面的书名按顺序输出: c basic pascal fortranint main() wjp27.c void sort ( ), print ( ); char *p4=“c”,“basic”,“pascal”,“fortran”; sort(p); print(p); return 0;fortran0b asic00cpascal0p0p1p2p32022-4-20第十章 指针102 void sort(pt) char *pt ; /*
53、pt是指针数组名是指针数组名*/ char *temp; int i, j, k; for(i=0;i4;i+) k=i; for(j=i+1;j4;j+) if(strcmp(ptj,ptk)0) k=j; if(k!=i) temp=pti;pti=ptk;ptk=temp; 问题问题: 若若pt0和和pt1的值交换的值交换, 实参实参p0、p1是否也是否也交换?交换?fortran0b asic00cpascal0pt0pt1pt2pt3交换!实参和虚交换!实参和虚参共用一个单元参共用一个单元2022-4-20第十章 指针103 void print(pt) char *pt ; /*
54、pt是指针数组名是指针数组名 */ int i; for(i=0;i4;i+) printf(“%sn”, pti); /*error: *pti*/ pt0pt1pt2pt3fortran0b asic00cpascal0p0p1p2p32022-4-20第十章 指针104ptpt是数组名是数组名, , 是是pt0pt0的的地址地址200E200Ept+1pt+1是是p1p1的地址的地址200F200Fcbasic00p0p1p2p32000200720072000ppt0ptpt1pt2pt3.200E200F20102011 设地址只用一个字节存储执行函数后:执行函数后:p0指向指向“b
55、asic”p1指向指向“c”2022-4-20第十章 指针105F思考思考: F本例若用二维数组本例若用二维数组, 当如何编程当如何编程?F与指针数组相比与指针数组相比, 孰优孰劣孰优孰劣?F用二维数组的缺点用二维数组的缺点: F浪费内存空间浪费内存空间F用二维数组编程用二维数组编程, 需交换字符串需交换字符串, 运行时间长运行时间长2022-4-20第十章 指针106二、二、 指向指针的指针指向指针的指针F前节所述前节所述: 可以定义一个指针数组可以定义一个指针数组, 其元其元素是指向变量的指针素是指向变量的指针F如如: char *pp=“ab”, “cd”, “ef”;F则则: Fpp共
56、有三个元素共有三个元素pp0、pp1、pp2, 都都是指针变量是指针变量 (分别存储三个字符串的指针分别存储三个字符串的指针)Fpp是数组名是数组名, 是数组的指针是数组的指针, 指向指向pp0, 而而pp+1指向指向pp1, pp+2指向指向pp2 F故故: pp、pp+1、pp+2 是指向指针的指针是指向指针的指针2022-4-20第十章 指针107abpp0pp1pp20cd0ef0200020032006200020032006pp0pp1pp2pppp+1pp+2指针数组指针数组指针指针指向指针的指针指向指针的指针2022-4-20第十章 指针108Fpp、pp+1、pp+2都是指向
57、指针的指针,都是指向指针的指针,是常量是常量 F可以定义一个变量,指向指针可以定义一个变量,指向指针, 该变量该变量称为指向指针的指针变量称为指向指针的指针变量F定义:定义:Fchar *p;F p是指向指针的指针变量是指向指针的指针变量, p所指的指所指的指针针, 指向字符变量指向字符变量 (*表示表示“指向指向”)2022-4-20第十章 指针109F例如例如:Fint main() wjp28.cFF char *pp=“ab”, “cd”;F int i; F char *p;F p=pp;F for(i=0;i1)F F p+;F printf(“%sn”, *p);F n-;F F
58、 return 0;F2022-4-20第十章 指针113F设上面的程序编译后产生可执行文件设上面的程序编译后产生可执行文件 abc.exe,执行时在执行时在DOS命令行中键入命令行中键入: F abc hello world F则则DOS传给传给main函数函数n的值是的值是3, p是数组名是数组名, p0指向指向a, p1指向指向h, p2指向指向wF abc hello world F p0 p1 p2 2022-4-20第十章 指针114DOS的批处理文件允许使用参数的批处理文件允许使用参数, 如如:批处理文件名批处理文件名: aaa.bat作用作用: 在在C:盘上建立一个子目录盘上建
59、立一个子目录(目录名由用户指定目录名由用户指定),将根目录中的某文件拷贝到新建目录中将根目录中的某文件拷贝到新建目录中 批处理文件内容批处理文件内容: md %1 cd %1 copy %2 调用批处理文件:调用批处理文件:aaa mynew command.exe批处理文件中批处理文件中, %0总是指批处理文件的主文件名总是指批处理文件的主文件名(即命即命令名令名), %1%9代表参数代表参数, 这一点与这一点与C程序中带参数的程序中带参数的main函数很相似函数很相似2022-4-20第十章 指针115思考题:思考题:编写程序,以便将来在编写程序,以便将来在DOS命令行上调用它的时候,能命
60、令行上调用它的时候,能将后面的所有参数(都是整数)都加起来。将后面的所有参数(都是整数)都加起来。例如:设所编程序编译后得到可执行文件例如:设所编程序编译后得到可执行文件: abc.exe则下面窗口所示的调用方式下,程序的执行结果应该是则下面窗口所示的调用方式下,程序的执行结果应该是130。说明:说明:12-5+100+23=130,调用时参数个数不定。,调用时参数个数不定。2022-4-20第十章 指针116第八节第八节 指针数据类型和指针运算小结指针数据类型和指针运算小结F有关指针的数据类型有关指针的数据类型F指针运算指针运算:F指针变量自增自减指针变量自增自减F指针变量赋值指针变量赋值F两个指针变量相减两个指针变量相减F指针变量的比较指针变量的比较2022-4-20第十章 指针117一、指针数据类型一、指针数据类型Fint i; 整型变量整型变量Fint *p; 指向整型变量的指针变量指向整型变量的指针变量Fint an; 整型变量组成的数组整型变量组成的数组Fint (*p)n; 指向整型一维数组的指针指向整型一维数组的指针
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年胆维丁乳剂项目可行性研究报告
- 2024年铜防盗链项目可行性研究报告
- 2024年粉碎机小型手推切边机项目可行性研究报告
- 2023年太阳能海水淡化装置项目成效分析报告
- 合同协议订金合同的续签与终止条件
- 智能制造行业合作方案
- 多元文化服装行业营销策略方案
- 3D打印机的维护行业营销策略方案
- 标准打井施工合同样本
- 标准版绿化服务合同
- 251直线与圆的位置关系(第1课时)(导学案)(原卷版)
- 2024浙江绍兴市人才发展集团第1批招聘4人(第1号)高频难、易错点500题模拟试题附带答案详解
- 幼儿园说课概述-课件
- 冠状动脉介入风险预测评分的临床应用
- 35导数在经济中的应用
- 苏科版(2024新版)七年级上册数学期中学情评估测试卷(含答案)
- 部编版《道德与法治》三年级上册第10课《父母多爱我》教学课件
- 期中模拟检测(1-3单元)2024-2025学年度第一学期西师大版二年级数学
- 气管插管操作规范(完整版)
- 2024-2025学年外研版英语八年级上册期末作文范文
- 四级劳动关系协调员试题库含答案
评论
0/150
提交评论