C Primer+Plus,十四编程练习

1、编写一个程序。请求用户键入日、月和年。月份可以是月份号,月份名或月份缩写。然后程序返回一年中到给定日期的总天数。

(1)只考虑月份的数字输入:

#include<stdio.h>
#include<ctype.h>
void eatline();
int count_days(struct date p);
struct date{
  int day;
  int month;
  char year[4];
};
int main(void)
{
  struct date yourday;
  int days;
  printf("please input yourday's date:\n");
  scanf("%d",&yourday.day);
  printf("please input yourday's month:\n"); 
  scanf("%d",&yourday.month);
  eatline();
  printf("please input yourday's year:\n");
  gets(yourday.year);
  printf("%d-%d-%s,the total days=%d.\n",yourday.day,
         yourday.month,yourday.year,count_days(yourday));
  getch();
  return 0;
}
void eatline(void)
{ while(getchar()!='\n')
    continue;
}
int count_days(struct date p)
{ int base;
  switch(p.month)
  {
    case 1:base=0;break;
    case 2:base=31;break;
    case 3:base=59;break;
    case 4:base=90;break;
    case 5:base=120;break;
    case 6:base=151;break;
    case 7:base=181;break;
    case 8:base=212;break;
    case 9:base=243;break;
    case 10:base=273;break;
    case 11:base=304;break;
    case 12:base=334;break;
   }
   return (base+p.day);
}

2、写一个程序,满足下列要求:

a.外部定义一个name结构模板,它含有2个成员:一个字符串用于存放名,另外一个字符串存放姓。

b.外部定义一个student结构模板,3个成员:一个name结构,一个存放3个浮点数分数的grade数组,以及一个存放这3个分数平均分的变量。

c.使main()函数声明一个具有CSIZE(=4)个student结构的数组,并随意初始化这些结构的名字部分。使用函数来执行d\e\f\g部分的任务。

d.请求用户输入学生姓名和分数,以交互地获取每个学生的成绩。将分数放到相应结构的的grade数组成员中。可以自主选择在main()或一个函数中实现该循环。

e.为每个结构计算平均分,并把这个值赋给适合成员。

f.输出每个结构中的信息。

g.输出结构的每个数值成员的班级平均分。

#include<stdio.h>
#define CSIZE 4
void eatline(void);
void get_score(struct student *);
float get_avr(struct student *);
struct name{
  char firstname[5];
  char lastname[10];
};
struct student{
  struct name sname;
  float grade[3];
  float average;
};
int main(void)
{
  struct student njust981021[CSIZE];
  int i;
  for(i=0;i<CSIZE;i++)
  {
    printf("input NO.%d student's First_name:\n",i+1);
    scanf("%s",njust981021[i].sname.firstname);
    eatline();
    printf("input NO.%d student's last_name:\n",i+1);
    scanf("%s",njust981021[i].sname.lastname);
    eatline();
  }
  for(i=0;i<CSIZE;i++)
  {
    get_score(&njust981021[i]);
  }
  for(i=0;i<CSIZE;i++)
  {
    njust981021[i].average=get_avr(&njust981021[i]);
  }
  for(i=0;i<CSIZE;i++)
  {
    printf("%s_%s's score is:%2f %2f %2f,averag score is:%5f.\n",
           njust981021[i].sname.firstname,njust981021[i].sname.lastname,
            njust981021[i].grade[0],njust981021[i].grade[1],
            njust981021[i].grade[2],njust981021[i].average);
  }
  getch();
  return 0;
    
}
void eatline(void)
{ while(getchar()!='\n')  
     continue;
}
void get_score(struct student *s)
{   
    float a,b,c;
    printf("input %s's score.\n",s->sname.lastname);
    scanf("%f%f%f",&a,&b,&c);
    s->grade[0]=a;
    s->grade[1]=b;
    s->grade[2]=c;
}
float get_avr(struct student *s)
{   
    return (s->grade[0]+s->grade[1]+s->grade[2])/3.0;
}

3、巨人航空公司的机群由座位容量为12的飞机组成。每天飞行一个航班。按照下面的功能,写一个座位预定程序:

a.程序使用一个含12个结构的数组。每个结构要包括一个用于标识座位编号,一个表示座位是否已被分配,座位预定人的姓和名。

b.程序显示下面的菜单:

To choose a function,enter its letter label:

a)Show number of empty seats

b)Show list of empty seats

c)Show alphabetical list of seats

d)Assign a customer to a seat assignment

e)Delete a seat assignment

f)Quit

c.程序应能执行菜单所给出的功能。选择d)和e)需要额外的输入,每一个选项都应当允许用户终止输入。

d.执行完一个特定的功能之后,程序再次显示菜单,除非选项为f.

e.每次运行程序都把数据保存到一个文件中。当程序再次运行时,首先从文件中载入数据。

//花了好多时间才弄出来,不含文件操作,不含字母排序功能
//增加了相关选项
//TC3下调试通过,各函数运行正常
#include<stdio.h>
#include<string.h>

struct planeseat{
//这里按字符串设置座位号应该更合理,可字符串在预订函数中的处理有不少暂时我
//无法解决的问题

   int seatnum;   
   char assign;
   char name[10];
};  //结构定义


//函数声明区域
void select_f(void(* fp)(struct planeseat *),struct planeseat *);
void eatline(void);
char show_menu(void);    //显示主菜单
void show_all(struct planeseat *);  //显示座位信息
void show_emptynum(struct planeseat *); //显示空余座位数量
void show_emptylist(struct planeseat *); //显示空余座位列表
void show_assign(struct planeseat *);  //显示已预订座位列表
void assign_seat(struct planeseat *);    //预定座位
void delete_seat(struct planeseat *);    //取消座位预订

int main(void)
{
  //结构数组定义,初始化
  struct planeseat ps[12]={
  {1,'n',"noname"},{2,'n',"noname"},{3,'n',"noname"},
  {4,'n',"noname"},{5,'n',"noname"},{6,'n',"noname"},
  {7,'n',"noname"},{8,'n',"noname"},{9,'n',"noname"},
  {10,'n',"noname"},{11,'n',"noname"},{12,'n',"noname"}
  };
  int i;
  char a;
  void (*pf)(struct planeseat *p);//定义函数指针
  //提示输入选项
  printf("iput your choice:(a,b,c,d,e,s,f)\n");
  //接收输入,调用对应函数,若f则退出;之后再调用显示菜单函数
  while((a=show_menu())!='f') //注意这里f选项的处理方式
  {
    switch(a)
    {
      case 'a':pf=show_emptynum;break;
      case 'b':pf=show_emptylist;break;
      case 'c':pf=show_assign;break;
      case 'd':pf=assign_seat;break;
      case 'e':pf=delete_seat;break;
      case 's':pf=show_all;break;
    }
    select_f(pf,ps);   //体会加深理解这里函数指针及select_f函数的定义及用法
  }
  printf("Enter for quit.\n");
  getch();
  return 0;
}

//显示主菜单函数定义
char show_menu(void)
{ char ans;
  printf("\nTo choose a function,enter its letter label:\n");
  printf("a)Show number of empty seats\n");
  printf("b)Show list of empty seats\n");
  printf("c)Show list of assigned seats\n");
  printf("d)Assign a customer to a seat assignment\n");
  printf("e)Delete a seat assignment\n");
  printf("s)Show all seats information\n");
  printf("f)Quit\n");
  ans=getchar();
  ans=tolower(ans);
  eatline();
  while(strchr("abcdesf",ans)==NULL)
  {
    puts("Between a.b.c.d.e.s.f:");
    ans=tolower(getchar());
    eatline();
  }
  return ans;
}

//清除缓冲区
void eatline(void)
{ while(getchar()!='\n')
       continue;
}

