第8章 指针
本章习题均要求用指针方法处理。
目录
3.输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写3个函数:①输入10个数;②进行处理;③输出10个数。
4.有n个整数,使前面各数顺序向后移m个位置,最后m个数变成最前面m个数,见图8.43。写一函数实现以上功能,在主函数中输入n个整数和输出调整后的n个数。
5.有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
6.写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。
7.有一字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串。
8.输入一行文字,找出其中大写字母、小写字母、空格、数字以及其他字符各有多少。
10.将一个5×5的矩阵中最大的元素放在中心,4个角分别放4个最小的元素(顺序为从左到右,从上到下依次从小到大存放),写一函数实现之。用main函数调用。
11.在主函数中输入10个等长的字符串。用另一函数对它们排序。然后在主函数输出这10个已排好序的字符串。
17.写一函数,实现两个字符串的比较。即自己写一个strcmp函数,函数原型为
18.编一程序,输入月份号,输出该月的英文月名。例如,输入3,则输出"March",要求用指针数组处理。
19.(1)编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
20.用指向指针的指针的方法对5个字符串排序并输出。
21.用指向指针的指针的方法对n个整数排序并输出。要求将排序单独写成一个函数。n个整数在主函数中输入,最后在主函数中输出。
1.输入3个整数,按由小到大的顺序输出。
#include <stdio.h>
int main() {
int a, b, c, t;
int *p = &a, *q = &b, *s = &c;
printf("请输入a、b和c的值:");
scanf("%d%d%d", p, q, s);
if(*p > *q) {
t = *p;
*p = *q;
*q = t;
}
if(*p > *s) {
t = *p;
*p = *s;
*s = t;
}
if(*q > *s) {
t = *q;
*q = *s;
*s = t;
}
printf("\n从小到大:%3d%3d%3d\n", *p, *q, *s);
return 0;
}
2.输入3个字符串,按由小到大的顺序输出。
#include <stdio.h>
#include <string.h>
#define M 80
int main() {
char a[M], b[M], c[M], t[M];
char *p = a, *q = b, *s = c;
printf("请输入字符串a:");
gets(p);
printf("请输入字符串b:");
gets(q);
printf("请输入字符串c:");
gets(s);
if(strcmp(p, q) > 0) {
strcpy(t, p);
strcpy(p, q);
strcpy(q, t);
}
if(strcmp(p, s) > 0) {
strcpy(t, p);
strcpy(p, s);
strcpy(s, t);
}
if(strcmp(q, s) > 0) {
strcpy(t, q);
strcpy(q, s);
strcpy(s, t);
}
printf("\n从小到大:\n");
puts(p);
puts(q);
puts(s);
return 0;
}
3.输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写3个函数:①输入10个数;②进行处理;③输出10个数。
#include <stdio.h>
#define M 10
void input(int *p) {
int i;
printf("请输入10个整数:\n");
for(i = 0; i < 10; i++) {
scanf("%d", p + i);
}
}
void process(int *p) {
int i, max, min, t1, t2;
for(i = 0, min = 0; i < 10; i++) {
if(*(p + min) > *(p + i)) {
min = i;
}
}
t1 = *(p);
*(p) = *(p + min);
*(p + min) = t1;
for(i = 1, max = 0; i < 10; i++) {
if (*(p + max) < *(p + i)) {
max = i;
}
}
t2 = *(p + 9);
*(p + 9) = *(p + max);
*(p + max) = t2;
}
void output(int *p) {
int i;
printf("\n");
for(i = 0; i < 10; i++) {
printf("%d ", *(p + i));
}
}
int main() {
int a[M];
input(a);
process(a);
output(a);
return 0;
}
4.有n个整数,使前面各数顺序向后移m个位置,最后m个数变成最前面m个数,见图8.43。写一函数实现以上功能,在主函数中输入n个整数和输出调整后的n个数。
#include <stdio.h>
#define M 80
void fun(int *p, int n, int m) {
int i, b[M], *q = p + n - m, *s = b;
for(i = 0; i < m; i++) *s++ = *q++;
q--;
for(i = 0; i < n - m; i++, q--) *q = *(q - m);
for(i = m, s--; i > 0; i--) *q-- = *s--;
}
int main() {
int a[M], n, m, i;
printf("\n请输入n的值:");
scanf("%d", &n);
printf("\n请输入%d个整数:\n", n);
for(i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
printf("\n请输入m的值:");
scanf("%d", &m);
printf("\n调整前:\n");
for(i = 0; i < n; i++) {
printf("%d ", a[i]);
}
fun(a, n, m);
printf("\n调整后:\n");
for(i = 0; i < n; i++) {
printf("%d ", a[i]);
}
return 0;
}
5.有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
#include <stdio.h>
#define M 80
int main() {
int a[M], n, i, j, *p = a, *q;
printf("\n请输入n的值:");
scanf("%d", &n);
for(i = 0; i < n; i++) {
*(p + i) = i + 1;
}
j = 1;
q = p;
while(n != 1) {
if(j == 3) {
for(i = q - p; i < n; i++) {
*(p + i) = *(p + i + 1);
}
j = 1;
n--;
if(q == p + n) {
q = p;
}
continue;
}
j++;
q++;
if(q == p + n) {
q = p;
}
}
printf("\n最后留下的是第 %d 号\n", *(p));
return 0;
}
6.写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。
#include <stdio.h>
#define M 80
int fun(char *p) {
int len = 0;
while(*p != '\0') {
len++;
p++;
}
return len;
}
int main() {
char a[M];
int len;
printf("请输入字符串:");
gets(a);
len = fun(a);
printf("长度为%d\n", len);
return 0;
}
7.有一字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串。
#include <stdio.h>
#define M 80
void fun(char *p, char *q, int m) {
p = p + m - 1;
while(*p != '\0') *q++ = *p++;
*q = '\0';
}
int main() {
char a[M], b[M];
int m;
printf("请输入字符串:");
gets(a);
printf("\n请输入m的值:");
scanf("%d", &m);
fun(a, b, m);
printf("\n");
puts(a);
puts(b);
return 0;
}
8.输入一行文字,找出其中大写字母、小写字母、空格、数字以及其他字符各有多少。
#include <stdio.h>
#define M 80
int main() {
char a[M], *p = a;
int uLetter, dLetter, space, number, other;
uLetter = dLetter = space = number = other = 0;
printf("请输入字符串:");
gets(a);
while(*p != '\0') {
if(*p >= 'A' && *p <= 'Z') uLetter++;
else if(*p >= 'a' && *p <= 'z') dLetter++;
else if(*p == ' ') space++;
else if(*p >= '0' && *p <= '9') number++;
else other++;
p++;
}
printf("\n");
puts(a);
printf("\n大写字母:%d,小写字母:%d,空格:%d,数字:%d,其他:%d\n", uLetter, dLetter, space, number, other);
return 0;
}
9.写一函数,将一个3×3的整型矩阵转置。
#include <stdio.h>
#define M 3
void fun(int (*p)[M]) {
int i, j, t;
for(i = 1; i < M; i++) {
for(j = 0; j < i; j++) {
t = *((*(p + i)) + j);
*((*(p + i)) + j) = *((*(p + j)) + i);
*((*(p + j)) + i) = t;
}
}
}
int main() {
int a[M][M] = {1, 3, 5, 2, 4, 6, 8, 9, 10}, i, j;
printf("\n调整前:\n");
for(i = 0; i < M; i++) {
for(j = 0; j < M; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
fun(a);
printf("\n调整后:\n");
for(i = 0; i < M; i++) {
for(j = 0; j < M; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
10.将一个5×5的矩阵中最大的元素放在中心,4个角分别放4个最小的元素(顺序为从左到右,从上到下依次从小到大存放),写一函数实现之。用main函数调用。
#include <stdio.h>
#define M 5
void fun(int *p) {
int i, j, t, *max = p, *min = p;
for(i = 0; i < M; i++) {
for(j = 0; j < M; j++) {
if(*max < *(p + 5 * i + j)) max = p + 5 * i + j;
if(*min > *(p + 5 * i + j)) min = p + 5 * i + j;
}
}
t = *max;
*max = *(p + 12);
*(p + 12) = t;
t = *min;
*min = *p;
*p = t;
for(i = 0; i < M; i++) {
for(j = 0; j < M; j++) {
if((p + 5 * i + j) != p && *min > *(p + 5 * i + j)) min = (p + 5 * i + j);
}
}
t = *min;
*min = *(p + 4);
*(p + 4) = t;
for(i = 0; i < M; i++) {
for(j = 0; j < M; j++) {
if((p + 5 * i + j) != p && (p + 5 * i + j) != p + 4 && *min > *(p + 5 * i + j)) min = (p + 5 * i + j);
}
}
t = *min;
*min = *(p + 20);
*(p + 20) = t;
for(i = 0; i < M; i++) {
for(j = 0; j < M; j++) {
if((p + 5 * i + j) != p && (p + 5 * i + j) != p + 4 && (p + 5 * i + j) != p + 20 && *min > *(p + 5 * i + j)) min = (p + 5 * i + j);
}
}
t = *min;
*min = *(p + 24);
*(p + 24) = t;
}
int main() {
int a[M][M] = {2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 12, 14, 16, 18, 20, 11, 13, 15, 17, 19, 22, 24, 26, 28, 30}, i, j;
printf("\n调整前:\n");
for(i = 0; i < M; i++) {
for(j = 0; j < M; j++) {
printf("%4d", a[i][j]);
}
printf("\n");
}
fun(&a[0][0]);
printf("\n调整后:\n");
for(i = 0; i < M; i++) {
for(j = 0; j < M; j++) {
printf("%4d", a[i][j]);
}
printf("\n");
}
return 0;
}
11.在主函数中输入10个等长的字符串。用另一函数对它们排序。然后在主函数输出这10个已排好序的字符串。
#include <stdio.h>
#include <string.h>
#define M 10
#define N 80
void fun(char (*p)[N]) {
int i, j;
char s[N], *t = s;
for(i = 0; i < M - 1; i++) {
for(j = 0; j < M - i - 1; j++) {
if(strcmp(p[j], p[j + 1]) > 0) {
strcpy(t, p[j]);
strcpy(p[j], p[j + 1]);
strcpy(p[j + 1], t);
}
}
}
}
int main() {
char a[M][N];
int i;
printf("请输入10个等长字符串:\n");
for(i = 0; i < M; i++) {
gets(a[i]);
}
fun(a);
printf("\n从小到大:\n");
for(i = 0; i < M; i++) {
puts(a[i]);
}
return 0;
}
12.用指针数组处理上一题目,字符串不等长。
#include <stdio.h>
#include <string.h>
#define M 10
#define N 80
void fun(char *p[]) {
int i, j;
char s[N], *t = s;
for(i = 0; i < M - 1; i++) {
for(j = 0; j < M - i - 1; j++) {
if(strcmp(*(p + j), *(p + j + 1)) > 0) {
strcpy(t, *(p + j));
strcpy(*(p + j), *(p + j + 1));
strcpy(*(p + j + 1), t);
}
}
}
}
int main() {
char a[M][N], *p[M];
int i;
for(i = 0; i < M; i++) {
p[i] = a[i];
}
printf("请输入10个等长字符串:\n");
for(i = 0; i < M; i++) {
gets(p[i]);
}
fun(p);
printf("\n从小到大:\n");
for(i = 0; i < M; i++) {
puts(p[i]);
}
return 0;
}
13.写一个用矩形法求定积分的通用函数,分别求
#include <stdio.h>
#include <math.h>
double (*F[3])(double) = {sin, cos, exp};
double fun(double a, double b, double (*f)(double), int n) {
double w = (b - a) / n, s = 0.0, i;
for(i = 1; i <= n; i++) {
s += f(a + i * w) * w;
}
return s;
}
int main() {
double a, b;
int i;
for(i = 0; i < 3; i++) {
printf("\n请输入上限和下限:");
scanf("%lf %lf", &a, &b);
printf("%lf\n", fun(a, b, F[i], 20));
}
return 0;
}
14.将n个数按输入时顺序的逆序排列,用函数实现。
#include <stdio.h>
#define M 80
void fun(int *a, int n) {
int *p = a, *q = p + n - 1, t;
while(p < q) {
t = *p;
*p = *q;
*q = t;
p++;
q--;
}
}
int main() {
int a[M], n, i;
printf("\n请输入n的值:");
scanf("%d", &n);
printf("\n请输入%d个整数:\n", n);
for(i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
printf("\n\n逆序前:\n");
for(i = 0; i < n; i++) {
printf("%d", a[i]);
}
fun(a, n);
printf("\n\n逆序后:\n");
for(i = 0; i < n; i++) {
printf("%d", a[i]);
}
return 0;
}
15.有一个班4个学生,5门课程。①求第1门课程的平均分;②找出有两门以上课程不及格的学生,输出他们的学号和全部课程成绩及平均成绩;③找出平均成绩在90分以上或全部课程成绩在85分以上的学生。分别编3个函数实现以上3个要求。
#include <stdio.h>
#define M 4
#define N 5
void f1(float *p) {
int i;
float sum = 0.0;
for(i = 0; i < M; i++) {
sum += *(p + 5 * i);
}
printf("\n\n课程1的平均分:%f\n", sum / 4);
}
void f2(float *p) {
int i, j, count;
float sum;
printf("\n\n有两门以上课程不及格的学生:\n");
for(i = 0; i < M; i++) {
count = 0;
sum = 0.0;
for(j = 0; j < N; j++) {
sum += *(p + 5 * i + j);
if(*(p + 5 * i + j) < 60) count++;
}
if(count >= 2) {
printf("\n--学生%d:\n", i + 1);
for(j = 0; j < N; j++) {
printf("课程%d:%f\n", j + 1, *(p + 5 * i + j));
}
printf("平均成绩:%f\n", sum / 5);
}
}
}
void f3(float *p) {
int i, j, count;
float sum;
printf("\n\n有平均成绩在90分以上或全部课程成绩在85分以上的学生:\n");
for(i = 0; i < M; i++) {
count = 0;
sum = 0.0;
for(j = 0; j < N; j++) {
sum += *(p + 5 * i + j);
if(*(p + 5 * i + j) >= 85) count++;
}
if((sum / 5) >= 90 || count == 5) {
printf("\n--学生%d:\n", i + 1);
for(j = 0; j < N; j++) {
printf("课程%d:%f\n", j + 1, *(p + 5 * i + j));
}
printf("平均成绩:%f\n", sum / 5);
}
}
}
int main() {
float a[M][N] = {90,99,92,94,90,88,86,58,98,40,90,89,87,85,85,67,55,60,51,67}, i, j, *p = &a[0][0];
// float a[M][N], i, j, *p = a;
// printf("请分别输入10名学生的5门课成绩\n\n");
// for(i = 0; i < M; i++) {
// printf("--学生%d\n", i + 1);
// for(j = 0; j < N; j++) {
// printf("课程%d:", j + 1);
// scanf("%f", p + 5 * i + j);
// }
// printf("\n");
// }
f1(p);
f2(p);
f3(p);
return 0;
}
16.输入一个字符串,内有数字和非数字字符,例如:
A123x456 17960? 302tab5876
将其中连续的数字作为一个整数,依次存放到一数组a中。例如,123放在a[0],456放在a[1]……统计共有多少个整数,并输出这些数。
#include <stdio.h>
#include <string.h>
#define M 80
int main() {
char str[M], *p = str;
int a[M], *q = a, num = 0, flag = 0, i, n = 0;
printf("请输入字符串:");
gets(str);
while(*p != '\0') {
if(*p >= '0' && *p <= '9') {
num = num * 10 + *p - '0';
flag = 1;
} else if(flag == 1) {
*q = num;
q++;
num = 0;
flag = 0;
n++;
}
p++;
if (*p == '\0' && flag == 1) {
*q = num;
n++;
}
}
printf("\n");
puts(str);
for(i = 0; i < n; i++) {
printf("%d ", a[i]);
}
return 0;
}
17.写一函数,实现两个字符串的比较。即自己写一个strcmp函数,函数原型为
int strcmp(char * pl, char * p2);
设p1指向字符串s1,p2指向字符串s2。要求当s1=s2时,返回值为0;若s1≠s2,返回它们二者第1个不同字符的ASCII码差值(如"BOY"与"BAD",第2个字母不同,0与A之差为79-65=14)。如果s1>s2,则输出正值;如果s1<s2,则输出负值。
#include <stdio.h>
#define M 80
int strcmp(char *p, char *q) {
while(*p != '\0' && *q != '\0') {
if(*p != *q) return *p - *q;
p++;
q++;
}
if(*p == '\0') return *q;
else return *p;
}
int main() {
char a[M], b[M];
int res;
printf("请输入字符串a:");
gets(a);
printf("请输入字符串b:");
gets(b);
res = strcmp(a, b);
printf("res = %d", res);
return 0;
}
18.编一程序,输入月份号,输出该月的英文月名。例如,输入3,则输出"March",要求用指针数组处理。
#include <stdio.h>
#define M 13
#define N 20
int main() {
char a[M][N] = {"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}, *p = &a[0][0];
int month;
printf("\n请输入month的值:");
scanf("%d", &month);
puts(p + N * month);
return 0;
}
19.(1)编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
(2)写一函数free,将前面用new函数占用的空间释放。free(p)表示将p(地址)指向的单元以后的内存段释放。
#include <stdio.h>
#include <stdlib.h>
char* new(int n) {
return (char*)malloc(n * sizeof(char));
}
void mfree(char* p) {
free(p);
}
int main() {
char *p = NULL;
int n;
printf("\n请输入n的值:");
scanf("%d", &n);
p = new(n);
if(p == NULL) {
printf("内存分配失败!\n");
return 1;
}
printf("\n请输入字符串:");
scanf("%s", p);
printf("\n字符串为:");
puts(p);
printf("\n");
mfree(p);
printf("已释放----%s", p);
return 0;
}
20.用指向指针的指针的方法对5个字符串排序并输出。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define M 5
#define N 80
int main() {
char *p[M];
char t[N];
char **q = p;
int i, j;
for(i = 0; i < M; i++) {
p[i] = (char*)malloc(N * sizeof(char));
}
printf("\n请输入5个字符串:\n");
for(i = 0; i < M; i++) {
scanf("%s", p[i]);
}
for(i = 0; i < M - 1; i++) {
for(j = 0; j < M - i - 1; j++) {
if(strcmp(*(q + j), *(q + j + 1)) > 0) {
strcpy(t, *(q + j));
strcpy(*(q + j), *(q + j + 1));
strcpy(*(q + j + 1), t);
}
}
}
printf("\n排序后:\n");
for(i = 0; i < M; i++) {
puts(p[i]);
}
for(i = 0; i < M; i++) {
free(p[i]);
}
return 0;
}
21.用指向指针的指针的方法对n个整数排序并输出。要求将排序单独写成一个函数。n个整数在主函数中输入,最后在主函数中输出。
#include <stdio.h>
#include <stdlib.h>
#define M 100
void sort(int **q, int n) {
int i, j, t;
for(i = 0; i < n - 1; i++) {
for(j = 0; j < n - i - 1; j++) {
if(*(*(q + j)) > *(*(q + j + 1))) {
t = *(*(q + j));
*(*(q + j)) = *(*(q + j + 1));
*(*(q + j + 1)) = t;
}
}
}
}
int main() {
int *p[M];
int **q = p;
int i, j, n;
printf("\n请输入n的值:");
scanf("%d", &n);
for(i = 0; i < n; i++) {
p[i] = (int*)malloc(sizeof(int));
}
printf("\n请输入n个整数:\n", n);
for(i = 0; i < n; i++) {
scanf("%d", p[i]);
}
sort(p, n);
printf("\n排序后:\n");
for(i = 0; i < n; i++) {
printf("%d ", *p[i]);
}
for(i = 0; i < n; i++) {
free(p[i]);
}
return 0;
}