"Output the calendar of any year after 1900" complete programming ideas!

 A top-down, step-by-step design approach is adopted. This kind of idea of ​​decomposing problems is very important and can help us better analyze difficult problems. Especially for engineering projects, more functions and coupling will make the problem impossible to start. Thinking can solve this kind of problem very well!

 

Question: According to the year input by the user, display the calendar of 12 months of the year and correspond to the specific day of the week.

Analysis: First, according to the idea of ​​problem handling, it can be divided into three processes: UserInput, Process, and Print. UserInput is mainly used to receive the year entered by the user and pass the input to Process. Process receives the year input by the user, and calculates the day of the week corresponding to each day of each month in the input year according to the reference time (January 1, 1990 is Monday). There are several problems here. First, you need to calculate the calendar of each month of the current year, and then loop 12 times. The monthly calendar of each month needs to calculate the number of days between the month before this month and 1990, and then Add the number of days in the month. Due to the particularity of the number of days in February, a leap year judgment is also required. The second question is how to calculate the monthly calendar for one month. The first day of the month can be obtained by taking the remainder of 7 to get the corresponding day of the week, and then calculate it in turn, taking the number of days in the month as the number of cycles. It is worth noting that every Saturday, a line break is required.

 

Program design process:

1. Top down

Let's start with the main program and consider what is the program going to do? In general, users only need to enter the year and press Enter to display the calendar for that year. Before the user enters, it is best to give the user some prompting statements as Instruction.

Therefore, the void GiveInstruction(void) function will be obtained, and the function statement is as follows:

voidGiveInstruction(void)         //tell theuser how to do

{

printf("This program displays a calendarfor a full\n");

printf("year. The year must not be before1900.\n");

}

This way will make the program feel more friendly to the user. The following is a step-by-step refinement. The principle of step-by-step refinement is: once you have a general description of a program, you should end here, write it down, and call other functions or procedures to express those who still need to Continue to refine the procedure.

 

It should be noted here that "procedure" refers to a function that does not return a value but does something, we call it a procedure.

Since the general way of writing a function is:

The type of the return value or the name of a function without a return value (parameter type 1 parameter name 1, parameter type 2 parameter name 2...)

Therefore, the writing method of the procedure function can be determined according to the general writing method of the function. Since the procedure function has no return value, it is void. The procedure function is written as follows:

void function name (parameter type 1 parameter name 1, parameter type 2 parameter name 2...)

 

We continue to go back to the top-down design. According to the description just now, the main program can be written as:

main()

{

         intYear;

         GiveInstruction();

         Year=GetYearFromUser();

         PrintCalendar(Year);

}

The three sub-functions contained in the main function are easy to understand. The core function is PrintCalendar(Year), which should be able to output the calendar according to the year input by the user. The following uses step-by-step refinement to decompose the PrintCalendar(Year) function.

2. Step by step refinement of PrintCalendar(Year)

Although the above three functions all need to be written, we go directly to the core of the problem and arrange or arrange the functions of other auxiliary functions according to the core function. From the call of main, the prototype of PrintCalendar(Year) is

void PrintCalendar(int Year);

We think about this function at an abstraction level, thinking about what it needs to do. It needs to print the calendar of 12 months, well, here, the next step has the idea, which can be achieved by using the for loop and the calendar function of each month. code show as below:

voidPrintCalendar(int year)

{

int month;

for(month=1;month<=12;month++)

{

           PrintCalendarMonth(month,year);//print the every month is the essence of program

           printf("\n");

}

}

The following problem is transformed into PrintCalendarMonth(month, year), we notice that this function has two inputs month, year. year comes from user input, while month represents the 12 months of the year. At this time, the problem of leap years obviously arises. When considering the number of days in February, leap years must be considered. We are already very familiar with the leap year function, as follows:

int IsLeapYear(int year) //judge the inputnumber is leapyear or not

{

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

}

After considering the issue of leap years, it is necessary to look back and pay attention to the output format of the calendar.

Since we need this output every month, as long as one can be achieved, the following is only a matter of "quantity". The first two lines of this calendar are also quite easy, the more troublesome thing is that the numbers match the weekday above. There are three problems here, the first one, the space before the 1st of each month should be just right; the second one, the line should be wrapped on the Saturday of every month; the third one, there is a gap between each number.

Solve the first problem first. Since the weekday corresponding to the 1st of each month may be different, the number of spaces in front is also different. Therefore, we need to know the weekday corresponding to the 1st of each month. Assuming we know the weekday corresponding to the 1st of each month, the space function can be written. as follows:

voidIndentFirstLine(int weekday) //The spacebar of the first row of every month

{

         int i;

         for(i=0;i<weekday;i++)

         {

                   printf("   ");

         }

}

