我找到了迭代C样式字符串数组的示例代码,它可以工作,但我不明白它是如何工作的,我特别不明白的是:
* iList!= NULL
也许有人可以向我解释它是如何运作的。可能有替代方法,可能更简单的方法来编写此代码,可能使用基于范围的C ++ 11 for?
int _tmain(int argc, TCHAR* argv[])
{
for (TCHAR **iList = argv; *iList != NULL; ++iList)
{
wcout << *iList << endl;
}
cin.get();
return 0;
}
答案 0 :(得分:2)
C风格的字符串也称为以空字符结尾的字符串。这只意味着你将实际字符串的字符放在内存中,然后在所有这些字符之后,你有空字符。因此,当你想迭代C风格字符串中的所有字符时,你只需要从头开始并继续前进,直到你找到一个空字符。
但是,在这个特定示例中,您正在处理字符串数组,而不仅仅是单个字符串。这意味着argv
实际指向内存中的一个位置,它是指针列表的开头。然后,该列表中的每个指针都指向一个C风格的字符串。在这个指针数组的末尾,你有一个NULL
指针,所以一旦你到达那个指针,你就会迭代argv
中的所有字符串。
让我们逐行看一下:
for (TCHAR **iList = argv; *iList != NULL; ++iList)
好的,那太复杂了。让我们先看看第一个表达式:
TCHAR **iList = argv;
这声明了一个iList
类型的变量TCHAR**
。这意味着它是指向TCHAR
指针的指针。它的值指向指针的位置,然后该指针指向C风格字符串开头的位置。
*iList != NULL;
这会接受iList
指向的事情并查看它是否是NULL
指针。请记住,iList
指向指针,因此我们的目标是继续检查iList
指向的指针,直到找到一个实际上并未指向任何指针的指针(NULL
{++iList
1}}意味着),并停止。
for
这只是意味着,每次执行iList
循环的主体时,都会将iList
的值加1。由于iList
是指向指针的指针,因此我们告诉wcout << *iList << endl;
指向指针之后的指针。
最后:
iList
这意味着接受iList
所指向的任何内容(指针,因为wcout
指向指针)并将其插入iList
,然后是换行符。在这种情况下插入运算符是智能的:因为iList
指向的东西是指向字符的指针,它知道将它解释为C样式的字符串,因此遵循该指针所指向的字符{ {1}}指向(yay,confusion)直到找到空字符,并将所有这些字符打印到屏幕上。 endl
充当换行符和信号以刷新wcout
缓冲区(将其直接打印到屏幕而不是仅保留在内存中)。
答案 1 :(得分:0)
将其分解为最简单的形式; 想想二维数组,
[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
每个元素都是一个表示单个字符的TCHAR元素,每一行都是一个字符串(一个字符数组是一个字符串),最后一个元素以'\ 0'开头(NULL终结符)
**ilist = argv
表示ilist指向矩阵的第一个元素,即[0,0]
*ilist
表示完整的行,因此使用cout打印它将打印出一行包含在该行中的字符串
++ilist
将指针递增到下一行的第一个元素(因此将它递增一次会使ilist指向[1,0])
ilist != NULL
检查我们是否已到达矩阵的末尾,因此循环执行直到未到达矩阵的末尾,最后一行(第5行之后的行,包含NULL,从而传达结束)数组)
(内存中的实际数组表示与上面的不一样,它几乎相似,一行中元素的数量根据字符串长度而变化,例如假设参数为:“这是一个字符串”,它可以表示为:
[0]->[T] [h] [i] [s] [\0]
[1]->[i] [s] [\0]
[2]->[a] [\0]
[3]->[s] [t] [r] [i] [n] [g] [\0]
[4]->NULL
记住'\0'
是空终止符,它用于表示这是字符串的结尾)