diff --git a/report4.md b/report4.md index 29b80cf4d49ccb9c479e16e9ad80f5241c98d5b4..61e21234d644d890e7cd32a8ef003d79dc3dd9a7 100644 --- a/report4.md +++ b/report4.md @@ -20,3 +20,548 @@ (4)动态数组的应用。 +## 问题:指针典型应用 + +用指针实现下面 11 个函数。 + +### 1. 问题陈述 + +(1)指针访问数组元素 + +不用下标而用指针实现数组清零、数组输入和数组输出。 + +函数原型如下: + +``` +// 将数组 a 中 n 个元素全部清零 +void zeros(int a[], int n); +// 输入数组 a 中 n 个元素 +void input(int a[], int n); +// 输出数组 a 中 n 个元素 +void print(int a[], int n); + +``` + +参考测试程序: + +```c +int main(void) +{ + int a[10]; + + // 清零后打印 + zeros(a, 10); + print(a, 10); + + // 输入后打印 + printf("Enter 10 integer numbers: "); + input(a, 10); + print(a, 10); + + return 0; +} + +``` + +(2)指针做函数参数 + +用指针做函数参数可以实现交换两个元素、找数组最大和最小值等功能。 + +函数原型如下: + +``` +// 交换指针 a、b 指向的两个元素的值 +void swap(int *a, int *b); +// 找出数组 a[n] 中的最大元素和最小元素,并分别保存到指针 max 和 min 指向的变量中 +void max_min(int a[], int n, int *max, int *min); + +``` + +参考测试程序: + +```c +int main(void) +{ + // 交换元素 + int x = 3, y = 5; + + printf("Before swap: x = %d, y = %d\n", x, y); + swap(&x, &y); + printf("After swap: x = %d, y = %d\n", x, y); + + // 求最大最小值 + int a[10] = {2, 7, 1, 8, 2, 8, 4, 5, 9, 0}; + int max, min; + + max_min(a, 10, &max, &min); + printf("max = %d, min = %d\n", max, min); + + return 0; +} + +``` + +(3)返回指针 + +利用指针返回两个数中的最大值或最小值。 + +函数原型: + +``` +// 求两个数中的最大值 +int *max(int *a, int *b); +// 求两个数中的最小值 +int *min(int *a, int *b); + +``` + +参考测试程序: + +```c +int main(void) +{ + int x = 3, y = 5; + + int *pmax = max(&x, &y); + int *pmin = min(&x, &y); + printf("max = %d, min = %d%", *pmax, *pmin); + + return 0; +} + +``` + +(4)字符串 + +用指针处理字符串是最方便的,请利用指针和尽可能少的语句实现求字符串长度、复制字符串、字符串连接、字符串比较。 + +函数原型: + +``` +// 求字符串 s 的长度 +int mystrlen(const char *s); +// 将字符串 s 复制到字符数组 t 中,返回复制后的字符串 +char *mystrcpy(char *t, const char *s); +// 将字符串 s 连接到字符串 t 之后,返回连接后的字符串 +char *mystrcat(char *t, const char *s); +// 比较字符串 s 和 t,返回正、负和零分别表示串 s>t、s 0); // 1 + printf("%d\n", mystrcmp("Abc", "abc") < 0); // 1 + printf("%d\n", mystrcmp("Abc", "Abc") == 0); // 1 + + return 0; +} + +``` + +### 2. 输入输出描述 + + +- 【输入】:初始数据 +- 【输出】:符合要求的数据 + +### 3.演算示例 + +示例一:指针访问数组元素 + +测试结果如下: + +``` +0 0 0 0 0 0 0 0 0 0 +Enter 10 integer numbers: 1 2 3 4 5 6 7 8 9 0 +1 2 3 4 5 6 7 8 9 0 + +``` + +示例二:指针做函数参数 + +测试结果如下: + +``` +Before swap: x = 3, y = 5 +After swap: x = 5, y = 3 +max = 9, min = 0 + +``` + +示例三:返回指针 + +测试结果如下: + +``` +max = 5, min = 3 + +``` + +实例四:字符串 + +测试结果如下: + +``` +5 +Hello +Hello world +1 +1 +1 + +``` + +### 4. 算法设计 + +#### (1)指针访问数组元素 + +伪代码如下: + +``` +// 将数组 a 中 n 个元素全部清零 +void zeros(int a[], int n) + FOR i = 0 TO n - 1 DO + a[i] = 0; + END +END + +// 输入数组 a 中 n 个元素 +void input(int a[], int n) + FOR i = 0 TO n - 1 DO + 输入数组a[i]中的元素 + END FOR +END + +// 输出数组 a 中 n 个元素 +void print(int a[], int n) + FOR i = 0 TO n - 1 DO + IF (i > 0) + 打印空格 + END IF + 打印数组a[i]中的元素 + END FOR +打印换行符 +END + +``` + +程序代码: + +```c + +#include +// 将数组 a 中 n 个元素全部清零 +void zeros(int a[], int n) +{ + for (int i = 0; i < n; i++) + a[i] = 0; +} + +// 输入数组 a 中 n 个元素 +void input(int a[], int n) +{ + for (int i = 0; i < n; i++) + scanf("%d", &a[i]); +} + +// 输出数组 a 中 n 个元素 +void print(int a[], int n) +{ + for (int i = 0; i < n; i++) { + if (i > 0) + printf(" "); + + printf("%d", a[i]); + } + printf("\n"); +} + +int main(void) +{ + int a[10]; + + // 清零后打印 + zeros(a, 10); + print(a, 10); + + // 输入后打印 + printf("Enter 10 integer numbers: "); + input(a, 10); + print(a, 10); + + return 0; +} +``` + +#### (2)指针做函数参数 + +伪代码如下: + +``` +// 交换指针 a、b 指向的两个元素的值 +void swap(int* a, int* b) + int t = *a; + *a = *b; + *b = t; + +// 找出数组 a[n] 中的最大元素和最小元素,并分别保存到指针 max 和 min 指向的变量中 +void max_min(int a[], int n, int* max, int* min) + +*max = a[0]; +FOR i = 1 TO n - 1 DO + IF(a[i] > *max) + *max = a[i]; + END IF +END FOR + +*min = a[0]; +FOR i = 1 TO n - 1 DO + IF(a[i] < *min) + *min = a[i]; + END IF +END FOR + +``` + +程序代码: + +```c +#include +// 交换指针 a、b 指向的两个元素的值 +void swap(int* a, int* b) +{ + int t = *a; // t为变量,a、b为指针指向变量 + *a = *b; //*a为a指向的变量,*b为b指向的变量 + *b = t; +} + +// 找出数组 a[n] 中的最大元素和最小元素,并分别保存到指针 max 和 min 指向的变量中 +void max_min(int a[], int n, int* max, int* min) +{ + // 求最大值 + *max = a[0]; // max、min为指针指向某一变量(最大值最小值) + for (int i = 1; i < n; i++) + if (a[i] > *max) + *max = a[i]; + + // 求最小值 + *min = a[0]; // max、min为指针指向某一变量(最大值最小值) + for (int i = 1; i < n; i++) + if (a[i] < *min) + *min = a[i]; +} + +int main(void) +{ + // 交换元素 + int x = 3, y = 5; + + printf("Before swap: x = %d, y = %d\n", x, y); + swap(&x, &y); + printf("After swap: x = %d, y = %d\n", x, y); + + // 求最大最小值 + int a[10] = { 2, 7, 1, 8, 2, 8, 4, 5, 9, 0 }; + int max, min; + + max_min(a, 10, &max, &min); + printf("max = %d, min = %d\n", max, min); + + return 0; +} + +``` + +#### (3)返回指针 + +伪代码如下: + +``` +// 求两个数中的最大值 +int* max(int* a, int* b) +IF(*a >= *b) + return a; +ELSE + return b; +END IF + +// 求两个数中的最小值 +int* min(int* a, int* b) +IF(*a > *b) + return b; +ELSE + return a; +END IF + +``` + +程序代码: + +```c +#include +// 求两个数中的最大值 +int* max(int* a, int* b) +{ + if (*a >= *b) // a、b是指针指向变量,变量分别为*a,*b + return a; + else + return b; +} + +// 求两个数中的最小值 +int* min(int* a, int* b) +{ + if (*a > *b) // a、b是指针指向变量,变量分别为*a,*b + return b; + else + return a; +} + +int main(void) +{ + int x = 3, y = 5; + + int *pmax = max(&x, &y); + int *pmin = min(&x, &y); + printf("max = %d, min = %d%", *pmax, *pmin); + + return 0; +} + +``` + +#### (4)字符串 + +伪代码如下: + +``` +// 求字符串 s 的长度 +int mystrlen(const char* s) +WHILE(*s != '\0') + n++; + s++; +END WHILE +return n; +END + +// 将字符串 s 复制到字符数组 t 中,返回复制后的字符串 +char* mystrcpy(char* t, const char* s) +WHILE((*p = *s) != '\0') + p++; + s++; +END WHILE +return t; +END + +// 将字符串 s 连接到字符串 t 之后,返回连接后的字符串 +char* mystrcat(char* t, const char* s) +WHILE(*p != '\0') + p++; +END WHILE + +WHILE(*p = *s) + p++; + s++; +END WHILE +return t; + +// 比较字符串 s 和 t,返回正、负和零分别表示串 s>t、st、s 0); // 1 + printf("%d\n", mystrcmp("Abc", "abc") < 0); // 1 + printf("%d\n", mystrcmp("Abc", "Abc") == 0); // 1 + + return 0; +} + +``` + +### 5. 测试 + +程序运行结果与示例结果相同,测试通过。 + +### 小结 + +- 将指针与函数结合,实现要求数据的返回。 +- 利用指针更加准确高效地进行程序运行。