4
\$\begingroup\$

Rewrite the routines day_of_year and month_day with pointers instead of indexing.

The exercise is quite simple, this is the solution:

int day_of_year(unsigned int year, int month, int day) {
    int leap, i;

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

    if((month >= 1 && month <= 12) && ((day >= 1) && (day <= *(*(daytab + leap) + month)))) {
        for(i = 1; i < month; i++) {
            day += *(*(daytab + leap) + i);
        }

        return day;
    }

    return -1;

}

int month_day(unsigned int year, int yearday, int *pmonth, int *pday) {
    int leap, i;

    leap = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
    if((leap == 1 && (yearday >= 1 && yearday <= 366)) || (leap == 0 && (yearday >= 1 && yearday <= 365))) {

        for(i = 1; yearday > *(*(daytab + leap) + i); i++) {
          yearday -= *(*(daytab + leap) + i);
        }
        *pday = yearday;
        *pmonth = i;

        return 1;
    }
    return -1; 
}

The expression (daytab + leap) is a pointer to the leap-th row and (*(daytab + leap) + i) is a pointer to the i-th element of the leap-th row.

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

It would have been nice to see your daytab definition as well. I'll just assume that you're satisfied with the way it's defined, and that the functions work as intended.

I find this condition in month_day() a bit monstrous:

if((leap == 1 && (yearday >= 1 && yearday <= 366)) || (leap == 0 && (yearday >= 1 && yearday <= 365)))

I would shorten it to the following. Also, I've inverted the check, so that the function returns early if the parameters fail validation. Returning early is a better habit, as it reduces indentation, and reduces mental load when reading the code by getting the simpler branch out of the way.

int leap = (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
if (yearday < 1 || yearday > 365 + leap) {
    return -1;
}
for (…) {
    …
}
\$\endgroup\$
1
  • \$\begingroup\$ But in this case I have to declare the variable i after the if. Is it recommended to declare variables in other places than the beginning of a routine? \$\endgroup\$
    – cristid9
    Commented Feb 15, 2014 at 0:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.