C程序设计(第二版) 第十章习题

 程序来自配套的习题解答一书。

10.2输入三个字符串,按由小到大的顺序输出
#include <stdio.h>
#include <string.h>

void main()
{
 char str1[50],str2[50],str3[50];
 void swap(char *p1,char *p2);
 printf("Input three lines:/n");
 gets(str1);
 gets(str2);
 gets(str3);
 if(strcmp(str1,str2)>0)
  swap(str1,str2);
 if(strcmp(str1,str3)>0)
  swap(str1,str3);
 if(strcmp(str2,str3)>0)
  swap(str2,str3);
 printf("Now,the order is :/n");
 printf("%s/n%s/n%s/n",str1,str2,str3);
}

void swap(char *p1, char *p2)
{
 char p[50];
 strcpy(p,p1);
 strcpy(p1,p2);
 strcpy(p2,p);
}

10.3输入10个数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写3个函数:(1)输入10个数(2)进行处理(3)输出10个数
#include <stdio.h>

void input(int array[])
{
 int *p;
 printf("Input 10 numbers:");
 for(p=array;p<array+10;p++)
  scanf("%d",p);
}

void max_min_value(int array[])
{
 int *max,*min,*p,t;
 max=min=array;
 for(p=array+1;p<array+10;p++)
 {
  if(*p>*max)
   max=p;
  else if (*p<*min)
   min=p;  
 }
 t=array[0];
 array[0]=*min;
 *min=t;

 t=array[9];
 array[9]=*max;
 *max=t;
}

void output(int array[])
{
 int *p;
 printf("Now ,they are:");
 for(p=array;p<array+10;p++)
  printf("%d ",*p);
}

void main()
{
 int number[10];
 input(number);
 max_min_value(number);
 output(number);
}

10.4有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面m个数。写一函数实现以上功能,在主函数中输入n个数,并输出调整后的n个数。
#include <stdio.h>

void move(int array[20],int n,int m)
{
 int *p,array_end; 
 for(;m>0;m--)
 {
  array_end=*(array+n-1);//先将最末数保存
  for(p=array+n-1;p>array;p--)//之前数依次后移一位
  {
   *p=*(p-1);
  }
  *array=array_end;//将最末数赋给首位
 }
 //递归解法
 //int *p,array_end;
 //array_end=*(array+n-1);
 //for(p=array+n-1;p>array;p--)
 //{
  //*p=*(p-1);
 //}
 //*array=array_end;
 //m--;
 //if(m>0)
  //move(array,n,m);
}

void main()
{
 int number[20],n,m,i;
 printf("How many numbers?");
 scanf("%d",&n);
 printf("Input %d numbers:/n",n);
 for(i=0;i<n;i++)
  scanf("%d",&number[i]);
 printf("How many place you want to move?");
 scanf("%d",&m);
 move(number,n,m);
 printf("Now,they are:/n");
 for(i=0;i<n;i++)
  printf("%d ",number[i]);
}

10.5有n个人围成一圈,顺序编号,从第一个人开始报数,凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
#include <stdio.h>

void main()
{
 int i,k,m,n,num[50],*p;
 printf("Input number of person:n=");
 scanf("%d",&n);
 p=num;
 for(i=0;i<n;i++)//从1到n给每个人编号
  *(p+i)=i+1;
 i=0;//循环计数变量
 k=0;//报数变量
 m=0;//退出的人数
 while(m<n-1)//当退出的人比n-1少(即未退出的人数大于1时)
 {
  if(*(p+i)!=0)
   k++;
  if(3==k)
  {
   *(p+i)=0;
   k=0;
   m++;
  }
  i++;
  if(i==n)
   i=0;
 }
 while(*p==0)
  p++;
 printf("The last one is NO.%d/n",*p);
}

10.7有一字符串,包含n个字符。写一个函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串。
#include <stdio.h>
#include <string.h>

