sepo

Answer to Exercise 5-9, page 114 [1] & [2]

Apr 16th, 2012
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.54 KB | None | 0 0
  1. /*
  2.  * A solution to exercise 5-9 in K&R2, page 114:
  3.  *
  4.  *  Rewrite the routines day_of_year and month_day with pointers
  5.  *  instead of indexing.
  6.  *
  7.  */
  8.  
  9. Method №1
  10.  
  11. #include <stdio.h>
  12.  
  13. static char daytab[2][13] =  {
  14.     {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  15.     {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  16. };
  17.  
  18. /* original versions, for comparison purposes */
  19.  
  20. int day_of_year(int year, int month, int day)
  21. {
  22.     int i, leap;
  23.    
  24.     leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
  25.     for (i = 1; i < month; i++)
  26.         day += daytab[leap][i];
  27.     return day;
  28. }
  29.  
  30. void month_day(int year, int yearday, int *pmonth, int *pday)
  31. {
  32.     int i, leap;
  33.    
  34.     leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
  35.     for (i = 1; yearday > daytab[leap][i]; i++)
  36.         yearday -= daytab[leap][i];
  37.     *pmonth = i;
  38.     *pday = yearday;
  39. }
  40.  
  41.  
  42. /* pointer versions */
  43.  
  44. int day_of_year_pointer(int year, int month, int day)
  45. {
  46.     int i, leap;
  47.     char *p;
  48.    
  49.     leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
  50.  
  51.     /* Set `p' to point at first month in the correct row. */
  52.     p = &daytab[leap][1];
  53.  
  54.     /* Move `p' along the row, to each successive month. */
  55.     for (i = 1; i < month; i++) {
  56.         day += *p;
  57.         ++p;
  58.     }
  59.     return day;
  60. }
  61.  
  62. void month_day_pointer(int year, int yearday, int *pmonth, int *pday)
  63. {
  64.     int i, leap;
  65.     char *p;
  66.    
  67.     leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
  68.     p = &daytab[leap][1];
  69.     for (i = 1; yearday > *p; i++) {
  70.         yearday -= *p;
  71.         ++p;
  72.     }
  73.     *pmonth = i;
  74.     *pday = yearday;
  75. }
  76.  
  77.  
  78. int main(void)
  79. {
  80.     int year, month, day, yearday;
  81.    
  82.     year = 2000;
  83.     month = 3;
  84.     day = 1;
  85.     printf("The date is: %d-%02d-%02d\n", year, month, day);
  86.     printf("day_of_year: %d\n", day_of_year(year, month, day));
  87.     printf("day_of_year_pointer: %d\n",
  88.         day_of_year_pointer(year, month, day));
  89.  
  90.  
  91.     yearday = 61;   /* 2000-03-01 */
  92.     month_day(year, yearday, &month, &day);
  93.     printf("Yearday is %d\n", yearday);
  94.     printf("month_day: %d %d\n", month, day);
  95.     month_day_pointer(year, yearday, &month, &day);
  96.     printf("month_day_pointer: %d %d\n", month, day);
  97.    
  98.     return 0;
  99. }
  100.  
  101.  
  102. Method №2
  103.  
  104. /* Given the problem, I thought that this would be a better
  105.  * description of daytab.
  106.  */
  107. static int *daytab = {
  108.     0,
  109.     31,
  110.     31+28,
  111.     31+28+31,
  112.     31+28+31+30,
  113.     31+28+31+30+31,
  114.     31+28+31+30+31+30,
  115.     31+28+31+30+31+30+31,
  116.     31+28+31+30+31+30+31+31,
  117.     31+28+31+30+31+30+31+31+30,
  118.     31+28+31+30+31+30+31+31+30+31,
  119.     31+28+31+30+31+30+31+31+30+31+30,
  120.     0,
  121.     31,
  122.     31+29,
  123.     31+29+31,
  124.     31+29+31+30,
  125.     31+29+31+30+31,
  126.     31+29+31+30+31+30,
  127.     31+29+31+30+31+30+31,
  128.     31+29+31+30+31+30+31+31,
  129.     31+29+31+30+31+30+31+31+30,
  130.     31+29+31+30+31+30+31+31+30+31,
  131.     31+29+31+30+31+30+31+31+30+31+30,
  132. };
  133.  
  134. /* is it a leap year?  (assume it's my calendar, the Gregorian) */
  135. int leap(int year)
  136. {
  137.     return ((year % 4) == 0)
  138.             && (((year % 100) != 0)
  139.                 || (year % 400) == 0)));
  140. }
  141.  
  142. /* day_of_year:  set day of year from month & day */
  143. int day_of_year(int year, int month, int day)
  144. {
  145.     return *(daytab + ((month - 1) + (leap(year) * 12))) + day;
  146. }
  147.  
  148. /* month_day: set month, day from day of year */
  149. void month_day(int year, int yearday, int *pmonth, int *pday)
  150. {
  151.     int m, ly;
  152.  
  153.     ly = leap(year);
  154.     if (yearday < 1 || yearday > (365 + ly))
  155.         return; /* no real error checking */
  156.     m = leap(year) ? 23 : 11;
  157.     while (*(daytab + m) > yearday)
  158.         m--;
  159.     if (pmonth)
  160.         *pmonth = (m % 12) + 1;
  161.     if (pday)
  162.         *pday = yearday - (*(daytab + m));
  163. }
Advertisement
Add Comment
Please, Sign In to add comment