Few c tips

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:

  1. I”ll remove the if in the function handler – prettier and faster code
  2. I”ll change the length of the array to constant – will allow easily to change the size of the array in the future
  3. 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.

Why do I use vim?

TL;DR: shortcuts. 99.9% of code editors has vim addons, so I can use familiar shortcuts from vim in every code editor.

Vim, the ancient text editor, that used to edit text files in terminal, is being used by a lot of people. Me including. Why should anyone use this old, terminal based text editor, while there are beautiful window based, fashionable and modern text editors out there? 

One of the best benefits of using vim is that I learned many of the vim shortcuts. And every other editor that I used has a vim addon. This allows me to use all vim shortcuts in every editor, without learning new shortcuts.

Example of vim add on for visual studio code

A little tip, use vim bootstrap to add some pre defined features to your vim. I added some personal addition on top of that , check them here.