void copystr(char *p1,char *p2,int m)
{
 int n=0;
 while(n<m-1)//定位到第m个字符处
 {
  n++;
  p1++;
 }
 while(*p1!='/0')//拷贝字符到目的串中
 {
  *p2=*p1;
  p1++;
  p2++;
 }
 *p2='/0';
}

void main()
{
 int m;//拷贝起始位置
 char str1[20];//原串
 char str2[20];//目的串
 printf("input string:");
 gets(str1);
 printf("which character that begin to copy?");
 scanf("%d",&m);
 if(strlen(str1)<m)
  printf("input error!");
 else
 {
  copystr(str1,str2,m);
  printf("result: %s/n",str2);
 }
}

10.9写一个函数,将一个3*3的矩阵转置
#include <stdio.h>

move(int *pointer)
{
 int i,j,t;
 for(i=0;i<3;i++)
  for(j=i+1;j<3;j++)
  {
   t=*(pointer+3*i+j);//元素a[i][j]相对于首元素的位置:m*i+j,其中m为列数
   *(pointer+3*i+j)=*(pointer+3*j+i);
   *(pointer+3*j+i)=t;
  }
}

void main()
{
 int a[3][3],*p,i;
 printf("Input matrix:/n");
 for(i=0;i<3;i++)
  scanf("%d %d %d",&a[i][0],&a[i][1],&a[i][2]);
 p=&a[0][0];//二位数组首元素地址
 move(p);
 printf("Now,matrix:/n");
 for(i=0;i<3;i++)
  printf("%d %d %d/n",a[i][0],a[i][1],a[i][2]);
}

10.10将一个5*5的矩阵中最大的元素放在心中,4个角分别放4个最小的元素(按从左到右,从上到下的顺序,依次从小到大存放),写一个函数实现之。
#include <stdio.h>

void change(int *p)
{
 int i,j,temp;
 int *pmax,*pmin;
 pmax=p;
 pmin=p;
 for(i=0;i<5;i++)//找最大最小元素地址并赋给pmax,pmin
 {
  for(j=0;j<5;j++)
  {
   if(*pmax<*(p+5*i+j))
    pmax=p+5*i+j;
   if(*pmin>*(p+5*i+j))
    pmin=p+5*i+j;
  }
 }
 temp=*(p+12);//将最大值换给中心元素
 *(p+12)=*pmax;
 *pmax=temp;
 temp=*p;//将最小值换给左上角元素
 *p=*pmin;
 *pmin=temp;
 pmin=p+1;
 for(i=0;i<5;i++)//找第二最小值的地址赋给pmin
  for(j=0;j<5;j++)
   if(((p+5*i+j)!=p) && (*pmin>*(p+5*i+j)))
    pmin=p+5*i+j;
 temp=*pmin;//将第二最小值换给右上角元素
 *pmin=*(p+4);
 *(p+4)=temp;
 pmin=p+1;
 for(i=0;i<5;i++)//找第三最小值的地址赋给pmin
  for(j=0;j<5;j++)
   if(((p+5*i+j)!=(p+4)) && ((p+5*i+j)!=p) && (*pmin>*(p+5*i+j)))
    pmin=p+5*i+j;
 temp=*pmin;//将第三最小值换给左下角元素
 *pmin=*(p+20);
 *(p+20)=temp;
 pmin=p+1;
 for(i=0;i<5;i++)//找第四最小值的地址赋给pmin
  for(j=0;j<5;j++)
   if(((p+5*i+j)!=p) && ((p+5*i+j)!=(p+4)) && ((p+5*i+j)!=(p+20)) && (*pmin>*(p+5*i+j)))
    pmin=p+5*i+j;
 temp=*pmin;//将第四最小值换给右下角元素
 *pmin=*(p+24);
 *(p+24)=temp;
}

void main()
{
 int a[5][5],*p,i,j;
 printf("Input matrix:/n");
 for(i=0;i<5;i++)
  for(j=0;j<5;j++)
   scanf("%d",&a[i][j]);
 p=&a[0][0];
 change(p);
 printf("Now,matrix:/n");
 for(i=0;i<5;i++)
 {
  for(j=0;j<5;j++)
  {
   printf("%d ",a[i][j]);   
  }
  printf("/n");
 }
}

