I've been programming in C for 2-3 years now and I use it professionally at work as well.
One sticking point for me that I've seen happen over and over is I'd like to improve at debugging off-by-one type errors. I'm going to use an example program that I wrote a couple days ago as an example:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void reverse_arr(char *arr, size_t len);
void print_chars(char *arr, size_t len);
void reverse_words(char *arr, size_t len);
int main(int argc, char **argv)
{
char phrase[] = {'p','e','r','f','e','c','t',' ',
'm','a','k','e','s',' ','p','r',
'a','c','t','i','c','e'};
size_t i;
reverse_arr(phrase, sizeof(phrase));
reverse_words(phrase,sizeof(phrase));
print_chars(phrase, sizeof(phrase));
return EXIT_SUCCESS;
}
void reverse_arr(char *arr, size_t len)
{
size_t front, tail;
tail = len-1;
char tmp;
for(front = 0; front < len/2; front++, tail--)
{
tmp = arr[front];
arr[front] = arr[tail];
arr[tail] = tmp;
}
return;
}
// 1. Search for a space
// 2. When space is found, that space is the place to stop and indicates all between the start and it are a word
// 3. Now call reverse_arr on the word and calculate the length of the word by subtracting tail - start
//
void reverse_words(char *arr, size_t len)
{
size_t tail, start;
for(tail = start = 0; tail < len; tail++)
{
if(arr[tail] == ' ' || tail == len-1)
{
reverse_arr(&arr[start], tail - start);
start = tail+1;
}
}
}
void print_chars(char *arr, size_t len)
{
size_t i;
for(i = 0; i < len; i++)
{
putchar(arr[i]);
}
putchar('\n');
return;
}
I was banging my head on this for hours trying to troubleshoot my counters and loop conditions.. I did make some small progress but this again made me realize I could improve my skills. The answer was that the function needed to be changed to this:
Code:
void reverse_words(char*arr,size_t len)
{
size_t tail, start;
for(tail = start =0; tail <= len; tail++)
{
if(tail == len || arr[tail]==' ')
{
reverse_arr(&arr[start], tail - start);
start = tail+1;
}
}
}
The if test needed to be reversed and the loop condition needed to change from < to <=.
My question is, what types of debugging techniques would you use to find the answer for this in a reasonable amount of time? I tried printfs on the counter variables as well as using gdb and watches, breaking on the entry of the reverse_words() function.
I've noted that in C, this is a common occurrence due to the manual looping process versus Python which handles most of these cases for the programmer. But rather than run away from C, I'd like to improve in this area. C also tends to lend itself to very dense code like that in K&R C and while many people say "don't program like that and don't use codebases like that,"
A) I don't have that luxury. I'm a software security engineer and there are several programmers at work who write very cryptic code that I have to work with.
B) I actually find the compact nature of K&R style code to be fascinating and I'd like to get better at understanding and writing it in some cases.