//显示座位信息表 void show_all(struct planeseat *p) { int i; for(i=0;i<12;i++) { printf("--No.%d--SeatNumber:%d---SeatAssigned: %c---AssignedName: %s.\n", i+1,p->seatnum,p->assign,p->name); p++; } }
//显示空余座位数量函数定义 void show_emptynum(struct planeseat *p) { int i=0,j; for(j=0;j<12;j++) {if (p->assign=='n') { p++;i++; } else p++; } if(i==0) printf("Sorry,it is Full.\n"); else printf("Now here is %d seats empty.\n",i); }
//显示空余座位列表函数定义 void show_emptylist(struct planeseat *p) { int i=0,j; for(j=0;j<12;j++) {if (p->assign=='n') printf("%d.ASSIGNED:%c seat is:%d of %s.\n",i++, p->assign,p->seatnum,p->name); p++; } if(i==0) printf("Sorry,it is Full.\n"); }
//预定座位函数定义 void assign_seat(struct planeseat *p) { int input_num; show_emptylist(p); printf("choose the number of seat.\n"); scanf("%d",&input_num); eatline(); while(input_num!=p->seatnum) p++; printf("input the name of seat.\n"); gets(p->name); p->assign='y'; printf("Assign success!%s's seat number is %d-%c.\n", p->name,p->seatnum,p->assign); }
//显示已预订座位清单函数定义 void show_assign(struct planeseat *p) { int j; for(j=0;j<12;j++) {if (p->assign=='y') printf("%d.assigned seat is:%d,BY %s.\n",j+1,p->seatnum,p->name); p++; } }
//取消座位预订函数定义 void delete_seat(struct planeseat *p) { int assign_num; show_assign(p); printf("input the assigned name.\n"); scanf("%d",&assign_num); eatline(); while(assign_num!=p->seatnum) p++; p->assign='n'; printf("Cancel success!\n Seat of %s is empty.\n",p->seatnum); }
//设置一个参数分别为一个函数指针(指向一个返回值为空、planeseat型结构指针变量作为参数的函数)、一个planeseat型结构指针变量
//函数功能:实质是将第二个参数作为第一个参数(函数)的参数,执行第一个参数指定的函数
void select_f(void(* fp)(struct planeseat *p),struct planeseat *q) { (*fp)(q); }

4、编写一个transfom()函数,接受4个参数:包含double类型的源数组名,double类型的目标数组名,标识数组元素个数的int变量以及一个函数名(或者,等价的指向函数的指针)。transform()函数把指定的函数作用于源数组的每个元素,并将返回值放到目标数组中。例如:

transform(source,target,100,sin);这个函数调用把sin(source[0])赋值给target[0],依次,共100个元素。在一个程序中测试该函数,调用4次transform(),分别用math.h库中的两个函数以及自己设计两个适合的函数。

#include<stdio.h>
#include<math.h>
#define arrlen 10
void transform(double a[],double b[],int n,double(*)(double));
double own_f(double);
void transform(double a[],double b[],int n,double(*pf)(double))
{
  int i;
  for(i=0;i<n;i++)
  { 
    b[i]=(*pf)(a[i]);
  }
  printf("Transfer finished!\n");
}

void show_array(double a[],int arraylen,int linenum)
{
  int i;
  printf("\n");
  for(i=1;i<=arraylen;i++)
  {
    printf("-----%f-----",a[i-1]);
    if(i%linenum==0) printf("\n");
  }
}
double own_f(double x)
{
   return x*x;
}
int main(void)
{
  double a[10]={1.2,2.3,3.41,4.09,5.60,6.18,7.63,8.123,9.36,10.00};
  double b[10];
  char choice;
  double(*pf[2])(double a)={sqrt,own_f};
  int i;
  for(i=0;i<2;i++)
  {
    transform(a,b,10,pf[i]);
    show_array(a,10,3);
    show_array(b,10,3);
    printf("Any key for next function.\n");
    getch();
  }
  return 0;
}