(1)重点掌握一级指针的定义与使用,会利用一级指针进行间接访问等操作。通过调试器观察分析程序的运行情况,理解指针与指针所指向的内容之间的关系,理解指针间接引用的实质。
(2)综合运用函数、数组和指针的知识,理解函数中指针形式参数的意义,数组名形参实质就是指针形参。通过跟踪调试理解传值与传地址的不同,及指针形参如何改变对应的实参变量。
(3)正确使用字符数组及字符指针处理字符串。
(4)进一步熟悉数组中经典算法的实现,并且能运用到字符串的处理中。
二、实验环境(实验设备)
硬件: 微型计算机
软件: Microsoft Visual C++6.0
三、实验原理及内容
实验题目(1)原样输入实验指导书实验六exp6_1.c源代码。要求:
① 编辑、编译、链接并运行程序,观察运行结果。
② 观察4个用于交换的函数,观察对应的形参与实参,注意正确的调用形式。分析为什么有的能实现实参变量的交换而有的不能。
③ 用F10键单步跟踪程序,运行到函数调用语句时改用F11键,进入被调函数内再用F10键观察每一步程序运行时实参与形参的作用域以及值的变化情况。
实验解答:
#include<stdio.h>
void swap1(int a, int b)
{
int t = a;
a = b;
b = t;
}
void swap2(int* a, int b)
{
int t = *a;
*a = b;
b = t;
}
void swap3(int* a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
void swap4(int* a, int b)
{
int* t = a;
a = b;
b = t;
}
int main()
{
int x = 3, y = 5;
swap1(x, y);
printf("after swap1,x=%d,y=%d\n", x, y);
x = 3,y = 5;
swap2(&x, y);
printf("after swap1,x=%d,y=%d\n", x, y);
x = 3, y = 5;
swap3(&x, &y);
printf("after swap1,x=%d,y=%d\n", x, y);
x = 3, y = 5;
swap4(&x, &y);
printf("after swap1,x=%d,y=%d\n", x, y);
}
①序的运行结果是:
after swap1,x=3,y=5
after swap1,x=5,y=5
after swap1,x=5,y=3
after swap1,x=3,y=5
② 观察4个用于交换的函数,观察对应的形参与实参,注意正确的调用形式。分析为什么有的能实现实参变量的交换而有的不能,填写下表:原
函数原型 | 对应实参 | 是否实现交换 | 原因分析 |
---|---|---|---|
void swap1( int a, int b ); | a b | 否 | 传值交换对应的实参不会发生改变 |
void swap2( int *a, int b ); | *a b | 否 | 第一个参数对应传地址,第二个参数对应传值,只有第一个参数会改变第二个参数不变 |
void swap3( int *a, int *b ); | *a *b | 是 | 标准形式传地址 |
void swap4(int *a, int *b ); | *a *b | 否 | 看起来像传地址实质上没有传,函数swap4中是传值变化 |
你能得出的结论:
③ 利用F10和F11功能键进行单步跟踪,观察各变量的变化情况,填写下表:
跟踪点 | 实参x的值 | 实参y的值 | 跟踪点 | 形参a的值 | 形参b的值 |
---|---|---|---|---|---|
swap1调用前 | -858993460 | -858993460 | swap1调用初 | -858993460 | -858993460 |
swap1调用后 | 3 | 5 | swap1调用止 | 3 | 5 |
swap 2调用后 | 3 | 5 | swap2调用止 | 3 | 5 |
swap 3调用后 | 5 | 3 | swap3调用止 | 5 | 3 |
swap4调用后 | 3 | 5 | swap4调用止 | 3 | 5 |
实验题目(2)定义一维数组和一级指针double array[10],*p,并依次完成如下功能:
①从键盘读入10个实数,保存到array数组中,通过指针p间接引用所有元素。
②打印这10元素及其对应的地址,通过下标法访问所有的元素。
③分别找出这组数的最大最小值,计算平均值并输出,通过指针p间接引用元素。
④对这10个数自选某种方法进行由小到大的排序,通过指针p间接引用所有元素。
⑤打印排序后数组的所有元素,通过指针p间接引用所有元素。
要求:所有的功能均定义函数,在主函数中进行调用实现,注意参数的正确使用。
实验解答:
① 请写出完整的源程序代码并做适当注释:
#include<stdio.h>
void input(double a[], int n)//从键盘读入10个实数,保存到array数组中,通过指针p间接引用所有元素。
{
double *p;
for (p = a;p < a + n;p++)
scanf_s("%lf", p);
}
void output(double a[], int n)//打印这10元素及其对应的地址,通过下标法访问所有的元素
{
int i;
for (i = 0;i < n;i++)
printf("%5.2f\t%p\n", a[i],a+i);
}
double ave(double a[], int n, double* pmax, double* pmin)//分别找出这组数的最大最小值,计算平均值并输出,通过指针p间接引用元素。
{
int i;
double s = a[0];
*pmax = *pmin = a[0];
for (i = 0;i < 0;i++)
{
if (a[i] > *pmax)
*pmax = a[i];
else if (a[i] < *pmin)
*pmin = a[i];
s += a[i];
}
return s / n;
}
void sort(double a[], int n)//对这10个数自选某种方法进行由小到大的排序,通过指针p间接引用所有元素
{
double* p, * q,t;
for (p = a;p < a + n - 1;p++)
for(q = p + 1;q < a + n;q++)
{
if (*p > *q)
{
t = *p;
*p = *q;
*q = t;
}
}
}
int main()
{
double array[10], *p,max,min,average;
p = array;
input(p, 10);
output(p, 10);
average = ave(p, 10, &max, &min);
printf("max=%f,min=%f,average=%f\n", max, min, average);
sort(p, 10);
output(p, 10);
return 0;
}
② 运行一次程序,写出你输入的数据,记录程序运行的结果:
1 3 5 6 8 4 2 1 3 9
1.00 010FFA34
3.00 010FFA3C
5.00 010FFA44
6.00 010FFA4C
8.00 010FFA54
4.00 010FFA5C
2.00 010FFA64
1.00 010FFA6C
3.00 010FFA74
9.00 010FFA7C
max=1.000000,min=1.000000,average=0.100000
1.00 010FFA34
1.00 010FFA3C
2.00 010FFA44
3.00 010FFA4C
3.00 010FFA54
4.00 010FFA5C
5.00 010FFA64
6.00 010FFA6C
8.00 010FFA74
9.00 010FFA7C
③ 使用调试器,进行单步或断点跟踪,观察数组某一个特定元素或所有元素在程序运行到某一步的值的情况,或随着程序的运行的变化情况,观察用数组名和指针名分别察看元素有何不同。
比如数组名-9.2559631349317831e+61 指针名有地址0x0055fbac {-9.2559631349317831e+61}
实验题目(3)编写程序,从键盘读入10个字符串,将这10个字符串进行由大到小的排序,并输出排序后的各字符串。要求:读入、输出、排序分别用函数实现。
实验解答:
①请写出源程序并作适当注释
#include<stdio.h>
#include<string.h>
#define N 10
#define MAX_LINE 80
char sort(char name[N][MAX_LINE]);
int main()
{
int i;
char name[N][MAX_LINE];
for (i = 0;i < N;i++)
scanf("%s", &name[i]);
sort(name);
printf("After sorted:\n");
for (i = 0;i < N;i++)
printf("%s\n", name[i]);
}
char sort(char name[N][MAX_LINE])
{
int i, j;
char temp[MAX_LINE];
for (i = 0;i < N - 1;i++)
{
for (j = 0;j < N - i - 1;j++)
{
if ((strcmp(name[j], name[j + 1])) > 0)
{
strcpy(temp, name[j]);
strcpy(name[j], name[j + 1]);
strcpy(name[j+1],temp);
}
}
}
}
实 验 报 告
②你管理多个字符串选用的是__用二维数组处理字符串_____,这样选择的理由是_______题目需要我们输入10个字符串假设输入的字符串的字符数不超过80_那么就当成二维数组来处理____________,优点是_简单______________________,如果该题目串的数量不是确定的10而是运行时任意读入的一个整数值n,要对n个串进行排序,你认为这种情况下可以改用_________插入排序_____________________________管理这些未知的串。
四、实验小结(包括问题和解决方法、心得体会、意见与建议、实验出错信息及解决方案等)
问题:对F10和F11功能键进行单步跟踪,观察各变量的变化情况还不是很熟悉
解决方法:多次实验,找到联系
心得体会;对与数组的应用还有待加强,对于指针变量的灵活性需要加强把握
实验出错信息:关于vs2019中scanf与scanf_s以及strcpy与strcpy_s的错误
解决方法:更改了系统属性中预处理器定义