TL;DR:
Use % instead of ‘if’ to reset counters
Use constants
Nest struct to keep your variables in one place
Here are a few tips to programmers in c out there. I don’t say that this is the correct way to program in c. It just a few tricks that I do when programming.
Anyway, let’s say you have a function that tracking some information in an array, in length of 10.
I have the following code for this:
#include <stdio.h>
#include <string.h>
struct history
{
int value;
}my_history[10];
int history_pointer=0;
int history_handler(int value_to_add)
{
my_history[history_pointer].value=value_to_add;
history_pointer++;
if (history_pointer==10) history_pointer=0;
}
int main (int argc, char *argv[])
{
int i;
memset(&my_history,0,sizeof(my_history));
for (i=0;i<100;i++)
history_handler(i);
for (i=0;i<10;i++)
printf ("%d - %d\n",i,my_history[i]);
return 0;
}
For this code I”ll change a few things:
- I”ll remove the if in the function handler – prettier and faster code
- I”ll change the length of the array to constant – will allow easily to change the size of the array in the future
- And I”ll nest the array with a pointer – will give me one array belonging to my function, so anyone else reading my program will understand it better, and it keeps all my variable in one place.
End result will be:
#include <stdio.h>
#include <string.h>
#define HISTORY_LENGTH 10
struct history_data
{
int value;
};
struct history
{
struct history_data my_data[HISTORY_LENGTH];
int history_pointer;
}my_history;
int history_handler(int value_to_add)
{
my_history.my_data[my_history.history_pointer].value=value_to_add;
my_history.history_pointer=(my_history.history_pointer+1)%HISTORY_LENGTH;
}
int main (int argc, char *argv[])
{
int i;
printf("main-imp\n");
memset(&my_history,0,sizeof(my_history));
for (i=0;i<100;i++)
history_handler(i);
for (i=0;i<10;i++)
printf ("%d - %d\n",i,my_history.my_data[i]);
return 0;
}
The first change I’ve added the constant instead of 10 :
#define HISTORY_LENGTH 10
I later changed every instance of 10 with the constant HISTORY_LENGTH. If in the future I will need to change the history length I will only change it here.
In the second changed, instead of using the history pointer as a global variable, I nested one struct within another. This keeps all my variable in one “place” under one struct, and any future change will be done there.
struct history_data
{
int value;
};
struct history
{
struct history_data my_data[HISTORY_LENGTH];
int history_pointer;
}my_history;
In the third change, I removed the if:
if (history_pointer==10) history_pointer=0;
And then I changed the increment the pointer from
history_pointer++;
To
my_history.history_pointer=(my_history.history_pointer+1)%HISTORY_LENGTH;
This means increment the history pointer by 1, and use the ‘%’ remainder operand. This do the same as when this was an ‘if’ statement, but this is faster and better looking.
I’m extremely impressed with your writing skills and also with the layout on your weblog.
Is this a paid theme or did you modify it yourself? Anyway keep
up the excellent quality writing, it is rare to see
a great blog like this one these days.