I turned print_args into the main function of a program that contains nothing and ran it. This is what it does:
$ ./a.out a ab abc abcd arg 1: a -> ab arg 2: ab -> abc arg 2: ab -> abc arg 3: abc -> abcd arg 3: abc -> abcd arg 3: abc -> abcd arg 4: abcd -> (null) arg 4: abcd -> (null) arg 4: abcd -> (null) arg 4: abcd -> (null)
In other words, for each character of each command line argument, it prints the entire command line argument, a thin arrow, and the next command line argument. (If my C library was not very nice with printf("%s", (char *)NULL) , it would crash when it got to the end.) Listing the entire command line argument, why does it need c , arg as well, although this line read perfectly
printf("arg %d: %s -> %s\n", i, argv[i], argv[i+1]);
and then arg not required.
Your hunch is as good as mine why this function performs this particular thing. For me, this does not seem to be a particularly useful thing.
EDIT: If your goal is to print argv[i] and argv[i+1] when argv[i] starts with a dash and argv[i+1] not NULL (which may make sense in context) then you should write it like this:
void print_args(int argc, const char *const *argv) { int i; for (i = 0; i < argc; i++) if (argv[i][0] == '-' && argv[i+1]) printf("arg %d: %s -> %s\n", i, argv[i], argv[i+1]); }
If you want to print when argv[i] contains a dash, then replace
argv[i][0] == '-'
with
strchr(argv[i], '-')
in the if statement.
Appendix: I highly recommend that you read http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html , which describes how modern UNIX command-line programs should interpret their arguments.