After completing KNK2, my interest in C was reignited, prompting a
re-reading of Traister's dubious book on pointers. Then I dusted off
the fine ``C Traps and Pitfalls'' by Andy Koenig. Nowadays I primarily
work in PHP, Perl and C++. Consequently my C skills have atrophied.
So inspired by CT&P's ``calendar'' example on page 30, I decided to
brush up on some elementary C (although Koenig describes it as walking
``out on the ice'') with the little toy exercise below.
For posting, here I yanked all the comments for brevity. There's a
(too?) liberal use of typedef, pointers for the sake of pointers and
some blatantly obvious asserts. It compiles cleanly with Sun C 5.8
2005/10/13 on a SPARC and lint shows only functions returning values
that are ignored. The output meets expectations for a non-leap year.
So look this over being brutal and merciless with your critique as I
try to rebuild my flabby C muscles:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MONTHS = 12, DAYS = 31 };
enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
static const char *const months[] = { "JAN", "FEB", "MAR", "APR",
"MAY", "JUN", "JUL", "AUG",
"SEP", "OCT", "NOV", "DEC", };
int main(void)
{
typedef int month_type[DAYS];
typedef month_type *month_ptr_type ;
typedef int *day_ptr_type;
int calendar[MONTHS][DAYS];
month_ptr_type month_ptr;
size_t num_months;
size_t num_days_per_mo nth;
memset(calendar , 0, sizeof calendar);
assert(calendar[DEC][DAYS - 1] == 0);
month_ptr = calendar;
assert(sizeof *month_ptr == DAYS * sizeof(int));
num_months = sizeof calendar / sizeof *calendar;
assert(num_mont hs == MONTHS);
num_days_per_mo nth = sizeof *calendar / sizeof **calendar;
assert(num_days _per_month == DAYS);
for(; month_ptr < calendar + num_months; ++month_ptr) {
day_ptr_type day_ptr = *month_ptr;
int month_num = (month_ptr - calendar + num_months) - num_months;
int days_in_month;
int day_num;
switch(month_nu m) {
case FEB:
days_in_month = 28;
break;
case APR:
case JUN:
case SEP:
case NOV:
days_in_month = 30;
break;
default:
days_in_month = 31;
break;
}
for(day_num = 1; day_num <= days_in_month; ++day_num, ++day_ptr)
*day_ptr = day_num;
}
for(month_ptr = calendar; month_ptr < calendar + num_months; ++month_ptr) {
int month_num = (month_ptr - calendar + num_months) - num_months;
int total_days_in_m onth = -1;
day_ptr_type day_ptr;
for(day_ptr = *month_ptr + num_days_per_mo nth - 1;
day_ptr *month_ptr; --day_ptr) {
if(*day_ptr) {
total_days_in_m onth = *day_ptr;
break;
}
}
printf("month %d (%s) has %d days\n",
month_num + 1, months[month_num], total_days_in_m onth);
}
return EXIT_SUCCESS;
}
re-reading of Traister's dubious book on pointers. Then I dusted off
the fine ``C Traps and Pitfalls'' by Andy Koenig. Nowadays I primarily
work in PHP, Perl and C++. Consequently my C skills have atrophied.
So inspired by CT&P's ``calendar'' example on page 30, I decided to
brush up on some elementary C (although Koenig describes it as walking
``out on the ice'') with the little toy exercise below.
For posting, here I yanked all the comments for brevity. There's a
(too?) liberal use of typedef, pointers for the sake of pointers and
some blatantly obvious asserts. It compiles cleanly with Sun C 5.8
2005/10/13 on a SPARC and lint shows only functions returning values
that are ignored. The output meets expectations for a non-leap year.
So look this over being brutal and merciless with your critique as I
try to rebuild my flabby C muscles:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MONTHS = 12, DAYS = 31 };
enum { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
static const char *const months[] = { "JAN", "FEB", "MAR", "APR",
"MAY", "JUN", "JUL", "AUG",
"SEP", "OCT", "NOV", "DEC", };
int main(void)
{
typedef int month_type[DAYS];
typedef month_type *month_ptr_type ;
typedef int *day_ptr_type;
int calendar[MONTHS][DAYS];
month_ptr_type month_ptr;
size_t num_months;
size_t num_days_per_mo nth;
memset(calendar , 0, sizeof calendar);
assert(calendar[DEC][DAYS - 1] == 0);
month_ptr = calendar;
assert(sizeof *month_ptr == DAYS * sizeof(int));
num_months = sizeof calendar / sizeof *calendar;
assert(num_mont hs == MONTHS);
num_days_per_mo nth = sizeof *calendar / sizeof **calendar;
assert(num_days _per_month == DAYS);
for(; month_ptr < calendar + num_months; ++month_ptr) {
day_ptr_type day_ptr = *month_ptr;
int month_num = (month_ptr - calendar + num_months) - num_months;
int days_in_month;
int day_num;
switch(month_nu m) {
case FEB:
days_in_month = 28;
break;
case APR:
case JUN:
case SEP:
case NOV:
days_in_month = 30;
break;
default:
days_in_month = 31;
break;
}
for(day_num = 1; day_num <= days_in_month; ++day_num, ++day_ptr)
*day_ptr = day_num;
}
for(month_ptr = calendar; month_ptr < calendar + num_months; ++month_ptr) {
int month_num = (month_ptr - calendar + num_months) - num_months;
int total_days_in_m onth = -1;
day_ptr_type day_ptr;
for(day_ptr = *month_ptr + num_days_per_mo nth - 1;
day_ptr *month_ptr; --day_ptr) {
if(*day_ptr) {
total_days_in_m onth = *day_ptr;
break;
}
}
printf("month %d (%s) has %d days\n",
month_num + 1, months[month_num], total_days_in_m onth);
}
return EXIT_SUCCESS;
}
Comment