mdh said:
The function accepts a command line argument of -n.
So, given
int main ( int argc, char *argv[])
......
if ( argc == 2 && (*++argv)[0]=='-')
n= atoi(argv[0]+1);
In general, avoid atoi, which is not robust in the face of ill-formed
input. strtol is far superior.
1) in a given function ( ? scope ?) once one has advanced the pointer
( to argv..in this case) is that where the pointer will remain
pointing at? and until when?
argv has type char **, and it's initially pointing at the first element
in an array of char *, each of which contains the address of the first
character in a string. When you do ++argv, you're moving it to point to
the /second/ element in that array of char *.
Let's look at it in terms of what might actually happen inside a real
(and very very simple) machine. Somewhere in memory, you have something
like this:
+--------+--------+--------+
addr + 0x3000 | 0x3002 | 0x3004 |
+--------+--------+--------+
val + 0x4200 | 0x4280 | 0x0000 |
+--------+--------+--------+
and, elsewhere, you have something like:
+--------+--------+--------+--------+--------+--------+
addr + 0x4200 | 0x4201 | 0x4202 | 0x4203 | 0x4204 | 0x4205 |
+--------+--------+--------+--------+--------+--------+
val + 'E' | 'x' | '5' | '1' | '3' | '\0' |
+--------+--------+--------+--------+--------+--------+
and...
+--------+--------+--------+
addr + 0x4280 | 0x4281 | 0x4282 |
+--------+--------+--------+
val + '-' | '6' | '\0' |
+--------+--------+--------+
argv starts off with the value 0x3000 (in our example, anyway!). As you
can see from the first array diagram, *argv is 0x4200. But then we add
1 to argv using ++argv. This means "move argv along by one OBJECT". So
we do that, moving argv's value from 0x3000 to the next slot in the
array, which is 0x3002. Then we deref it, which gives us the value
0x4280 (the value stored at address 0x3002). Finally, we come to [0].
Bear in mind that A[i] and *(A + I) are synonymous in C. So what we have
finally arrived at is *(0x4280 + 0) which is *0x4280 which is... check
the diagram... '-'.
So (*++argv)[0] ends up meaning this: "move argv along a bit, then find
the first character in what has now become the string that argv is
pointing to".
Better:
myarg = argv[1];
if(myarg[0] == '-')
{
n = strtol(myarg + 1, &e, 10);
where e is a char *. (Look up strtol.)
2) In the case above, where Tondo and Gimpel use indices as well as
pointer incrementation, is there a good reason for this or is this
just a matter of style? ie why not use ( instead of (*++argv)[0])
argv[1][0]? ( if that indeed is equivalent?)
It's nearly equivalent. ++argv has the side effect of adding 1 to argv,
which affects all the indices in subsequent lines.
I can't comment on T&G's code, since I have never seen it.
3) I have until now not seen the construct "atoi(argv[0]+1". Does this
mean get the pointer at index argv[1] ( which I believe is an pointer
to char array, then add 1 to that pointer? ( not argv)?
To understand atoi(argv[0] + 1), start with argv[0] and be sure you know
what it points to. If argv's value has been modified prior to this
point, that is important (and, in your example, it has been).
Once you know that it points to the first character in a string, you can
see that argv[0] + 1 will point to the second character in that string.
So for example, if argv[0] --"-42987", then argv[0] + 1 --"42987",
argv[0] + 2 --"2987", argv[0] + 3 --"987", etc.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.