如何在C和C++中迭代字符串数组

How do I iterate over a string array in C and C++?

本文关键字:迭代 字符串 数组 C++      更新时间:2023-10-16

我发现了在主函数内迭代C风格字符串数组的示例代码,代码运行良好,如下所示:

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

有一部分我不明白:

*iList != NULL

也许有人能给我解释一下这个部分?

C样式字符串也称为以null结尾的字符串。这只是意味着你将实际字符串的字符放在内存中,然后在所有这些字符之后,你就有了null字符。因此,当你想迭代C风格字符串中的所有字符时,你只需要从头开始,一直到达到一个null字符。

然而,在这个特定的示例中,您处理的是字符串的数组,而不仅仅是单个字符串。这意味着argv实际上指向内存中的一个位置,该位置是指针列表的开头。然后,该列表中的每个指针都指向一个C样式字符串。在这个指针数组的末尾,您有一个NULL指针,因此一旦达到该指针,您就对argv中的所有字符串进行了迭代。

让我们逐行来看:

for (TCHAR **iList = argv; *iList != NULL; ++iList)

好吧,这太复杂了。让我们先来看第一个表达式:

TCHAR **iList = argv;

这声明了一个类型为TCHAR**的变量iList。这意味着它是指向TCHAR的指针的指针。它的值指向指针的位置,然后指针指向C样式字符串开头的位置。

*iList != NULL;

这将获取iList所指向的对象,并查看它是否是NULL指针。请记住,iList指向指针,因此目标是不断检查iList指向的指针,直到找到一个实际上不指向任何东西的指针(这就是NULL的意思),然后停止。

++iList

这只是意味着,每次执行for循环的主体时,都会在iList的值上加1。由于iList是指向指针的指针,我们告诉iList指向它之前指向的指针之后的指针。

最后:

wcout << *iList << endl;

这意味着取iList(一个指针,因为iList指向指针)所指向的任何内容,并将其插入wcout中,后跟一个换行符。在这种情况下,插入运算符是聪明的:由于iList所指向的是一个指向字符的指针,它知道将其解释为C样式字符串,因此它会跟随iList所指向的指针所指向的字符(yay,混淆),直到它找到一个空字符,并将所有这些字符打印到屏幕上。endl同时充当换行符和刷新wcout缓冲区的信号(将其直接打印到屏幕上,而不仅仅是将其保存在内存中)。

将其分解为最简单的形式;想想二维阵列,

[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]

每个元素都是表示单个字符的TCHAR元素,每一行都是一个字符串(字符数组是一个串),最后一个元素以"\0"(NULL终止符)开头

**ilist = argv表示矩阵第一个元素的ilist点,即[0,0]

*ilist表示完整的行,因此使用cout打印它将打印出该行中包含的字符串

++ilist增加指向下一行第一个元素的指针(因此增加一次将使ilist指向[1,0])

ilist != NULL检查我们是否已经到达矩阵的末尾,因此循环执行,直到还没有到达矩阵的结尾,最后一行(第5行之后的一行,包含NULL,从而传递数组的末尾)

(内存中的实际数组表示与上面的不同,它几乎相似,一行中元素的数量根据字符串长度而变化,例如,假设参数为:"This is a string",它可以表示为:

[0]->[T] [h] [i] [s] []  
[1]->[i] [s] []  
[2]->[a] []
[3]->[s] [t] [r] [i] [n] [g] []
[4]->NULL

记住''是null终止符,它用于告诉这是字符串的末尾)