Next, you need to know which weekday corresponds to the 1st of each month, that is, the intFirstDayOfMonth(month,year) function. A specific reference is needed here. For example, if we know that a certain day of a certain year in history corresponds to the day of the week, we can calculate which weekday is the first day of a certain month in the year entered by the user based on the number of days and months. For example, January 1, 1900 is a Monday. From this day on, add 365 or 366 days each year, depending on whether it is a leap year. For the month preceding the month to be processed in the current year, add the number of days in the month. Calculate with modulo operation. For example, if we want to calculate February 2018, we can first calculate the day of the week until the first day of January 2018 by year, only need (weekday+365/366)%7, and then calculate it by month to February, Just need (weekday+month(I,year))%7. Since January 1, 1900 is a Monday, the initial value of weekday is Monday. The code of the intFirstDayOfMonth(month, year) function is as follows:

intFirstDayOfMonth(month,year) //know first day of every month is which one ofweekday

{

         int weekday,i;

         weekday=Monday;

         for(i=1900;i<year;i++) //firstaccording to the year

         {

                   weekday=(weekday+365)%7; // %can get the weekday

                   if(IsLeapYear(i))  weekday=(weekday+1)%7;

         }

         for(i=1;i<month;i++) //secondaccording to the month

         {

                   weekday=(weekday+MonthDays(i,year))%7;

         }

         return weekday;

}

Here is a trick. Since we use the modulo operation, we can set the number represented by weekday, which is very convenient when performing the modulo operation. as follows:

#defineSunday 0      //easy to qiumo(%)

#defineMonday 1

#defineTuesday 2

#defineWednesday 3

#defineThursday 4

#defineFriday 5

#defineSaturday 6

Since the intFirstDayOfMonth(month,year) function uses the function MonthDays(i,year) that counts the number of days in each month, this is very simple, so we also write this function below by the way:

intMonthDays(int month,int year)

{

         switch(month)

         {

                   case 2:

                            if(IsLeapYear(year))

                                     return 29;

                       return 28;

                   case 4: case 6: case 9: case11:

                            return 30;

                   default:

                            return 31;

         }

}

In this case, the first problem - the space in front of the 1st of each month should be just right, which can be solved by calling back the weekday of the 1st of each month.

Next, we will solve the problem of line breaks and spacing. The problem of line wrapping is not difficult. Using the number of days in each month as the for condition, add 1 to the weekday on the 1st of each month (the advantage of define is that the number in the range of 0~6 after the modulo and the weekday represented can be converted at any time ) and then modulo 7. When weekday==Saturday, wrap the line. Here Saturday can also be changed to 6, the benefits of define are fully demonstrated here! Since there is a line break between the calendars of each month, the logic of line break must be clarified. Obviously, when the last day of the month is not reached, a new line is required every Saturday. After the line is changed, add 1 to weekday to become Sunday; Sunday on the 1st will naturally wrap; when the last day of the month is not Saturday, the line cannot be wrapped because it is still in the calendar of this month, but since the calendars of the next month cannot be pasted together, it should be placed in the calendar of this month. A newline operation is performed outside. This part requires careful debugging.

voidPrintCalendarMonth(int month,int year)

{

         int weekday,nDays,day;

         printf("   %s %d\n",MonthName(month),year); //thehead of the monthly calendar

         printf(" Su Mo Tu We Th FrSa\n");

         nDays=MonthDays(month,year); //get thedays of month,which will call IsLeapYear function

         weekday=FirstDayOfMonth(month,year);//know first day of every month is which one of weekday

         IndentFirstLine(weekday); //print thespacebar before the first day

         for(day=1;day<=nDays;day++)

         {

                   printf(" %2d",day);//printf the day

                   if(weekday==Saturday)printf("\n");

                   // saturday can be placedwith 6,this will fully display the advantages of "define"

                   //if saturday,line feed;ifnot,the final weekday will line feed

                   weekday=(weekday+1)%7;//calculate next day

         }

         if (weekday!=Sunday)printf("\n");

         //if not sunday,line feed;if sunday,theformer weekday is saturday,has already line feed

}

The MonthName(month) function needs to pay attention here. Since the function returns a string, the C language does not have a string function (int month) that returns a string. It seems that C++ has it. The usual way to deal with this problem is to use function parameters to pass pointers or apply for Heap space, free after use. Here, the pointer method is used.

char*MonthName(int month) //transmit the string of months

{

         switch(month)

         {

                   case 1:return("January");

                   case 2:return("February");

                   case 3:return("March");

                   case 4:return("April");

                   case 5:return("May");

                   case 6:return("June");

                   case 7:return("July");

                   case 8:return("August");

                   case 9:return("September");

                   case 10:return("October");

                   case 11:return("November");

                   case 12:return("December");

                   default:return ("Illegalmonth");

         }

}

3. Assembly

Now that the body of the function is available, let's introduce writing comments, modifications, and tests. The complete code is as follows:

Output calendars after 1900

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325815823&siteId=291194637