"Mike Wahler" <mk******@mkwah ler.net> wrote in message news:<bU******* ***********@new sread1.news.pas .earthlink.net> ...
"Daniel Rudy"
<i0************ *************** *******@n0o1p2a 3c4b5e6l7l8s9p0 a1m2.3n4e5t6>
wrote in message news:kG******** ***********@new ssvr21.news.pro digy.com...
Thanks to everyone who replied. The code now looks like this:
strata:/home/dcrudy/c 1047 $$$ ->cat argtest.c
/*
just echos the command line arguments onto the screen
tests the format of argument processing
*/
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i; /* generic counter */
if (argc < 3)
{
printf("error: need more arguments.\n");
return(0);
}
printf("argc = %d\n", argc);
for (i = 0; i < argc; i++)
{
printf("argv[%d] = %s\n", i, argv[i]);
}
/* return to operating system */
return(0);
}
So now when I run it, instead of core dumping, I get the following output:
strata:/home/dcrudy/c 1046 $$$ ->./argtest arg1 arg2 arg3
argc = 4
argv[0] = ./argtest
argv[1] = arg1
argv[2] = arg2
argv[3] = arg3
Now there is something about this that I do not understand. What
exactly is the nature of argv? I know it's an array,
Actually, it's not. Arrays cannot be passed to or returned
from functions.
but is it an array
of char?
No. It's a pointer (to an array of pointers (to char)).
This allows for arguments of varying lengths.
Actually, it's just a pointer to pointer to char, not a pointer to an
array of pointers to char (otherwise it would have to be typed char
*(*argv)[SIZE]).
A number of people pointed out that the * was required.
AFAIK, * is a pointer reference.
Right. Logically speaking, you're passing an array of strings to
main(). Physically speaking, this translates as a pointer to a
pointer to char:
int main (int argc, char *argv[])
or
int main (int argc, char **argv)
Here's why. Remember that a "string" in C is a 0-terminated array of
char:
char a[6] = "Hello"; /* a == {'H', 'e', 'l', 'l', 'o', 0} */
Therefore, an array of strings would be an array of 0-terminated
arrays of char:
char b[2][6] = {"Hello", "World"};
Now, remember that when you pass an array as an argument to a
function, what actually happens is that you pass a *pointer* to the
first element of the array. In other words:
void foo(char *arr) {...}
....
foo(a); /* a == &a[0] */
foo(b[0]); /* b[0] == &b[0][0] */
foo(b[1]); /* b[1] == &b[1][0] */
....
Even though the actual *types* of a, b[0], and b[1] are "6-element
array of char", when an array identifier appears in any context other
than as an operand to sizeof, it is evaluated as a pointer to the
first element in the array.
Now, since b is itself an array of something, when we pass it to a
function, we are actually passing the pointer to the first element:
void bar(char **arr) {...}
....
bar(b); /* b == &b[0] */
....
In the context of a function prototype, a[] and *a are equivalent;
both indicate that a is a pointer to something. *b[] and **b are also
equivalent. Since this tends to cause no end of confusion, I stick
with the *a, **b syntax exclusively.