写在开始

这一次写的是实验四.

实验四 循环与数组程序综合应用

一、实验目的:
掌握循环与数组程序设计的一般方法及循环与数组程序的调试方法,能够综合运用顺序、选择、循环和数组解决一般难度的实际应用问题。
二、实验要求

1. 仔细阅读下列实验内容,并编写出相应的C语言源程序。

2. 在C语言运行环境下,编辑录入源程序。

3. 调试运行源程序, 注意观察调试运行过程中发现的错误及改正方法。

4. 掌握如何根据出错信息查找语法错误。

  1. 最后提交带有充分注释的源程序文件(扩展名为.c)。要求该文件必须能够正确地编译及运行,并不得与他人作品雷同。

三、实验内容

编程序实现如下功能:输入任意一个年份,求出从公元1年1月1日到这一年每个月的1日总共有多少天,并求出这一年每个月的1日是星期几,再按以下格式输出该年份全年的公历日历。
 
要求用循环控制打印。

提示:可以将每个月的总天数存入到一个数组中,但是不需要将一个月的每一天存入到数组中。

打印样例如下:

9月

   ----------------------------

日    一    二    三    四    五    六
                        1
2    3    4    5    6    7    8
9    10    11    12    13    14    15
16    17    18    19    20    21    22
23    24    25    26    27    28    29
30

   ---------------------------    

四、常见问题

疑问1:如何控制某个月1日的打印位置?
 
答:先由程序计算出来该月份的1日是星期几,然后控制在打印“1”之前打印相应个数的空格。

疑问2:如何控制每周和每月的打印换行?

答:可以根据当前这一天的打印位置控制每周的打印换行,并根据该月份的天数控制每月的打印换行。

题目分析

这个题目可以把上一道题的那几个主要的函数放过来,然后就是再添加一个复杂一点的打印函数就可以解决问题了,因为这个题要求用循环打印日历表,所以我只能用循环打印了,这是整个代码里面唯一有循环的地方.

我的代码

同样的,为了适配VS2017,我写成了C++的版本.

//本程序需要在编译时打开尾递归优化,不开尾递归优化有可能堆栈溢出,不过最大层数应该不超过30000
// gcc 的优化选项 ~-O1 -foptimize-sibling-calls~  或 ~-O2~
#include"stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
char* Weekdays[] = { "日","一","二","三","四","五","六" };

int getYearDays(int year) {//int -> int
                           //这一个函数写的是获取本年的天数
    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
        return 366;
    }
    else {
        return 365;
    }
}
int getMonthDays(int year, int month) {//(int,int) -> int
                                       //获得本月的天数
    int months[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    if (getYearDays(year) == 366) {
        months[1] = 29;
    }
    return months[month - 1];
}
int getToLastYearsDays(int sum, int year) {//(int,int) -> int
                                           //get from AD 1 to this year's before year's last day.
    if (year <= 1) {
        return sum + getYearDays(year);
    }
    else {
        return getToLastYearsDays(sum + getYearDays(year), year - 1);
    }
}
int getToLastMonthsDays(int sum, int year, int months) {// (int,int,int) -> int
                                                        //Only get this year's before this month's days sum.
    if (months == 0) return sum;
    return getToLastMonthsDays(sum + getMonthDays(year, months), year, months - 1);
}

int getWeekday(int day) {//int -> int
    return day % 7;
}

void printALLYearMonth(int year) {
    int sum = 0, idi, day, idj, ido, today, thisMonthDay;
    sum = getToLastYearsDays(sum, year - 1) + 1;
    for (idi = 0; idi < 12; idi++) {
        day = getWeekday(sum);
        printf("\t\t\t%d月\n", idi + 1);
        printf("--------------------------------------------------\n");
        for (ido = 0; ido < 7; ido++) {
            printf("%s\t", Weekdays[ido]);
        }
        printf("\n\t");
        today = 0;
        thisMonthDay = getMonthDays(year, idi + 1);
        for (idj = 0; idj < 42; idj++) {
            if (idj<day) {
                printf("  \t");
                continue;
            }
            if ((idj + 1) % 7 == 0) {
                printf("\n");
            }
            printf("%d\t", ++today);
            if (today == thisMonthDay) {
                printf("\n--------------------------------------------------\n");
                printf("\n\n");
                break;
            }
        }
        if (idi == 0) {
            sum += thisMonthDay - 1;
        }
        else {
            sum += thisMonthDay;
        }
    }

}

int main(int argc, char const *argv[]) {
    int year;
    int month;
    int day;
    int sum = 0;
    //printf("%d\n",getYearDays(100));
    printf("请输入年份:\n");
    scanf("%d", &year);
    printALLYearMonth(year);
    //printf("到前一年年末的天数=%d\n",sum=getToLastYearsDays(sum,year-1));
    //printf("到前一个月月末的天数=%d\n",sum=getToLastMonthsDays(sum,year,month-1));
    //printf("到这一天的天数=%d\n",sum+=day);
    //printf("这一天是%s\n",Weekdays[getWeekday(sum)]);
    system("pause");
    return 0;
}

写在最后

这段代码整体来说还是有问题的,问题主要出在计算星期几上面,好像是我的这个代码总是计算星期几的时候总是计算晚了一天,然后有时候一个月的第一天会出现在第二行,我记得之前解决了来着,但是我不知道怎么回事这个代码又出故障了,哎.

Last modification:January 27, 2020
如果觉得我的文章对你有用,请随意赞赏