Exercise 5-9. Rewrite the routines
day_of_yearandmonth_daywith pointers instead of indexing.
Replace every daytab[leap][i] with pointer arithmetic. The key step: instead of indexing into the 2D array, take a pointer to the correct row (const char *p = daytab[ly]) and use p[i] or *(p + i) to access elements. The loop variable can be replaced by advancing the pointer directly.
Solution
/* K&R Exercise 5-9 — day_of_year / month_day with pointers
* Compile: gcc -ansi -Wall ex5-9.c -o ex5-9 */
#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}
};
static int leap(int year) { return year%4==0 && (year%100!=0 || year%400==0); }
int day_of_year(int year, int month, int day)
{
const char *p = daytab[leap(year)]; /* pointer to the correct row */
const char *pm;
for (pm = p + 1; pm < p + month; pm++)
day += *pm;
return day;
}
int month_day(int year, int yearday, int *pmonth, int *pday)
{
const char *p = daytab[leap(year)];
const char *pm;
for (pm = p + 1; yearday > *pm; pm++)
yearday -= *pm;
*pmonth = (int)(pm - p);
*pday = yearday;
return 0;
}
int main(void)
{
int m, d;
printf("2024-03-01: day %d\n", day_of_year(2024,3,1)); /* 61 */
printf("2023-12-31: day %d\n", day_of_year(2023,12,31)); /* 365 */
month_day(2024, 61, &m, &d);
printf("day 61 of 2024: %02d/%02d\n", m, d); /* 03/01 */
month_day(2023, 365, &m, &d);
printf("day 365 of 2023: %02d/%02d\n", m, d); /* 12/31 */
return 0;
}
Array vs Pointer Comparison
/* Indexing (original) */
for (i = 1; i < month; i++)
day += daytab[leap(year)][i];
/* Pointer (exercise 5-9) */
const char *p = daytab[leap(year)];
for (pm = p + 1; pm < p + month; pm++)
day += *pm;
In month_day, the pointer version has a bonus: pm - p gives the month number directly without maintaining a separate counter.
Compile and Run
gcc -ansi -Wall ex5-9.c -o ex5-9
./ex5-9
Sample Output
2024-03-01: day 61 2023-12-31: day 365 day 61 of 2024: 03/01 day 365 of 2023: 12/31
What This Exercise Teaches
- Row pointer from 2D array —
daytab[ly]is a pointer to the first element of rowly; assigning it toconst char *pis idiomatic - Pointer difference as index —
pm - precovers the integer index without a counter variable; this is the pointer-arithmetic payoff - Bounds via pointer comparison —
pm < p + monthis equivalent toi < month; both compile to the same loop
Set Up Your C Environment
← Exercise 5-8 |
Chapter 5 Solutions |
Exercise 5-10 →
Book: The C Programming Language, 2nd Ed — Kernighan & Ritchie