简体   繁体   中英

how to iterate C style string array

I found sample code that iterates through C style string array, it works but I don't understand how it works, what I in particular don't understand is:

*iList != NULL

Maybe somebody can explain to me how it works. Might there alternative, maybe easier ways to write this code, maybe with a range based C++ 11 for?

int _tmain(int argc, TCHAR* argv[])
{
    for (TCHAR **iList = argv; *iList != NULL; ++iList)
    {
        wcout << *iList << endl;
    }

    cin.get();
    return 0;
}

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).

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 ie [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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM