C++ 使用指针循环遍历数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41687921/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Looping through array using pointers
提问by none
The following program in C++ prints more output than I expected. Can anyone explain why this has happened? The program attempts to use pointers to loop through the integer array, printing each value along the way.
以下 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
*/
回答by Paul Rooney
You will need to have a 0/NULL value to stop at, currently you do not.
您需要有一个 0/NULL 值才能停止,目前您不需要。
Your loop condition will allow iteration until you get a value that evaluates to false (i.e 0) and your array does not contain that, so your iteration will continue on past the bounds of the array and will at some point exit when it access some memory its not supposed to.
您的循环条件将允许迭代,直到您得到一个评估为假的值(即 0)并且您的数组不包含该值,因此您的迭代将继续超过数组的边界,并在访问某些内存时在某个时候退出它不应该。
There are several ways to fix it. You can add a 0 to the end of the array.
有几种方法可以修复它。您可以在数组末尾添加 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;
}
Issue with this is that you now cant use 0 in your array, or it will terminate early.
问题在于您现在不能在数组中使用 0,否则它将提前终止。
A better way would be to pre calculate the address at which to stop, given the array length. This address is one off the end of the array.
给定数组长度,更好的方法是预先计算停止的地址。该地址位于数组末尾。
#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;
}
Now we are getting towards the method used by standard library iterators. Now templates can deduce the size of the array.
现在我们正在研究标准库迭代器使用的方法。现在模板可以推断数组的大小。
i.e.
IE
#include <iterator>
...
for (auto it = std::begin(ia); it != std::end(ia); ++it) {
printf("Char is: %d\n", *it);
}
...
and finally, range based for also supports arrays.
最后,基于范围的 for 也支持数组。
for (auto i: ia)
{
/* do something */
}
回答by R Sahu
Can anyone explain why this has happened?
谁能解释为什么会这样?
You are accessing the array out of bounds. Your program has undefined behavior.
您正在访问数组越界。您的程序有未定义的行为。
The line
线
int ia[5] = {1,2,3,4,5};
creates an array with exactly 5 elements. Accessing *p
after you have accessed the last element of the array is not good.
创建一个正好有 5 个元素的数组。访问*p
您访问数组的最后一个元素之后也不好。
You can use:
您可以使用:
for (int *p = ia; p != std::end(ia); ++p) {
to make sure that you don't access the array out of bounds.
以确保您不会越界访问数组。
You will need to add:
您需要添加:
#include <iterator>
to use std::end
.
使用std::end
.
回答by artm
Alternatively use sizeof()
operator to determine the number of elements:
或者使用sizeof()
运算符来确定元素的数量:
for (int *p = ia; p < ia + sizeof(ia)/sizeof(*ia); ++p) {
printf("Char is: %d\n", *p);
}
回答by Raindrop7
in fact the condition:
事实上条件:
for( ; *p; )//...
will check whether the value in the address is equal to 0 or not so it stops only if the value is zero and of course this is not what you wanted; you wanted to increment the address until the last element but your code checks the value inside the address not the address itself morever the address after the lat element is not NULL.
将检查地址中的值是否等于 0,因此只有当值为零时它才会停止,当然这不是您想要的;您想增加地址直到最后一个元素,但您的代码检查地址内的值而不是地址本身,而且 lat 元素之后的地址不为 NULL。
to solve your problem you can count how many elements in the array and then inside the loop increment the pointer accordingly:
要解决您的问题,您可以计算数组中有多少个元素,然后在循环内相应地增加指针:
#include <cstdio>
using namespace std;
int main(int argc, char **argv) {
puts("hi");
int ia[5] = {1,2,3,4,5};
int* end = &ia[0] + 4;
for (int *p = ia; p <= end; ++p) {
printf("Char is: %d\n", *p);
}
return 0;
}