Monday, January 26, 2009

Multiple Levels of Pointers; Program Arguments

When a C program is called, the arguments on the command line are made available to the main program as an argument count argc and an array of character strings argv containing the arguments. Manipulating these arguments is one of the most common uses of multiple levels of pointers (``pointer to pointer to ...''). By convention, argc is greater than zero; the first s argument (in argv[0]) is the command name itself.
Here is a program that simply echoes its arguments.
main(argc, argv)
int argc;
char **argv; {
int i;
for( i=1; i < argc; i++ )
}
Step by step: main is called with two arguments, the argument count and the array of arguments. argv is a pointer to an array, whose individual elements are pointers to arrays of characters. The zeroth argument is the name of the command itself, so we start to print with the first argument, until we've printed them all. Each argv[i] is a character array, so we use a `%s' in the printf.
You will sometimes see the declaration of argv written as
char *argv[ ];
which is equivalent. But we can't use char argv[ ][ ], because both dimensions are variable and there would be no way to figure out how big the array is.
Here's a bigger example using argc and argv. A common convention in C programs is that if the first argument is `-', it indicates a flag of some sort. For example, suppose we want a program to be callable as
prog -abc arg1 arg2 ...
where the `-' argument is optional; if it is present, it may be followed by any combination of a, b, and c.
main(argc, argv)
int argc;
char **argv; {
...
aflag = bflag = cflag = 0;
if( argc > 1 && argv[1][0] == '-' ) {
for( i=1; (c=argv[1][i]) != '\0'; i++ )
if( c=='a' )
aflag++;
else if( c=='b' )
bflag++;
else if( c=='c' )
cflag++;
else
printf("%c?\n", c);
--argc;
++argv;
}
...
There are several things worth noticing about this code. First, there is a real need for the left-to-right evaluation that && provides; we don't want to look at argv[1] unless we know it's there. Second, the statements
--argc;
++argv;
let us march along the argument list by one position, so we can skip over the flag argument as if it had never existed; the rest of the program is independent of whether or not there was a flag argument. This only works because argv is a pointer which can be incremented.

No comments:

Post a Comment