使用指针循环遍历数组

non*_*one 1 c++ pointers

C ++中的以下程序输出的输出超出我的预期。谁能解释为什么会这样?该程序尝试使用指针遍历整数数组,并沿途打印每个值。

#include <cstdio>
using namespace std;

int main(int argc, char **argv) {
    puts("hi");
    int ia[5] = {1,2,3,4,5};
    for (int *p = ia; *p; ++p) {
        printf("Char is: %d\n", *p);
    }
    return 0;
}

/*
 hi
 Char is: 1
 Char is: 2
 Char is: 3
 Char is: 4
 Char is: 5
 Char is: 32767
 Char is: -811990796
 Char is: -133728064
 Char is: 1606416320
 Char is: 32767
 Char is: -1052593579
 Char is: 32767
 Program ended with exit code: 0
*/
Run Code Online (Sandbox Code Playgroud)

Pau*_*ney 5

您将需要有一个0 / NULL值才能停止,目前还没有。

您的循环条件将允许迭代,直到获得一个值为false(即0)的值,并且数组不包含该值,因此您的迭代将继续超出数组的边界,并在访问内存时退出它不应该。

有几种解决方法。您可以在数组末尾添加0。

#include <cstdio>
using namespace std;

int main(int argc, char **argv) {
    puts("hi");
    int ia[] = {1,2,3,4,5, 0};
    for (int *p = ia; *p; ++p) {
        printf("Char is: %d\n", *p);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题是您现在不能在数组中使用0,否则它将提前终止。

给定数组长度,更好的方法是预先计算要停止的地址。该地址位于阵列末尾。

#include <cstdio>
using namespace std;

int main(int argc, char **argv) {
    puts("hi");
    int ia[] = {1,2,3,4,5};
    int* end = ia + 5;
    for (int *p = ia; p != end; ++p) {
        printf("Char is: %d\n", *p);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,我们正在走向标准库迭代器使用的方法。现在,模板可以推断出数组的大小。

#include <iterator>
...

for (auto it = std::begin(ia); it != std::end(ia); ++it) {
    printf("Char is: %d\n", *it);
}

...
Run Code Online (Sandbox Code Playgroud)

最后,基于范围的还支持数组。

for (auto i: ia)
{
    /* do something */
}
Run Code Online (Sandbox Code Playgroud)

  • 甚至对于范围:`for(int e:ia){/*..*/}`。 (2认同)