10.11在主函数中输入10个等长的字符串。用另一个函数对它们排序,然后在主函数输出这10个已排好序的字符串。
#include <stdio.h>
#include <string.h>

void sort(char s[10][6])
{
 int i,j;
 char *p,temp[10];
 p=temp;
 for(i=0;i<9;i++)
  for(j=0;j<9;j++)
   if(strcmp(s[j],s[j+1])>0)
   {
    strcpy(p,s[j]);
    strcpy(s[j],s[j+1]);
    strcpy(s[j+1],p);
   }
}

void main()
{
 int i;
 char str[10][6];
 printf("Input 10 string:/n");
 for(i=0;i<10;i++)
  scanf("%s",str[i]);
 sort(str);
 printf("Now,the sequence:/n");
 for(i=0;i<10;i++)
  printf("%s/n",str[i]);
}

10.12用指针数组处理上一题目,字符串不等长。
#include <stdio.h>
#include <string.h>

void sort(char *p[])
{
 int i,j;
 char *temp;
 for(i=0;i<9;i++)
  for(j=0;j<9-i;j++)
   if(strcmp(*(p+j),*(p+j+1))>0)
   {
    temp=*(p+j);
    *(p+j)=*(p+j+1);
    *(p+j+1)=temp;
   }
}

void main()
{
 int i;
 char *p[10],str[10][20];
 for(i=0;i<10;i++)
  p[i]=str[i];//将第i个字符串的首地址赋予指针数组p的第i个元素
 printf("Input 10 strings:/n");
 for(i=0;i<10;i++)
  scanf("%s",p[i]);
 sort(p);
 printf("Now,the sequnce is:/n");
 for(i=0;i<10;i++)
  printf("%s/n",p[i]);
}

10.14将n个数按输入顺序的逆序排列,用函数实现。
#include <stdio.h>

void sort(char *p,int m)
{
 int i;
 char temp,*p1,*p2;
 for(i=0;i<m/2;i++)
 {
  p1=p+i;
  p2=p+(m-1-i);
  temp=*p1;
  *p1=*p2;
  *p2=temp;
 }
}

void main()
{
 int i,n;
 char *p,num[20];
 printf("input n:");
 scanf("%d",&n);
 printf("please input numbers:/n");
 for(i=0;i<n;i++)
  scanf("%d",&num[i]);
 p=num;
 sort(p,n);
 printf("Now,the sequence is:/n");
 for(i=0;i<n;i++)
  printf("%d ",num[i]);
}

10.15有一个班4个学生,5门课。(1)求第一门课的平均分(2)找出有两门以上课程不及格的学生,输出它们的学号和全部课程成绩及平均成绩(3)找出平均成绩在90分以上或全部课程成绩在85以上的学生。编3个函数实现。
#include <stdio.h>

void main()
{
 void avsco(float *psco,float *pave);
 void avcour1(char *pcou,float *psco);
 void fail2(char *pcou,int *pnum,float *psco,float *pave);
 void good(char *pcou,int *pnum,float *psco,float *pave);

 int i,j,*pnum,num[4];//num是存放4个学生学号的一位数组
 float score[4][5],aver[4],*psco,*pave;//score是存放4个学生5门课成绩的二维数组,aver是存放每个学生平均成绩的数组
 char course[5][10],*pcou;//course是存放5门课名称的二维字符数组
 printf("Input course:/n");
 pcou=course[0];//第0行首地址
 for(i=0;i<5;i++)//输入5门课程名称
  scanf("%s",course[i]);
 printf("NO. and score:/n");
 printf("NO.");
 for(i=0;i<5;i++)//输出5门课程名称
  printf(",%s",course[i]);
 printf("/n");
 psco=&score[0][0];//0行0列元素地址
 pnum=num;//数组首地址
 for(i=0;i<4;i++)//输入4个学生的学号以及5门课程的成绩
 {
  scanf("%d",pnum+i);
  for(j=0;j<5;j++)
   scanf(",%f",psco+5*i+j);
 }
 pave=aver;//数组首地址
 printf("/n/n");
 avsco(psco,pave);//求出每个学生平均成绩
 avcour1(pcou,psco);//求出第一门课的平均成绩
 printf("/n/n");
 fail2(pcou,pnum,psco,pave);//找出2门课不及格的学生
 printf("/n/n");
 good(pcou,pnum,psco,pave);//找出成绩好的学生
}

