Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * A solution to exercise 5-9 in K&R2, page 114:
- *
- * Rewrite the routines day_of_year and month_day with pointers
- * instead of indexing.
- *
- */
- Method №1
- #include <stdio.h>
- static char daytab[2][13] = {
- {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
- {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
- };
- /* original versions, for comparison purposes */
- int day_of_year(int year, int month, int day)
- {
- int i, leap;
- leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
- for (i = 1; i < month; i++)
- day += daytab[leap][i];
- return day;
- }
- void month_day(int year, int yearday, int *pmonth, int *pday)
- {
- int i, leap;
- leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
- for (i = 1; yearday > daytab[leap][i]; i++)
- yearday -= daytab[leap][i];
- *pmonth = i;
- *pday = yearday;
- }
- /* pointer versions */
- int day_of_year_pointer(int year, int month, int day)
- {
- int i, leap;
- char *p;
- leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
- /* Set `p' to point at first month in the correct row. */
- p = &daytab[leap][1];
- /* Move `p' along the row, to each successive month. */
- for (i = 1; i < month; i++) {
- day += *p;
- ++p;
- }
- return day;
- }
- void month_day_pointer(int year, int yearday, int *pmonth, int *pday)
- {
- int i, leap;
- char *p;
- leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
- p = &daytab[leap][1];
- for (i = 1; yearday > *p; i++) {
- yearday -= *p;
- ++p;
- }
- *pmonth = i;
- *pday = yearday;
- }
- int main(void)
- {
- int year, month, day, yearday;
- year = 2000;
- month = 3;
- day = 1;
- printf("The date is: %d-%02d-%02d\n", year, month, day);
- printf("day_of_year: %d\n", day_of_year(year, month, day));
- printf("day_of_year_pointer: %d\n",
- day_of_year_pointer(year, month, day));
- yearday = 61; /* 2000-03-01 */
- month_day(year, yearday, &month, &day);
- printf("Yearday is %d\n", yearday);
- printf("month_day: %d %d\n", month, day);
- month_day_pointer(year, yearday, &month, &day);
- printf("month_day_pointer: %d %d\n", month, day);
- return 0;
- }
- Method №2
- /* Given the problem, I thought that this would be a better
- * description of daytab.
- */
- static int *daytab = {
- 0,
- 31,
- 31+28,
- 31+28+31,
- 31+28+31+30,
- 31+28+31+30+31,
- 31+28+31+30+31+30,
- 31+28+31+30+31+30+31,
- 31+28+31+30+31+30+31+31,
- 31+28+31+30+31+30+31+31+30,
- 31+28+31+30+31+30+31+31+30+31,
- 31+28+31+30+31+30+31+31+30+31+30,
- 0,
- 31,
- 31+29,
- 31+29+31,
- 31+29+31+30,
- 31+29+31+30+31,
- 31+29+31+30+31+30,
- 31+29+31+30+31+30+31,
- 31+29+31+30+31+30+31+31,
- 31+29+31+30+31+30+31+31+30,
- 31+29+31+30+31+30+31+31+30+31,
- 31+29+31+30+31+30+31+31+30+31+30,
- };
- /* is it a leap year? (assume it's my calendar, the Gregorian) */
- int leap(int year)
- {
- return ((year % 4) == 0)
- && (((year % 100) != 0)
- || (year % 400) == 0)));
- }
- /* day_of_year: set day of year from month & day */
- int day_of_year(int year, int month, int day)
- {
- return *(daytab + ((month - 1) + (leap(year) * 12))) + day;
- }
- /* month_day: set month, day from day of year */
- void month_day(int year, int yearday, int *pmonth, int *pday)
- {
- int m, ly;
- ly = leap(year);
- if (yearday < 1 || yearday > (365 + ly))
- return; /* no real error checking */
- m = leap(year) ? 23 : 11;
- while (*(daytab + m) > yearday)
- m--;
- if (pmonth)
- *pmonth = (m % 12) + 1;
- if (pday)
- *pday = yearday - (*(daytab + m));
- }
Advertisement
Add Comment
Please, Sign In to add comment