程序来自配套的习题解答一书。
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;
}