void avsco(float *psco,float *pave)
{
 int i,j;
 float sum,average;
 for(i=0;i<4;i++)
 {
  sum=0.0;
  for(j=0;j<5;j++)
   sum=sum+(*(psco+5*i+j));//累计每个学生的各科成绩
  average=sum/5;//计算平均成绩
     *(pave+i)=average;
 }
 
}

void avcour1(char *pcou,float *psco)
{
 int i;
 float sum,average1;
 sum=0.0;
 for(i=0;i<4;i++)
  sum=sum+(*(psco+5*i));//累计每个学生的得分
 average1=sum/4;//计算平均成绩
 printf("course 1:%S,average score:%6.2f./n",pcou,average1);
}

void fail2(char *pcou,int *num,float *psco,float *pave)
{
 int i,j,k,label;
 printf("======================student who is fail========================/n");
 printf("NO.");
 for(i=0;i<5;i++)
  printf("%10s",pcou+10*i);
 printf("    average/n");
 for(i=0;i<4;i++)
 {
  label=0;
  for(j=0;j<5;j++)
   if(*(psco+5*i+j)<60.0)
    label++;
  if(label>=2)
  {
   printf("%d",num[i]);
   for(k=0;k<5;k++)
    printf("%10.2f",*(psco+5*i+k));
   printf("%10.2f/n",*(pave+i));
  }
 }
}

void good(char *pcou,int *num,float *psco,float *pave)
{
 int i,j,k,n;
 printf("===================student whose score is good====================/n");
 printf("NO.");
 for(i=0;i<5;i++)
  printf("%10s",pcou+10*i);
 printf("average/n");
 for(i=0;i<4;i++)
 {
  n=0;
  for(j=0;j<5;j++)
   if(*(psco+5*i+j)>85.0)
    n++;
  if((n==5) || (*(pave+i)>=90))
  {
   printf("%d",num[i]);
   for(k=0;k<5;k++)
    printf("%10.2f",*(psco+5*i+k));
   printf("%10.2f/n",*(pave+i));
  }
 }
}
运行情况:
Input course:(输入课程名称)
English
Computer
Math
Physics
Chemistry
Input NO. and scores:(输入学号和各门课成绩)
NO.,English,Computer,Math,Physics,Chemistry,average(按此顺序输入)
101,34,56,88,99,89
102,77,88,99,67,78
103,99,90,87,86,89
104,78,89,99,56,77

10.16输入一个字符串,内有数字和非数字字符,如:a123x456 17960?302tab5876将其中连续的数字作为一个整数,依次存放到一数组a中.例如123放在a[0]...统计共有多少整数,并输出.
#include <stdio.h>

