• 沒有找到結果。

【例 6.25】编写一个程序完成“菜单”功能,提供三种选择途径:其一是求水仙花数(所 谓水仙花数是指三位整数的每一位上数字的立方和等于该整数本身。 例如 153 就是一个水仙花 数:153=1 +5 +3 )。找出 100~999 之间的水仙花数。

其二是查找素数,找出 2~n 之间的素数。

其三是求 Faibonacci 数列前 n 项的值。

#include<stdio.h> 

#include<math.h> 

#include<stdlib.h> 

void main()  {  int m,xz; 

void narcissus();  /*声明求水仙花数的函数*/ 

void prime();  /*声明查找素数的函数*/ 

void faibonacci();  /*声明求 Faibonacci 数列前 n 项的函数*/ 

system("cls"); 

m=0; 

while(m==0) 

{  printf("\n"); 

printf("1 求水仙花数\n"); 

printf("2 查找素数\n"); 

printf("3 求 Faibonacci 数列前 n 项\n"); 

printf("输入了非法的数据,退出!\n"); 

printf("\n"); 

printf("请输入 1~3 中的一个数字:"); 

scanf("%d",&xz);

switch(xz)  /*用开关语句 switch 进行选择*/ 

{ case 1:narcissus();break;  /*若选择 1,求水仙花数*/ 

case 2:prime();break;  /*若选择 2,求素数*/ 

case 3:faibonacci();break;  /*若选择 3, 求 Faibonacci 数列前 n 项的值*/ 

default:m=1;  /*若选择其他讲 m 置 1,循环结束*/ 

void narcissus()  /*此函数用于求水仙花数*/ 

{  int k,a,b,c,d; 

for(k=100;k<1000;k++)  { a=k/100; 

b=k/100/10; 

c=k%10; 

d=a*a*a+b*b*b+c*c*c; 

if(d==k) 

printf("%d\n",k); 

void prime()  /*此函数用于查找素数*/ 

int i,j,k,n,m=0; 

printf("请输入一个数:"); 

scanf("%d",&n); 

for(i=2;i<=n;i++)  j=sqrt(i); 

for(k=2;k<=j;k++)  if(i%k==0) 

break; 

if(k>j)  {  m++; 

printf("%3d",i); 

if(m%10==0)  printf("\n"); 

void faibonacci()  /*此函数用于求 Faibonacci 数列前 n 项的值*/ 

long int f,f1=1,f2=1; 

int i,n; 

printf("请输入 n: "); 

scanf("%d",&n); 

printf("%8ld%8ld",f1,f2); 

for(i=3;i<=n;i++) 

f=f1+f2; 

f1=f2;  /*存放第一个数*/ 

f2=f;  /*存放第二个数*/ 

printf ("%8ld",f); 

if(i%6==0)  /*为打印整齐,一行打印 6 个数,满 6 个数换行*/ 

printf("\n"); 

}

程序共有  4  个函数,其中主函数提供了主菜单,允许选择三种情况之一,否则就退出。

方法是:先输入选择,然后通过开关语句 switch 进行选择。为了不断地提供菜单,用 while 来 循环。一开始给变量 m 赋初值为 0,m=0 就继续循环,一旦选择了不存在的情况,则将 m 置 为 1,循环就结束,这是一种较为巧妙的程序设计技巧。

【例 6.26】 编写程序,解决万年历问题。

这里,编制的程序只要求解决公历问题,不需要考虑农历。整个程序的功能概括如下:

(1)输入一个年份,输出全年的日历。

(2)输入年份、月份,输出该月的日历。

(3)输入年月日,计算出这天是星期几。

这里将这个功能定义为一个功能模块,在主程序中分别调用,实现不同的功能。

在这个问题中,最主要是闰年的判断和如何确定每年的第一天是星期几。

某一年是闰年的条件为:该年份能被 4 整除但不能被 100 整除,或者能被 400 整除。根 据这个条件,可以写出判断闰年的函数如下:

int isleap(int year) 

{return (year%4==0&&year%100!=0||year%400==0);}

对于该函数,给它一个年份,如果返回值是  1  则说明是闰年,如果返回值是  0 则为非闰 年。判断是否为闰年主要是为了确定 2 月份的天数,其他月份的天数是固定的。

确定一年的第一天是星期几的函数如下:

int day(int year) 

long a,b; 

if(year<=2000)  /*年份在 2000 年之前*/ 

a=2000­year; 

b=6­(a+a/4­a/100+a/400)%7; 

return b; 

else  /*年份在 2000 年之后*/ 

a=year­2000; 

b=(a+(a­1)/4­(a­1)/100+(a­1)/400)%7; 

return b; 

}

在该函数中,对于年份首先判断是在  2000 年之前还是在  2000  之后,然后分别计算,最 后返回该年份的第一天是星期几,这里,返回值 0~6 分别对应是星期天到星期六。

知道了每个月的天数和该年份的第一天是星期几,利用累加就能计算出每一天对应星期 几,也就容易实现万年历系统的功能。

源程序如下:

(1)首先建立头文件 wnl.h,如下所示:

#include"stdio.h" 

#define   D  "Sum  Mon  Tue  Wed  Thu  Fri  Sat" 

void print(int n)  /*显示 n 个空格*/ 

int  i; 

for(i=0;i<n;i++)  printf("  "); 

}

int day (int year)  /*确定年份 year 的第一天是星期几*/ 

long  a,b; 

if(year<=2000)  /*年份在 2000 年之前*/ 

a=2000­year; 

b=6­(a+a/4­a/100+a/400)%7; 

return b; 

else  /*年份在 2000 年之后*/ 

a=year­2000; 

b=(a+(a­1)/4­(a­1)/100+(a­1)/400)%7; 

return b; 

int isleap(int year)  /*判断闰年*/ 

return(year%4==0&&year%100!=0||year%400==0); 

}

在文件头中,包含了闰年的判断,确定一年的第一天是星期几,显示  n  个空格等函数,

以及几个宏定义和必需的头文件 stdio.h。

(2)显示一年的日历,定义文件 year.c 如下:

void oneyear() 

int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};   /*每个月的天数*/ 

int i,j,k,m,n,f1,f2,year,d; 

clrscr(); 

printf("请输入年份:\n") ;  scanf("%d",&year); 

printf("你所输入的年份是:%d\n",year); 

d=day(year);    /*确定该年的第一天是星期几,用变量 d 表示*/ 

if(isleap(year)) 

a[2]++;      /*如果是闰年则 2 月份的天数加 1*/ 

for(i=1;i<=12;i+=2) 

m=n=f1=f2=0; 

switch(i)       /*显示月份*/ 

case  1 :printf("January  1");break; 

case  3 :printf("March   3");break; 

case  5 :printf("May   5");break; 

case  7 :printf("July  7");break; 

case  9 :printf("September  9");break; 

case  11:printf("November  11");break; 

print(21); 

switch(i+1)  /*显示月份*/ 

case  2 :printf("February  2");break; 

case  4 :printf("April  4");break; 

case  6 :printf("June  6");break;

case  8 :printf("August  8");break; 

case  10:printf("October  10");break; 

case  12:printf("December  12");break; 

printf("\n"); 

printf(D);print(6);printf(D);printf("\n");     /*显示日历的表头*/ 

for(j=0;j<6;j++)  /*显示每一天的日期*/ 

if(j==0)  /*第一行*/ 

print(d*4) ;  for(k=0;k<7­d;k++)  printf("%4d",++m); 

print(6); 

d=d+a[i]%7; 

d%=7;  /*确定下个月的第一天是星期几*/ 

print(d*4); 

for(k=0;k<7­d;k++)  printf("%4d",++n); 

printf("\n"); 

else      /*其他行*/ 

{for(k=0;k<7;k++)  {if (m<a[i]) 

printf("%4d",++m); 

print(4); 

if(m==a[i]) 

f1=1;    /*该月显示完毕*/ 

print(6); 

for(k=0;k<7;k++)  {if(n<a[i+1]) 

printf("%4d",++n); 

else 

print(4); 

if(n==a[i+1]) 

f2=1;  /*该月显示完毕*/ 

printf("\n"); 

if(f1&&f2) 

break;  /*两个月显示完毕*/ 

d=d+a[i+1]%7;d%=7;  /*确定下个月的第一天是星期几*/ 

printf (""); 

for(k=0;k<27;k++) 

printf("=");  /*显示分隔符*/ 

print(7); 

for(k=0;k<27;k++) 

printf("=");  /*显示分隔符*/ 

printf("\n");

if(i==5)  {getch(); 

clrscr();} 

getch(); 

}

该函数将每年的日历分两屏显示,每屏显示 6 个月,在这个函数中,变量 m,n 分别为同 一行上两个月的日期,利用累加实现。变量 d 用来记录每个月第一天是星期几,通过它确定每 个月显示的位置。

(3)显示每个月的日历,定义文件 month.c 如下:

void onemonth() 

int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};  /*每个月的天数*/ 

int i,j,k,m,flag,year,month,d; 

clrscr();  /*清屏*/ 

printf("请你输入年份和月份"); 

scanf("%d%d",&year,&month);  /*输入年份和月份*/ 

printf("\nThe calendar of %d\n",year);  /*输出表头*/ 

switch(month) 

{  case  1 :printf("January  1");break; 

case  2 :printf("February  2");break; 

case  3 :printf("March   3");break; 

case  4 :printf("April  4");break; 

case  5 :printf("May   5");break; 

case  6 :printf("June  6");break; 

case  7 :printf("July  7");break; 

case  8 :printf("August  8");break; 

case  9 :printf("September  9");break; 

case  10:printf("October  10");break; 

case  11:printf("November  11");break; 

case  12:printf("December  12");break; 

printf(D); 

printf("\n\n"); 

d=day(year);  /*确定该年的第一天是星期几*/ 

if(isleap(year)) 

a[2]++;  /*如果是闰年,则 2 月的天数加 1*/ 

for(i=1;i<month;i++)  /*确定该月第一天是星期几*/ 

{d+=a[i]%7;d%=7;} 

m=flag=0; 

for(i=0;i<6;i++)  /*显示该月的日历*/ 

if(i==0)  /*显示第一行*/ 

print(4*d); 

for(j=0;j<7­d;j++)  printf("%4d",++m); 

printf("\n"); 

else 

for(j=0;j<7;j++)

if(m<a[month])  printf("%4d",++m); 

else  flag=1; 

printf("\n"); 

if(flag)  break; 

printf(" "); 

for(k=0;k<27;k++)      /*分隔符*/ 

printf("="); 

printf("\n"); 

getch(); 

}

(4)输入年月日,计算出这天是星期几,定义文件 day.c 如下:

void oneday() 

int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};  /*每个月的天数*/ 

int i,year,month,dday,d; 

clrscr();  /*清屏*/ 

printf("请你输入年月日"); 

scanf("%d%d%d",&year,&month,&dday);   /*输入年月日*/ 

printf("你输入的是年月日是%d 年%d 月%d 日", year,month,dday); 

d=day(year);  /*确定该年的第一天的星期天数目*/ 

if(isleap(year)) 

a[2]++;  /*如果是闰年,则 2 月份的天数加 1*/ 

for(i=1;i<month;i++)  /*确定该月第一天的星期数*/ 

{d+=a[i]%7;d%=7;} 

d+=(dday­1)%7;d%=7;  /*确定该天的星期数*/ 

switch(d) 

case  0: printf("Sunday.\n");break; 

case  1: printf("Monday.\n");break; 

case  2: printf("Tuesday.\n");break; 

case  3: printf("Wednesday.\n");break; 

case  4: printf("Thursday.\n");break; 

case  5: printf("Friday.\n");break; 

case  6: printf("Saturday.\n");break; 

getch(); 

}

