Firstly, be sure that your code actually needs to be optimised. You can do that by running your program with a profiler, which will give you an idea of where your program is using its time. If it's spending only 1% of its time in your leapyear function, and 99% elsewhere, there's hardly any reason to optimise it. Similarly, if you're writing a smaller program and it terminates successfully in a few nanoseconds, you'd just be wasting your time.
If it's necessary to optimise this function, you can figure out the range you're most likely going to use (perhaps a few thousand years before the current year and a few thousand years after), then precompute the return values like so:
Code:
#include <stdio.h>
enum {
BASE = 1584,
THRESHOLD = 10000
};
static unsigned char tab[THRESHOLD - BASE];
int leapyear_slow(int y)
{
return !(y % 400) || (y % 100 && !(y % 4));
}
int leapyear(int y)
{
return y < BASE ? 0 :
y < THRESHOLD ? tab[y - BASE] : leapyear_slow(y);
}
void gen(void)
{
for (int i = 0; i < sizeof tab; i++)
tab[i] = leapyear_slow(i + BASE);
}
int main(void)
{
const char *s[] = { "not leap year", "leap year" };
int n;
for (gen(); scanf("%d", &n) == 1; puts(s[leapyear(n)]))
;
return 0;
}
If you need a larger range, you can save space by packing CHAR_BIT return values into each character, and you can save time by computing the values before the programs interpretation, perhaps by writing the hex values to a text file then #including it into your initialiser list like so:
Code:
static unsigned char tab[THRESHOLD - BASE] = {
#include "leapyears.txt"
};