void main()
{
 char str[50],*pstr;
 int i,j,k,m,e10,digit,ndigit,a[10],*pa;
 printf("Input a string:/n");
 gets(str);
 printf("/n");
 pstr=str;//字符指针pstr置于数组str首地址
 pa=a;//指针pa置于a数组首地址
 ndigit=0;//ndigit代表有多少个整数
 i=0;//代表字符串中字符的位置
 j=0;//代表连续数字的位数
 while(*(pstr+i)!='/0')
 {
  if((*(pstr+i)>='0') && (*(pstr+i)<='9'))
   j++;
  else
  {
   if(j>0)
   {
    digit=*(pstr+i-1)-'0';//将个数位赋予digit
    k=1;
    while(k<j)//将含有两位以上数的其他位的数值累计于digit
    {
     e10=1;
     for(m=1;m<=k;m++)
     e10=e10*10;//e10代表该位数所应乘的因子
     digit=digit+(*(pstr+i-1-k)-'0')*e10;//将该位数数值累加于digit
     k++;//位数k自增
    }
    *pa=digit;//将数值赋予数组
    ndigit++;
    pa++;//指针pa指向a数组下一元素
    j=0;
   }
  }
  i++;
 }
 if(j>0)//以数字结尾字符串的最后一个数据
 {
  digit=*(pstr+i-1)-'0';//将个数位赋予digit
  k=1;
  while(k<j)//将含有两位以上数的其他位的数值累加于digit
  {
   e10=1;
   for(m=1;m<=k;m++)
    e10=e10*10;//e10代表该位数所应乘的因子
   digit=digit+(*(pstr+i-1-k)-'0')*e10;//将该位数数值累加于digit
   k++;//位数k自增
  }
  *pa=digit;//将数值赋予数组
  ndigit++;
  j=0;
 }
 printf("There are %d numbers in this line.They are:/n",ndigit);
 j=0;
 pa=a;
 for(j=0;j<ndigit;j++)//输出数据
  printf("%d ",*(pa+j));
 printf("/n");
}

10.19编写一个函数alloc(n),用来在内存区新开辟一个连续的空间(n个字节)。此函数的返回值是一个指针,指向新开辟的连续空间的起始地址。再写一个函数free(p),将地址p开始的各单元释放.
提示:先在内存规定出一片相当大的连续空间(例如1000个字节).然后开辟与释放都在此空间内进行。假设指针变量p原已指向未用空间的开头,调用alloc(n)后,开辟了n个字节可供程序使用。现在
需要使p的值变成p+n,表示空白未用区从p+n地址开始,同时要将新开辟区的起始位置(p)作为函数值返回,以表示可以利用从此点开始的单元。如果更新开辟的区太大,超过了预设的空间(1000字符)
则alloc(n)函数返回指针NULL,表示开辟失败。
alloc(n)应返回一个指向字符数据的指针,因为开辟的空间是以字节为单位被利用的。


#include <stdio.h>

#define NULL 0//当开辟失败时返回标志
#define ALLOCSIZE 1000//可以开辟的最大空间
char allocbuf[ALLOCSIZE];//开辟一个字符数组,作为存储区
char *allocp=allocbuf;//指针指向存储区的始端
char *alloc(int n)//开辟存储区函数,开辟存储区后返回指针
{
 if(allocp+n<=allocbuf+ALLOCSIZE)
 {
  allocp+=n;
  return (allocp-n);//返回一个指针,它指向存储区的开始位置
 }
 else
  return NULL;//当存储区不够分配时,返回一个空指针
}

void free(char *p)//释放存储区函数
{
 if(p>=allocbuf && p<allocbuf+ALLOCSIZE)
  allocp=p;
}

10.19扩展:编写一个函数mynew(n),用来在内存区新开辟一个连续的空间(n个字节)。此函数的返回值是一个指针,指向新开辟的连续空间的起始地址。再写一个函数free(p),将地址p开始的各单元释放
#include <stdio.h>

#define NULL 0//当开辟失败时返回标志
#define NEWSIZE 1000//可以开辟的最大空间
char newbuf[NEWSIZE];//开辟一个字符数组,作为存储区
char *newp=newbuf;//指针指向存储区的始端
char *mynew(int n)//开辟存储区函数,开辟存储区后返回指针
{
 if(newp+n<=newbuf+NEWSIZE)
 {
  newp+=n;
  return (newp-n);//返回一个指针,它指向存储区的开始位置
 }
 else
  return NULL;//当存储区不够分配时,返回一个空指针
}

void free(char *p)//释放存储区函数
{
 if(p>=newbuf && p<newbuf+NEWSIZE)
  newp=p;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值