该函数中首先要确定该年份第一天的星期数,而后计算对应月份第一天的星期数,再计 算出该天的星期数,最后输出结果。

(5)主程序。定义文件 wnl.c 如下:

#include"year.c" 

#include"month.c" 

#include"day.c" 

void  main() 

int choice,flag; 

while(1)

flag=0;  /*标志变量赋初值*/ 

clrscr();  /*清屏,以下是显示功能菜单*/ 

printf("************************\n"); 

printf("*Please select  the  function(0­­3):*\n"); 

printf("*1 Dispiay the calendar of one year.*\n"); 

printf("*2 Dispiay the calendar of one month.*\n"); 

printf("*3 Display the weekday of one day.*\n"); 

printf("*0.Exit*\n”); 

printf("* ***********************\n"); 

scanf("%d",&choice); 

switch(choice) 

case  0: 

clrscr (); 

printf ("Thank you  for use this software.\n");  /*显示信息*/ 

printf("Welcome to use it again\n"); 

flag=1;break; 

case  1:oneyear();break;  /*显示全年*/ 

case  2:onemonth();break;  /*显示某个月*/ 

case  3:oneday();break;  /*确定某一天的星期数*/ 

default:printf("Your choice wrong,please input again."); 

getch(); 

/*结束 switch   */ 

if(flag)  break; 

/*结束 while*/ 

/*结束 main */

程序说明:

(1)该程序包含所有子函数的源文件,根据用户选择的功能调用相应的自定义子函数。

(2)在主程序中,菜单循环显示,用户可以一直使用,直到选择功能键“0” ,退出程序。

相關文件