Reputation: 520
I found sample code that iterates over a C style string array inside a main function, the code works fine and looks like this:
int _tmain(int argc, TCHAR* argv[])
{
for (TCHAR **iList = argv; *iList != NULL; ++iList)
{
wcout << *iList << endl;
}
cin.get();
return 0;
}
There is a part which I don't understand:
*iList != NULL
Maybe somebody can explain to me this part?
Upvotes: 1
Views: 2279
Reputation: 41
To break it down to simplest form; Think of a 2-D array,
[0,0] [0,1] [0,2] [0,3] [0,4] [0,5]
[1,0] [1,1] [1,2] [1,3] [1,4] [1,5]
[2,0] [2,1] [2,2] [2,3] [2,4] [2,5]
[3,0] [3,1] [3,2] [3,3] [3,4] [3,5]
[4,0] [4,1] [4,2] [4,3] [4,4] [4,5]
[5,0] [5,1] [5,2] [5,3] [5,4] [5,5]
NULL
Each element is a TCHAR element representing a single character, Each row is a string(an array of characters is a string), with the last element begin '\0'(NULL terminator)
**ilist = argv
means ilist points to the first element of matrix i.e. [0,0]
*ilist
represents the complete row, so printing it using cout will print out a string that is contained int that row
++ilist
increments the pointer to first element of next row(so incrementing it one time will make ilist to point at [1,0])
ilist != NULL
checks whether we have reached the end of the matrix, so the loop executes until the end of matrix has not been reached, the last row(the one after 5th row, contains NULL, thus conveying the end of array)
(The actually array representation in memory is not the same as above, it is almost similar, the number of element in a row vary according to the string length, For example suppose the arguments are : "This is a string", it can be represented as:
[0]->[T] [h] [i] [s] [\0]
[1]->[i] [s] [\0]
[2]->[a] [\0]
[3]->[s] [t] [r] [i] [n] [g] [\0]
[4]->NULL
Remember '\0'
is null terminator, it is used to tell that this is the end of the string)
Upvotes: 1
Reputation: 13314
C-style strings are also called null-terminated strings. That just means that you have the characters of the actual string laid out together in memory, and then after all of those characters, you have the null character. So when you want to iterate over all the characters in a C-style string, you just need to start at the beginning and keep going until you reach a null character.
In this particular example, however, you're dealing with an array of strings, not just a single string. What this means is that argv
actually points to a location in memory which is the beginning of a list of pointers. Each pointer in that list then points to a C-style string. At the end of this array of pointers, you have a NULL
pointer, so once you reach that, you've iterated over all the strings in argv
.
Let's look at it line-by-line:
for (TCHAR **iList = argv; *iList != NULL; ++iList)
OK, that's too complicated. Let's just look at the first expression first:
TCHAR **iList = argv;
This declares a variable iList
which is of type TCHAR**
. That means it is a pointer to a pointer to a TCHAR
. Its value points to the location of a pointer, and that pointer then points to the location of the beginning of a C-style string.
*iList != NULL;
This takes the thing pointed to by iList
and sees if it is a NULL
pointer. Remember that iList
points to pointers, so the goal is to keep examining pointers pointed to by iList
until you find one that actually doesn't point to anything (that's what NULL
means), and stop.
++iList
This just means that, every time you execute the body of the for
loop, you add 1 to the value of iList
. Since iList
is a pointer to pointers, we're telling iList
to point to the pointer right after the one it was previously pointing to.
And finally:
wcout << *iList << endl;
This means to take whatever is pointed to by iList
(a pointer, because iList
points to pointers) and insert it into wcout
, followed by a newline character. The insertion operator in this case is smart: since the thing pointed to by iList
is a pointer to characters, it knows to interpret it as a C-style string, and so follows the characters pointed to by that pointer that iList
points to (yay, confusion) until it finds a null character, and prints all those characters to the screen. The endl
acts as both a newline and a signal to flush the wcout
buffer (print it directly to the screen instead of just keeping it in memory).
Upvotes: 3