资源描述
3fd4df26142a840b6f65b2909eac3df5.doc (匡珍春制作)
实验八 指针的应用(2学时)
实验前必须做的操作——新建文件夹:
1、先在对应的K:盘上建立一个父文件夹(用来存放本人整个学期的作业),格式为:“专业+班级+学号+姓名”,如:航海1091班、学号为05的匡珍春同学,其父文件夹名称为:航海109105匡珍春,然后在此父文件夹下建立子文件夹,名称为:实验8(用来存放实验8需要上交的文件)。
2、在E:盘上建立一个以本人姓名为名称的文件夹(本次实验的工作文件夹),例如:E:\匡珍春
【实验目的】
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 <stdio.h>
void main( )
{ char a[100]={0}, =a, c;
scanf ("%c", &c);
while( )
{ ;
;
*pa=c;
scanf("%c", &c);
}
printf("\nnumber of 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 M 81
int fun(char *ss)
{ /*答题开始 */
┇
┇
/*答题开始 */
}
void main( )
{ char *a;
printf("\nPlease enter a string:");
gets(a);
fun(a);
printf("\nThe new string is:%s\n", a);
}
将编写好的程序以文件名daoxu.c最终保存在实验8文件夹里。(需要存盘)
编程实例8-2:下面程序用来实现a,b两个数的交换。
#include <stdio.h>
void main( )
{ int a, b, *pa, *pb;
printf(“please input two integer numbers: \n”);
scanf(“%d%d”, &a, &b);
printf(“the values of a and b before exchanging are: \n”);
printf(“a=%d b=%d\n”, a, b);
pa=&a; pb=&b;
swap(pa, pb);
printf(“the values of a and b after exchanging are: \n”);
printf(“a=%d b=%d\n”, a, b);
}
swap(int *p1, int *p2)
{ int *p;
*p=*p1; *p1=*p2; *p2=*p;
}
【问题】:① 上述程序能否完成两个数互换的目地,为什么?如何改正?
② 若把swap函数改写成如下形式:
能否达到此目的,为什么?如何改正。
将改正好的程序以文件名swap.c保存在实验8文件夹里。(需要存盘)
[实验任务三]:上机调试《C语言程序设计上机指导与习题选解》P80-82的程序,并分析程序运行结果。将输入的完成程序依次以文件名8_1_1.c、8_1_2.c、8_1_3.c、8_1_4.c、8_2_1.c、8_2_2.c、8_3_1.c和8_3_2.c共8个.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 <stdio.h>
#define ARR_SIZE 40
int FindMax(int score[], long num[], int n, long *pMaxNum);
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<n; 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↙
99012 83↙
99013 88↙
99014 87↙
99015 61↙
maxScore = 88, maxNum = 99013
程序2参考答案:
#include <stdio.h>
#define CLASS 3
#define STU 4
int FindMax(int score[CLASS][STU], int m, int *pRow, int *pCol);
void main()
{
int score[CLASS][STU], i, j, maxScore, row, col;
printf("Please enter 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,指向数组最大值所在的列
函数返回值: 数组元素的最大值
*/
int FindMax(int score[][STU], int m, int *pRow, int *pCol)
{
int i, j, maxScore;
maxScore = score[0][0]; /*置初值,假设第一个元素值最大*/
*pRow = 0;
*pCol = 0;
for (i = 0; i<m; i++)
{
for (j = 0; j<STU; j++)
{
if (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, int n, int *pRow, int *pCol);
main()
{
int score[CLASS][STU], i, j, maxScore, row, col;
printf("Please enter score:\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)
{
int i, j, maxScore;
maxScore = p[0]; /*置初值,假设第一个元素值最大*/
*pRow = 0;
*pCol = 0;
for (i = 0; i<m; 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:
81 72 73 64↙
65 86 77 88↙
91 90 85 92↙
max = 92, class = 3, number = 4
程序4参考答案:
#include <stdio.h>
#include <stdlib.h>
int FindMax(int *p, int m, int n, int *pRow, int *pCol);
main()
{
int *pScore, i, j, m, n, maxScore, row, col;
printf("Please enter array size m,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<m; 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 array size m,n:3,4↙
Please enter 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):\ 航海109105匡珍春\实验8,才算上交作业。
注:为了方便自己使用,不妨将源程序备份到可移动存储器上(如U盘、手机卡等)
第 10 页 共 10 页
展开阅读全文