When your algorithm produces output in reverse order, take a pointer to the end of a buffer and write it in decreasing order, returning a pointer to the first element. It's up to the caller to supply a buffer large enough for any this input, or for any possible input.
Base conversion / int-to-string is a classic example where this interface is used in real life, such as glibc's internal _itoa
, used by the printf family of functions as well as some other internal callers. The max buffer size is 65 bytes for a 64-bit integer -> base 2 string.
// takes a pointer to one-past-the-end, which is also a valid option.char *itoa_end(unsigned long val, char *p_end) { // does *not* zero terminate the buffer. Use *--p_end = 0; const unsigned base = 10; char *p = p_end; do { *--p = (val % base) +'0'; val /= base; } while(val); // runs at least once to print '0' for val=0. // write(1, p, p_end-p); return p; // let the caller know where the leading digit is}
For golfing, it can be more compact to take the pointer by reference and modify it, instead of returning it. (return
is a long keyword, and code depending on gcc -O0
evaluating expressions in the return-value register isn't even C.)
For example, I used this in ASCII art uncompression from a base-n number (i.e. int->string with a digit lookup table), where I already needed a char*
arg, so it was very cheap to declare another as a char **
.
Use *p
everywhere you have p
in the simple version. *--*p
decrements the caller's pointer, then dereferences that to reference the actual character.
/* int n = the number * int B = size of I = base * char I[] = input table * char **O = input/output arg passed by ref: * on entry: pointer to the last byte of output buffer. * on exit: pointer to the first byte of the 0-terminated string in output buffer */void semi_golfed_g(n,I,B,O)char*I,**O;{ for(**O=0 ; n ; n/=B) *--*O = I[n%B];}