实验8 指针的应用
实验八指针得应用(2学时)
实验前必须做得操作
..新建文件夹
.....:.
.........——
首先在各自对应得计算机ncre(k:)盘上对应座位号文件夹内新建一个文件夹,文件夹得名字为“班级+学号得后两位+姓名”,如座位号为K02,航海1111班、学号后两位就是02得、姓名为“张强”得同学,则其对应得文件夹名字就是:航海111102张强。然后在刚才建好得文件夹里面再建立一个文件夹,文件夹为“实验8”。
【实验目得】
1、掌握指针得概念、指针变量定义格式;
2、掌握指针得运算;
3、学会用指针对变量进行操作;
4、掌握指针与数组得关系;
5、了解通过指针操作字符串得方法;
6、了解指针与函数得关系;
7、了解指向指针变量得指针。
【实验内容】
[实验任务一]:补充完整程序,掌握C语言中与指针有关得算法。
程序填空实例8-1:使用指针把从键盘输入得2个数按从大到小得顺序输出(不改变变量得值),请补充完整并上机调试、将填空后完整得程序以文件名为blank8_1。c保存在实验8文件夹里、(需要存盘)
程序填空实例8—2:输入10个整数存入一维数组,再按逆序重新调整该数组中元素得顺序然后再输出、下面给出部分程序得内容,请将程序补充完整,然后上机调试。
将填空后完整得程序以文件名为nixu_1。c保存在实验8文件夹里。(需要存盘)
将填空后完整得程序以文件名为nixu_1、c保存在实验8文件夹里。(需要存盘)
程序填空实例8—3:用指针访问简单变量、从键盘输入三个整数,要求设三个指针变量p1,p2,p3,使p1指向三个数得最大者,p2指向次大者,p3指向最小者,然后按由小到大得顺序输出这三个数、将填空后完整得程序以文件名为blank8_3.c保存在实验8文件夹里。(需要存盘)
程序填空实例8-4:用指针来处理一维数组元素。从键盘上输入若干个字符,以符号“”结束。编一个C 程序,统计这些符号得个数(不包括)存入数组元素a[0],将这些符号依次存入a[1]、a[2]、a[3]、…中。接着利用a[0]中存放得字符个数,输出这些字符。将填空后完整得程序以文件名为blank8_4。c 保存在实验8文件夹里。(需要存盘)
【待填充得源程序参考清单】?#include voidmain() {char a[100]={0}, =a, c; scanf (”%c”, &c); while( ) {; ; *pa=c; scanf("%c",&c); } printf(”\nnumberof string: %d\nstring:\n", a[0]); for(pa=a+1;pa<=;pa++) printf("%c",*pa); printf("\n"); } [实验任务二]:通过调试与补充实例程序,以达到能正确使用指针变量作为函数得参数进行地址传递得目得。 编程实例8-1:编一个函数int fun(*char ss),它得功能就是:把ss字符串中得字符按逆序存放。例如:若输入字符串为ABCDEFG,则逆置后得字符串为GFEDCBA。请勿改动主函数main与其它函数中得任何内容,仅在函数fun得花括号中填入您编写得若干语句、 #include <stdio、h〉 #include<string.h〉 #define M81 int fun(char *ss) {/*答题开始*/ ┇ ┇ /*答题开始 */ } voidmain( ) {char*a; printf("\nPlease enter a string:"); gets(a); fun(a); printf(”\nThe newstring is:%s\n", a); } 将编写好得程序以文件名daoxu。c最终保存在实验8文件夹里。(需要存盘) 编程实例8-2:下面程序用来实现a,b两个数得交换。 #include <stdio.h> void main( ) {inta, b, *pa, *pb; printf(“please inputtwo integer numbers:\n”); scanf(“%d%d”, &a,&b); printf(“the values of a and b before exchangingare:\n”); printf(“a=%d b=%d\n”, a, b); pa=&a; pb=&b; s, pb); printf(“the values of a andbafter exchangingare: \n”); printf(“a=%d b=%d\n",a, b); } s *p1, int*p2) {int*p; *p=*p1; *p1=*p2; *p2=*p; } 【问题】:①上述程序能否完成两个数互换得目地,为什么?如何改正? ②若把swap函数改写成如下形式: 能否达到此目得,为什么?如何改正。 将改正好得程序以文件名swap。c保存在实验8文件夹里。(需要存盘) [实验任务三]:通过设计一个实际例子掌握数组、指针与函数得综合编程方法、 设计程序实例8—1:打印最高分与学号 假设每班人数最多不超过40人,具体人数由键盘输入,试编程打印最高分及其学号、 程序1 用一维数组与指针变量作为函数参数,编程打印某班一门课成绩得最高分及其学号。 程序2 用二维数组与指针变量作为函数参数,编程打印3个班学生(假设每班4个学生)得某门课成绩得最高分,并指出具有该最高分成绩得学生就是第几个班得第几个学生、 程序3用指向二维数组第0行第0列元素得指针作为函数参数,编写一个能计算任意m行n列二维数组中元素得最大值,并指出其所在得行列下标值得函数,利用该函数计算3个班学生(假设每班4个学生)得某门课成绩得最高分,并指出具有该最高分成绩得学生就是第几个班得第几个学生。 程序 4 编写一个计算任意m行n列二维数组中元素得最大值,并指出其所在得行列下标值得函数,利用该函数与动态内存分配方法,计算任意m个班、每班n个学生得某门课成绩得最高分,并指出具有该最高分成绩得学生就是第几个班得第几个学生。 【思考题】请读者思考: ①编写一个能计算任意m行n列得二维数组中得最大值,并指出其所在得行列下标值得函数,能否使用二维数组或者指向二维数组得行指针作为函数参数进行编程实现呢?为什么? ②请读者自己分析动态内存分配方法(题目要求中得程序4)与二维数组(题目要求中得程序3)两种编程方法有什么不同?使用动态内存分配方法存储学生成绩与用二维数组存储学生成绩相比,其优点就是什么? 【说明】:初学者通常都会对指针望而生畏,其实只要从原理上掌握了指针得概念,它就会变得如此简单而易用。首先,指针不过就是C语言提供得一种比较特殊得数据类型而已,定义为指针类型得变量与其它类 型得变量相比,主要差别在于指针变量得值就是一个内存地址。其次,在C语言中,指针与数组之间有着密不可分得关系,不带下标得数组名就就是一个指针,它代表数组元素得首地址,只要让声明为相同基类型得指针变量指向数组元素得首地址,那么对数组元素得引用,既可以用下标法,也可以用指针法,用指针法存取数组比用数组下标存取数组速度快一些。反之,任何指针变量也可以取下标,可以像对待数组一样来使用。虽然多维数组得地址概念稍微麻烦些,但只要知道它得元素在内存中就是如何存放得,使用也就不难了,由于C语言中得多维数组都就是按列存放得,因此,用指针法引用时,必须知道数组得一行有多长(即列得维数)。在某种意义上,二维数组类似于一个由指向行数组得指针构成得一维指针数组。多于二维得数组可以通过类似方法进行降维处理。 指针得一个重要应用就是用指针作函数参数,为函数提供修改调用变元得手段。当指针作函数参数使用时,需要将函数外得某个变量得地址传给函数相应得指针变元,这时,函数内得代码可以通过指针变元改变函数外得这个变量得值。 指针得另一个重要应用就是同动态内存分配函数联用,使得定义动态数组成为可能。 本题程序1中,用到了一维数组作为函数参数,程序2用到了指向二维数组得行指针作函数参数,程序3用到了指向二维数组得列指针作函数参数,程序4用到了动态内存分配实现动态数组。 【设计程序实例8—1得参考答案】: 程序1参考答案: #include #define ARR_SIZE40 int FindMax(int score[],long num[], int n, long *pMaxNu m); void main() { int score[ARR_SIZE], maxScore, n, i; long num[ARR_SIZE], maxNum; printf(”Please enter total number:”); ?scanf(”%d",&n); /*从键盘输入学生人数n*/ ?printf("Please enter the number and score:\n”); ?for(i=0;i ?{ ?scanf(”%ld%d”, &num[i], &score[i]); } maxScore = FindMax(score, num, n,&maxNum);/*计算最高分及其学号*/ ?printf("maxScore = %d, maxNum = %ld\n”,maxScore, maxNum); } /*函数功能:计算最高分及最高分学生得学号 函数参数:整型数组score,存储学生得成绩 长整型数组num,存储学生得学号 ?长整型指针变量pMaxNum,存储求出来得最高分学生得学号 函数返回值:最高分 */ int FindMax(int score[], long num[], int n, long *pMaxNum) { ?int i; ?int maxScore; ?maxScore=score[0]; *pMaxNum= num[0]; /*假设score[0]为最高分*/ ?for (i=1; i〈n; i++) if(score[i]> maxScore) { ??maxScore = score[i];/*记录最高分*/ ?*pMaxNum = num[i]; /*记录最高分学生得学号num[i]*/ } ?return (maxScore); /*返回最高分maxScore*/ } 程序运行结果如下: Please enter total number:5↙ Please enter the number and score: 99011 84↙ 9901283↙ 99013 88↙ 99014 87↙ 99015 61↙ maxScore=88, maxNum=99013 程序2参考答案: #include #define CLASS 3 #define STU 4 int FindMax(intscore[CLASS][STU], int m, int *pRow, int *pCol); void main() { int score[CLASS][STU], i,j, maxScore, row, col; printf("Pleaseenter score:\n"); ?for (i=0; i<CLASS; i++) ?{ ??for(j=0; j〈STU; j++) ?{ ??scanf("%d", &score[i][j]); /*输入学生成绩*/ ?} ?} ?/*计算最高分及其所在班号与学号*/ ?maxScore =FindMax(score, CLASS, &row, &col); ?printf("maxScore = %d,class = %d, number = %d\n", ??maxScore, row+1,col+1); } /*函数功能: 计算任意m行STU列得二维数组中得最大值、并指出其所在行列下标值函数入口参数:二维整型数组score,存储学生得成绩 整型变量m,二维整型数组得行数,代表班级数 函数出口参数:整型指针变量pRow,指向数组最大值所在得行 整型指针变量pCol,指向数组最大值所在得列 函数返回值: 数组元素得最大值 */ intFindMax(int score[][STU],int m, int *pRow, int*pCol) ?maxScore = score[0][0]; /*置初值,假设第一个元素值最大*/ *pRow =0; ?*pCol =0; ?for (i=0;i ?{ ??for (j = 0; j〈STU; j++) ?{ i f (score[i][j]> maxScore) ???{ ???maxScore =score[i][j]; /*记录当前最大值*/ ??*pRow =i; /*记录行下标*/ ?*pCol=j; /*记录列下标*/ } /*if结束*/ ??}/*内层for结束*/ } /*外层for结束*/ ?return (maxScore); /*返回最大值*/ } 程序3参考答案: #include 〈stdio.h〉 #define CLASS 3 #define STU 4 int FindMax(int*p,int m, intn,int *pRow,int*pCol); main() { ?int score[CLASS][STU], i, j, maxScore, row, col; ? printf(”Please enterscore:\n”); ?for (i=0; i<CLASS;i++) ?{ ?for(j=0; j〈STU;j++) ?{ ?scanf("%d”, &score[i][j]); /*输入学生成绩*/ } } ?/*计算最高分及其所在班号与学号*/ ??maxScore = FindMax(*score, CLASS, STU, &row, &col); printf("maxScore = %d,class= %d,number = %d\n”, ??maxScore, row+1, col+1); } /*函数功能: 计算任意m行n列得二维数组中得最大值、并指出其所在得行列下标值 ?函数入口参数:整型指针变量p,指向一个二维整型数组得第0行第0列 整型变量m,二维整型数组得行数 整型变量n,二维整型数组得列数 函数出口参数:整型指针变量pRow,指向数组最大值所在得行 整型指针变量pCol,指向数组最大值所在得列 函数返回值: 数组元素得最大值 */ int FindMax(int *p,int m, int n, int *pRow,int *pCol) ? maxScore=p[0]; /*置初值,假设第一个元素值最大*/ *pRow= 0; ?*pCol=0; for (i = 0;i { for (j = 0; j〈n; j++) { ???if (p[i*n+j]〉maxScore) ??{ ?maxScore= p[i*n+j]; /*记录当前最大值*/ ??*pRow =i; /*记录行下标*/ ???*pCol = j;/*记录列下标*/ ??} /*if结束*/ ?} /*内层for结束*/ } /*外层for结束*/ return (maxScore); /*返回最大值*/ } 程序运行结果如下: Please enter score: 8172 73 64↙ 65 867788↙ 91 90 85 92↙ max = 92, class= 3,number = 4 程序4参考答案: #include〈stdio.h> #include intFindMax(int*p,int m, int n,int *pRow, int *pCol); main() { ?int*pScore,i, j, m,n, maxScore,row, col; printf(”Pleaseenter array sizem,n:”); scanf("%d,%d", &m,&n); /*输入班级数m与学生数n*/ ?/*申请m*n个sizeof(int)字节得存储空间*/ ?pScore= (int *) calloc(m*n, sizeof(int)); ?if (pScore == NULL) { ?printf("No enough memory!\n"); ??exit(0); } ?printf("Please enter the score:\n"); ?for (i = 0; i〈m; i++) ?{ for (j= 0; j〈n; j++) ?{ ??scanf(”%d",&pScore[i*n+j]); /*输入学生成绩*/} ?} maxScore =FindMax(pScore,3, 4, &row, &col); /*调用函数FindMax*/ ?/*输出最高分max及其所在得班级与学号*/ ?printf(”maxScore=%d, class= %d,number =%d\n”, ?maxScore, row+1,col+1); ?free(pScore); /*释放向系统申请得存储空间*/ } /*函数功能: 计算任意m行n列得二维数组中得最大值,并指出其所在行列下标值函数入口参数:整型指针变量p,指向一个二维整型数组得第0行第0列 整型变量m,二维整型数组得行数 整型变量n,二维整型数组得列数 函数出口参数:整型指针变量pRow,指向数组最大值所在得行 整型指针变量pCol,指向数组最大值所在得列 函数返回值: 数组元素得最大值 */ int FindMax(int *p, int m, int n, int*pRow, int *pCol) { int i, j,max; max = p[0]; /*置初值,假设第一个元素值最大*/?*pRow = 0; ?*pCol =0; ?for(i = 0; i { ?for(j = 0; j〈n;j++) ??{ ??if (p[i*n+j]〉max) { ???max = p[i*n+j]; /*记录当前最大值*/ ?*pRow =i; /*记录行下标*/ ??*pCol = j; /*记录列下标*/ ???}/*if结束*/ ??} /*内层for结束*/ }/*外层for结束*/ return (max); /*返回最大值*/ } 程序运行结果如下: Please enter arraysize m,n:3,4↙ Pleaseenter the score: 81 72 73 64↙ 65 86 77 88↙ 91 90 85 92↙ maxScore = 92, class = 3, number = 4 ★作业上交(千万不要忘记):? C程序编译、连接、运行成功后,请务必将源程序(扩展名为、C、存于E:盘以本人姓名为名称得文件夹下,如E:\匡珍春\c01。c)复制到K:盘对应得文件夹中,如K(01):\ 陆上110105匡珍春\实验8,才算上交作业、 注:为了方便自己使用,不妨将源程序备份到可移动存储器上(如U盘、手机卡等)