Reputation: 536
I got this code snippet from here:
int main(int argc, char *argv[])
{
for (int i = 1; i < argc; ++i) {
char *pos = argv[i];
while (*pos != '\0') {
printf("%c\n", *(pos++));
}
printf("\n");
}
}
I have two questions:
Why are we starting the iterations of for
loop at i=1
, why not
start it at i=0
, especially when we are ending the iterations at
i<argc
and Not at i<=argc
?
The second, third and fourth last lines of code! In char *pos =
argv[i];
, we declare a pointer type variable and assign it a
pointer to a commandline parameter passed when running the program.
Then in while (*pos != '\0')
, *pos
dereferences the pointer
stored in pos
, so *pos
contains the actual value pointed by the
pointer stored in pos
.
Then in printf("%c\n", *(pos++));
, we have *(pos++)
, and
that is the actual question: (a) Why did he increment pos
, and
(b) what is the meaning of dereferencing (pos++)
with the
dereference operator *
?
Upvotes: 0
Views: 275
Reputation: 21965
Why are we starting the iterations of for loop at i=1, why not start it at i=0, especially when we are ending the iterations at i < argc and Not at i <= argc?
Note that the argc
contains the name of the program being executed too which will be the first (given the number zero) thing to be counted. So the actual arguments starts from 1 and ends at total - 1
A note here, the command line arguments are stored in array of pointer to char, ie
argv[0] -> "YourFirstArguement"
argv[1] -> "YourSecondArguement"
.
.
argv[argc-1] -> "YourLastArguement" //Remember argc-1 is the last argument
and so. Note that each of the argument is a null terminated string
So in
char *pos = argv[i]; // Create another pointer to each string
while (*pos != '\0') {
printf("%c\n", *(pos++)); // Note %c, you're printing char by char.
}
You're just printing character by character using the format specifier %c
in printf. So you need to dereference character by character in the while loop and this answers
a) Why did he increment pos, and
b) what is the meaning of dereferencing (pos++) with the dereference operator *?
Upvotes: 0
Reputation: 28674
Why are we starting the iterations of for loop at i=1, why not start it at i=0, especially when we are ending the iterations at i
Because first parameter is name of the program - and it seems author is not interested in it.
Second case is basically similar to the following (argv[i]
basically being a char *
):
So you have something like this:
char * c = "Hello"
and then char * p = c;
Now you have
+------------------+
| H e l l o /0 |
| ^ |
| | |
+------------------+
|
|
+
p
When you do p++
you have
+------------------+
| H e l l o /0 |
| ^ |
| | |
+------------------+
|
+-+
+
p
If you do now *p
- the value you get is 'e'.
*(p++)
is basically same as above two steps, just due to post increment, first the value where p
points will be retrieved (before increment), and then p
will advance.
Then in printf("%c\n", *(pos++));, we have *(pos++), and that is the actual question: (a) Why did he increment pos, and (b) what is the meaning of dereferencing (pos++) with the dereference operator *?
So in the while
loop the author is traversing through the whole string until he meets null terminator '\0' and printing each character.
This on the other hand is repeated for each parameter in argv
using the for loop.
Upvotes: 2
Reputation: 134356
For the first part,
Why are we starting the iterations of for loop at
i=1
, why not start it ati=0
, especially when we are ending the iterations ati<argc
and Not ati<=argc
?
Because, for hosted environment, argv[0]
represents the executable name. Here, we're only interested in supplied command line arguments other than the executable name itself.
Quoting C11
, chapter §5.1.2.2.1
If the value of
argc
is greater than zero, the string pointed to byargv[0]
represents the program name; [....] If the value ofargc
is greater than one, the strings pointed to byargv[1]
throughargv[argc-1]
represent the program parameters.
Point to note: using i<=argc
as the loop condition would be wrong, as C arrays use 0-based indexing.
For the second part,
(a) Why did he increment
pos
, and (b) what is the meaning of dereferencing(pos++)
with the dereference operator*
?
*(pos++),
can also be read as *pos; pos++;
which, reads the current value from the memory location pointed to by pos
and then advances pos
by one element.
To elaborate, at the beginning of each iteration of the for
loop, by saying
char *pos = argv[i];
pos
holds the pointer to the starting of the string which holds the supplied program parameter and by continuous increment (upto NULL
), we're basically traversing the string and by dereferencing, we're reading the value at those locations.
Just for the sake of completeness, let me state, that the whole for
loop body
char *pos = argv[i];
while (*pos != '\0') {
printf("%c\n", *(pos++));
can be substituted using
puts(argv[i]);
Upvotes: 2
Reputation: 12404
- Why are we starting the iterations of for loop at i=1, why not start it at i=0, especially when we are ending the iterations at i
We start at 1 because argv[0]
holds the name of the program itself which we don't care about. Ignoring the first element of an array does not move the index of the last array.
We have argc
elements stored in argv[]
. Therefore we mustn't run until i==argc
but need to stop one element earlier, just as with every other array.
- The second, third and fourth last lines of code! In char *pos = argv[i];, we declare a pointer type variable and assign it a pointer to a commandline parameter passed when running the program.
Correct. pos
is a pointer and points to the first string passed via command line.
Then in while (*pos != '\0'), *pos dereferences the pointer stored in pos, so *pos contains the actual value pointed by the pointer stored in pos.
*pos
contains the first character of the string we are currently inspecting.
Then in printf("%c\n", *(pos++));, we have *(pos++), and that is the actual question: (a) Why did he increment pos, and (b) what is the meaning of dereferencing (pos++) with the dereference operator *?
You have 2 things here:
1. (pos++)
: pos
is a pointer to char
and with ++
increment the pointer to point to the next element, i.e. to the next char
after taking its value.
2. The value of pos
(before the post-increment) is taken and dereferenced to read the char
at that position.
As a result the while
loop will read all characters, while the for
loop handles all strings.
Upvotes: 3