C语言程序设计(第四版)谭浩强版 课后答案 第八章 指针
1、输出3个整数,按由小到大的顺序输出,写的复杂了,加上分析会变得简单,像下面输出3个字符(从小到大)
#include<stdio.h> int main(){ void compare(int *a,int *b,int *c); int a,b,c; printf("please input three numbers:"); scanf("%d%d%d",&a,&b,&c); compare(&a,&b,&c); printf("%d<%d<%d\n",a,b,c); return 0; } void compare(int *a,int *b,int *c){ int max; if(*a<*b){ if(*a>*c){ max = *a; *a = *b; *b = max; } if(*a<*c&&*c<*b){ max = *c; *c = *b; *b = max; } } if(*a>*b){ if(*b>*c){ max = *c; *c = *a; *a = max; } else if(*b<*c&&*c<*a){ max = *a; *a = *b; *b = *c; *c = max; } else{ max = *b; *b = *a; *a = max; } } }
2、为了代码简单,用了strcmp函数,也可以自己写一个strcmp函数
#include<stdio.h> #include<string.h> int main(){ void compare(char *a,char *b,char *c); char a[10],b[10],c[10]; printf("please input three string:"); scanf("%s%s%s",a,b,c); compare(a,b,c); printf("%s<%s<%s\n",a,b,c); return 0; } void compare(char*a,char *b,char *c){ char *p; if(strcmp(a,b)>0){ p = a; a = b; b = p; } if(strcmp(a,c)>0){ p = a; a = c; c = p; } if(strcmp(b,c)>0){ p = b; b = c; c = p; } }
3、输入10个数,单独输入,单独输出,并且把最大的一个数和最后一个数进行交换,最小的一个数和第一个进行交换。需要特别注意的传入的数组指针,进行操作过,已经从第一个数据指向了最后一个数据,如果在想通过指指针对数组的一些值进行操作,就需要把它在赋值成首指针,在进行操作。容易忽略,程序也没有报错,但是没有结果
#include<stdio.h> #define N 10 int main(){ void scan(int *p,int n); void trans(int *p,int n); void print(int *p,int n); int a[N]; scan(a,N); print(a,N); trans(a,N); print(a,N); return 0; } void scan(int *p,int n){ for(int i=0;i<n;i++){ scanf("%d",p++); } } void print(int *p,int n){ for(int i=0;i<n;i++){ printf("%d ",*p++); } printf("\n"); } void trans(int *p,int n){ int min=p[0],max=p[n-1]; int i,t,l,h; int *q; q=p; for(i=0;i<n;i++){ if(min>*q){ min = *q; l = i; } if(max<*q){ max = *q; h = i; } q++; } t = p[0]; p[0] = p[l]; p[l] = t; t = p[n-1]; p[n-1] = p[h]; p[h] = t; }
4、n个数,后面m个数放在前面,前面的n-m个数移到m个数的后面
#include<stdio.h> #define N 20 int main(){ void mhead(int *a,int n,int m); int a[N]; int n,m; int i; printf("please input the number :"); scanf("%d",&n); printf("please input numbers:"); for(i=0;i<n;i++){ scanf("%d",&a[i]); } printf("please input the number of behind :"); scanf("%d",&m); mhead(a,n,m); for(i=0;i<n;i++){ printf("%d ",a[i]); } printf("\n"); return 0; } void verse(int *a,int i,int j){ int t; j=j-1; for(;i<j;i++,j--){ t = a[i]; a[i] = a[j]; a[j] = t; } } void mhead(int *a,int n,int m){ verse(a,0,n); verse(a,0,m); verse(a,m,n); }
5、一圈人,每次报到3出局,问最后一个留下来的人是第几号(循环结束条件很重要,想了超级久;也能用单向循环链表实现,但是写的不对,可能后期会加进来)
#include<stdio.h> #include<stdio.h> #include<stdlib.h> #define N 20 int main(){ void delete3(int *p,int n); int n; int i; int a[N]; printf("please input number of people:"); scanf("%d",&n); for(i=0;i<n;i++){ a[i]=i+1; } delete3(a,n); for(i=0;i<n;i++){ if(a[i]!=0){ printf("%d ",a[i]); } } printf("\n"); return 0; } void delete3(int *p,int n){ int count=0; int i; int j=3; while(j>1){ for(i=0;i<n;i++){ if(p[i]!=0){ count++; } if(count==3){ count=0; p[i]=0; } } j=0; for(i=0;i<n;i++){ if(p[i]!=0) j++; } } }
6、字符串长度
#include<stdio.h> #define N 100 int main(){ int strlen(char *a); char a[N]; int l; printf("please input a string:"); scanf("%s",a); l=strlen(a); printf("%d\n",l); return 0; } int strlen(char *a){ int i=0; int count=0; while(a[i]!='\0'){ count++; i++; } return count; }
7、有一字符串,n个字符,将字符串中从第m个开始的全部字符复制成另一个字符串。
#include<stdio.h> int main(){ void replacen(char *a,char *b,int n); char a[20],b[10]; int n; printf("please input two strings:"); scanf("%s%s",a,b); printf("please input the location:"); scanf("%d",&n); replacen(a,b,n); printf("%s\n",a); return 0; } void replacen(char *a,char *b,int n){ int i = 0; while(b[i]!='\0'){ a[n-1]=b[i]; i++; n++; } a[n-1]='\0'; }
8、输入一行文字,找出其中大写字母,小写字母,空格,数字以及其他字符有多少
#include<stdio.h>//一开始程序总是不报错不显示结果,这种情况下fgets一般都是没有问题的, //循环出错了,如果用while一定要注意循环结束条件是不是没有处理好(这种情况出现了两次了) int main(){ void multinum(char *a); char a[20]; printf("please input the string :\n"); fgets(a,20,stdin); multinum(a); return 0; } void multinum(char *a){ int b=0,c=0,d=0,e=0,o=0; int i=0; while(a[i]!='\0'){ if(a[i]>='A'&&a[i]<='Z'){ b++; } else if(a[i]>='a'&&a[i]<='z'){ c++; } else if(a[i]>='0'&&a[i]<='9'){ d++; } else if(a[i]==' '){ e++; } else o++; i++; } printf("capital:%d,lowercase:%d,num:%d,blank:%d,other:%d\n",b,c,d,e,o); }
9、将3*3的矩阵转置
#include<stdio.h> #include<stdlib.h> #include<time.h> int main(){ srand((unsigned)time(NULL)); void T(int a[][3]); void print(int a[][3]); int a[3][3]; int i,j; for(i=0;i<3;i++){ for(j=0;j<3;j++){ a[i][j]=rand()%10; } } print(a); T(a); print(a); return 0; } void print(int a[][3]){ int i,j; for(i=0;i<3;i++){ for(j=0;j<3;j++){ printf("%4d",a[i][j]); } printf("\n"); } printf("\n"); } void T(int a[][3]){ int i,j,t; for(i=0;i<3;i++){ for(j=i;j<3;j++){ t = a[i][j]; a[i][j] = a[j][i]; a[j][i] = t; } } }
10、对5*5数组中间换成最大值,其他四个角落分别是最小值,从左到右,从上到下,从小到大依次存放(本来的想法是一次性把四个小的全部找到,确实也是可行的,但是第一个最小的和a[0][0]还完位置后,会影响其他地方的互换,所以还是建议一个一个找,一个一个换,代码目前没有改)
#include<stdio.h> #include<stdlib.h> #include<time.h> #define N 5 int main(){ srand((unsigned)time(NULL)); void T(int a[][N]); void print(int a[][N]); int a[N][N]; int i,j; for(i=0;i<N;i++){ for(j=0;j<N;j++){ a[i][j]=rand()%100; } } print(a); T(a); print(a); return 0; } void print(int a[][N]){ int i,j; for(i=0;i<N;i++){ for(j=0;j<N;j++){ printf("%4d",a[i][j]); } printf("\n"); } printf("\n"); } void T(int a[][N]){ int i,j,mx,my,max,t; int min[4][3]={{a[0][0],0,0},{a[1][0],1,0},{a[2][0],2,0},{a[3][0],3,0}};//怎么获取到四个最小值; max = a[2][2]; for(i=0;i<N;i++){ for(j=0;j<N;j++){ if(max<a[i][j]){ max = a[i][j]; mx = i; my = j; } } } t = a[2][2];//最大值互换 a[2][my] = t; /*for(i=0;i<4;i++){ for(j=i;j<4;j++){ if(min[i][0]>min[j][0]){ t = min[i][0]; min[i][0] = min[j][0]; min[j][0] = t; t = min[i][1]; min[i][1] = min[j][1]; min[j][1] = t; t = min[i][2]; min[i][2] = min[j][2]; min[j][2] = t; } } } printf("%d,%d,%d,%d\n",min[0][0],min[1][0],min[2][0],min[3][0]); //for(i=0;i<5;i++){//有个问题,有可能换过一次以后,最小值不在那个地方,怎么办呢,所以这个时候还是一个一个找最合适。 for(j=0;j<5;j++){ if(a[i][j] <= min[0][0]&&i!=min[0][1]&&j!=min[0][2]){ min[3][0] = min[2][0]; min[3][1] = min[2][1]; min[3][2] = min[2][2]; min[2][0] = min[1][0]; min[2][1] = min[1][1]; min[2][2] = min[1][2]; min[1][0] = min[0][0]; min[1][1] = min[0][1]; min[1][2] = min[0][2]; min[0][0] = a[i][j]; min[0][1] = i; min[0][2] = j; } else if (a[i][j]<=min[1][0]&&i!=min[1][1]&&j!=min[1][2]){ min[3][0] = min[2][0]; min[3][1] = min[2][1]; min[3][2] = min[2][2]; min[2][0] = min[1][0]; min[2][1] = min[1][1]; min[2][2] = min[1][2]; min[1][0] = a[i][j]; min[1][1] = i; min[1][2] = j; } else if(a[i][j]<=min[2][0]&&i!=min[2][1]&&j!=min[2][2]){ min[3][0] = min[2][0]; min[3][1] = min[2][1]; min[3][2] = min[2][2]; min[2][0] = a[i][j]; min[2][1] = i; min[2][2] = j; } else if(a[i][j]<=min[3][0]&&i!=min[3][1]&&j!=min[3][2]){ min[3][0] = a[i][j]; min[3][1] = i; min[3][2] = j; } } } printf("%d,%d,%d,%d\n",min[0][0],min[1][0],min[2][0],min[3][0]); printf("%d,%d,%d,%d\n",min[0][1],min[1][1],min[2][1],min[3][1]); printf("%d,%d,%d,%d\n",min[0][2],min[1][2],min[2][2],min[3][2]); t = a[0][0]; a[0][0] = a[min[0][1]][min[0][2]]; a[min[0][1]][min[0][2]] = t; t = a[0][4]; a[0][4] = a[min[1][1]][min[1][2]]; a[min[1][1]][min[1][2]] = t; t = a[4][0]; a[4][0] = a[min[2][1]][min[2][2]]; a[min[2][1]][min[2][2]] = t; t = a[4][4]; a[4][4] = a[min[3][1]][min[3][2]]; a[min[3][1]][min[3][2]] = t; */ //后期应该会补 }
11、12、见下一节三种写法
13、偷得,没太看
//写一个用矩形法求定积分的通用函数 #include<stdio.h> #include<math.h> double sinx(double x) { return sin(x); } double cosx(double x) { return cos(x); } double ex(double x) { return exp(x); } int main() { int flag; double (*p)(double);//此处定义指针函数 double h,i,a,b,n,sum,t; n=1000; sum=0; printf("请输入积分的上下线,中间用空格隔开:\n"); scanf("%lf %lf",&a,&b); if(a<b) { printf("输入错误,但已自动改正您输入的错误:\n"); t=a; a=b; b=t; } h=(a-b)/n; printf("请输入你要计算的积分0 sinx 1 cosx 2 ex\n"); scanf("%d",&flag); if(flag==0) p=sinx; else if(flag==1) p=cosx; else if(flag==2) p=ex; for(i=b;i<a;i+=h) //这一步是最重要的一步 sum+=p(i)*h; printf("%lf\n",sum); return 0; }
14、将n个数按输入时顺序的逆序排列,用函数实现
#include<stdio.h> #include<stdlib.h> int main(){ void vers(int *a,int n); int n; int *a; int i; printf("please input the number of digit:"); scanf("%d",&n); a = (int *)malloc(n*(sizeof(int))); for(i=0;i<n;i++){ scanf("%d",&a[i]); } vers(a,n); for(i=0;i<n;i++){ printf("%4d",a[i]); } printf("\n"); free(a); return 0; } void vers(int *a,int n){ int i,j,t; for(i=0,j=n-1;i<n/2;i++,j--){ t = a[i]; a[i] = a[j]; a[j] = t; } }
15、也是偷得,后期可能会改,真的很不喜欢写这个啊啊啊
#include<stdio.h> int main(){ float ave(int (*p)[5]); //函数声明 int score[4][5]={{78,86,55,59,90},{93,86,95,83,97},{89,88,90,86,91},{87,79,87,81,92}}; printf("第一门课程平均分:%.2f",ave(score)); //函数调用及结果输出 return 0; } float ave(int (*p)[5]){ //形参为指向一维数组的指针变量 int i; float sum=0; //平均分可能为小数,故用浮点型 for(i=0;i<4;i++,p++){ sum+=(*p)[0]; //累加每个学生的第一门课成绩 } return (sum/4); }
/*第二问*/
#include<stdio.h>
int main(){
void rev(int (*p)[5]); //函数声明
int score[4][5]={{78,86,55,59,90},{93,86,95,83,97},{89,88,90,86,91},{87,56,87,55,92}};
printf("两门以上成绩不及格的学生:\n"); //函数调用及结果输出
rev(score); //函数调用及其结果输出
return 0;
}
void rev(int (*p)[5]){ //形参为指向一维数组的指针变量
int i,j,sign=0; //0-1变量sign,用以判断该学生的成绩是否有两门及其以上科目不及格
for(i=0;i<4;i++,p++) //从第一个学生开始判断
for(j=0,sign=0;j<5;j++) //从第一个科目开始判断
if((*p)[j]<60) //如果当前科目成绩不及格
if(sign==1){ //且sign为1(之前有科目也不及格 )
printf("学号:%d;各科成绩:",i+1); //输出这个学生的学号
for(j=0;j<5;j++) //输出这个学生的所有科目成绩
printf("%d,",(*p)[j]);
printf("\n");
}
else sign=1; //如果sign不为1,这是该学生第一个不及格的科目,将sign置1
}
/*第三问*/
#include<stdio.h>
int main(){
void pd(int (*p)[5]); //函数声明
int score[4][5]={{78,86,55,59,90},{90,88,91,86,92},{89,84,97,95,91},{87,56,87,55,92}};
printf("平均成绩在90分以上或全部课程成绩在85分以上的学生学号:\n");
pd(score); //函数调用及结果输出
return 0;
}
void pd(int (*p)[5]){
int i,j,sign=0; //0-1变量sign,用以判断该学生的成绩是否有两门及其以上科目不及格
float sum;
for(i=0;i<4;i++,p++){ //从第一个学生开始判断
for(j=0,sign=0;j<5;j++){ //从第一个科目开始判断
if((*p)[j]<85) { //若当前分数小于于85分
sign=1; break; //置sign=1(及已经不满足所有科目成绩都大于85分)跳出循环进入下一情况的判断
}
else if(j==4&&sign==0) //当前科目是否是最后一个科目且sign=0(这位学生没有低于85分的科目)
printf("NO.%d\t",i+1); //满足条件则输出该生学号
}
if(sign==1){ //若sign=1,开始第二种情况的判断
for(j=0,sum=0;j<5;j++)
sum+=(*p)[j]; //累加该生没科成绩
if(sum/5>90) //平均分是否大于90
printf("NO.%d\t",i+1); //是则输出该生学号
}
}
}
16、输入一串带有数字的字符串比如456fg56,将数字整数都输出(456 56)
#include<stdio.h> int main(){ int numout(char *a,int *b); char a[30]; int b[20]; int n; int i; printf("please input a string:"); scanf("%s",a); n = numout(a,b); for(i=0;i<n;i++){ printf("%d",b[i]); printf("\n"); } return 0; } int numout(char *a,int *b){ int i=0; int j=0; int flag = 1; int sum=0; while(a[i]!='\0'){ if(a[i]>='0'&&a[i]<='9'){ if(0==flag){ flag =1 ; } sum = sum*10+(a[i]-'0'); } else{ flag = 0; if(sum!=0){ b[j] = sum; j++; sum = 0; } } i++; } if(a[i-1]>='0'&&a[i-1]<='9'){ b[j] = sum; j++; } return j; }
17、字符串比较
#include<stdio.h> int main(){ int strc(char *a,char *b); char a[20]; char b[20]; int n; printf("please input two strings:"); scanf("%s%s",a,b); n = strc(a,b); printf("%d\n",n); return 0; } int strc(char *a,char *b){ int i = 0; int n; while(a[i]!='\0'&&b[i]!='\0'){ if(a[i]!= b[i]){ n = a[i]-b[i]; break; } i++; } if(a[i]=='\0'&&b[i]=='\0') n = 0; if(a[i]=='\0'&&b[i]!='\0') n =-b[i]; if(a[i]!='\0'&&b[i]=='\0') n = a[i]; return n; }
18,输入相应月份,输出开头字母大写的月份,用指针数组实现。
#include<stdio.h> int main(){ char a[12][15]={"January","Feburary","March","April","May","June","July","August","September","October","November","December"}; char *p[12]; int n; int i; for(i=0;i<11;i++){ p[i]=a[i]; } printf("please input a month number:"); scanf("%d",&n); printf("%s\n",p[n-1]); return 0; }
19、编写一个new 和free函数,给n个字符分配空间,释放空间
#include<stdio.h> #include<stdlib.h> int main(){ char *new(int n); void myfree(char *a); char *a; int n; printf("please input a num:"); scanf("%d",&n); a = new(n); printf("before new p--%p:%s\n", a, a); myfree(a); printf("before new p--%p:%s\n", a, a); return 0; } char *new(int n){ return (char *)malloc(sizeof(char)*n); } void myfree(char *a){ free(a); }
20.用指向指针的指针的方法对五个字符串输出(指向一维指针数组的指针,每个)
#include<stdio.h> #include<string.h> int main(){ char *a[]={"abcd","befjirg","bbfkeorjgi","aajideo"}; char **p[4]; char *q; int i; int j; for(i=0;i<4;i++){ p[i]=&a[i]; } for(i=0;i<4;i++){ for(j=i;j<4;j++){ if(strcmp(*p[i],*p[j])>0){ q=*p[i]; *p[i]=*p[j]; *p[j]=q; } } } for(i=0;i<4;i++){ printf("%s\n",*p[i]); } return 0; }
21、用指向指针的方法对n个整数进行排序并输出(定义一个数组,和一个指针数组,把数组元素的每个地址给指针数组,二维指针指向一维指针数组)
#include<stdio.h> int main(){ void sort(int **p,int n); int str[20],*pstr[20],**p,n,i; printf("input n:"); scanf("%d",&n); for(i=0;i<n;i++) pstr[i]=&str[i]; printf("input %d number:",n); for(i=0;i<n;i++) scanf("%d",pstr[i]); p=pstr; sort(p,n); printf("now,the sequence is:\n"); for(i=0;i<n;i++) printf("%d ",*pstr[i]); printf("\n"); return 0; } void sort(int **p,int n){ int i,j,*temp; for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) {if(**(p+i)>**(p+j)){ temp=*(p+i); *(p+i)=*(p+j); *(p+j)=temp; } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)