/** delimiter.c -- by James D. Lin (last updated: 2006-05-29) * * Demonstration of a hack to print delimiters only between items * in a sequence with minimal code duplication and without using * an extra conditional per iteration. */ #include #include /** Returns the length of an array; array must be a true array, not a pointer. */ #define ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0]) int main(void) { const char* words[] = { "the", "five", "boxing", "wizards", "jump", "quickly" }; const char* delimiter = "_"; size_t i = 0; size_t n = ARRAY_LENGTH(words); /* Conventional approach #1: * Handle the first element explicitly as a special case before * starting the loop. (Or alternatively, handle the last element * explicitly after exiting the loop.) * * Duplicates the meat of the loop body. */ i = 0; if (i < n) { while (i < n - 1) { printf("%s", words[i]); printf("%s", delimiter); i++; } printf("%s", words[i]); putchar('\n'); } /* Conventional approach #2: * Handle the first (or alternatively, the last) element explicitly as * a special case inside the loop. * * Compact but evaluates two conditionals per iteration. */ i = 0; while (i < n) { printf("%s", words[i]); i++; if (i != n) { printf("%s", delimiter); } } putchar('\n'); /* Conventional approach #3: * Remove the redundant outer conditional from approach #2. * * Slightly less compact, and control flow is slightly less clear. */ i = 0; if (i < n) { while (1) { printf("%s", words[i]); ++i; if (i == n) { break; } printf("%s", delimiter); } } putchar('\n'); /* Hacky approach: * Special-case the first iteration, but don't do it inside the loop, * and avoid duplicating code. * * Uses 'goto', which most people are afraid to use. Code is relatively * compact but weird-looking. */ i = 0; if (i < n) { goto start; while (i < n) { printf("%s", delimiter); start: printf("%s", words[i]); i++; } } putchar('\n'); return EXIT_SUCCESS; }