除了main
函数中的第二行:int* end = array+5;
,我了解它的大部分工作原理。该行如何工作?
#inlcude <iostream>
int main()
{
int array[] = {10, 20, 29, 200, 2};
int* end = array+5;
for(int* it = array; it != end; ++it)
{
std::cout << *it << std::endl;
}
}
应该只打印列表中的每个元素。
答案 0 :(得分:9)
it != end;
表示它到达了位置[5],位于最后一个(4)之后。
int* end = array + 5;
简单地创建一个指向[5]位置的变量。
它可以工作,但是更干净,更安全的版本是:
for(int i = 0 ; i < 5 ; i++)
{
std::cout << it[i] << std::endl;
}
当然,您可以将硬编码5替换为sizeof(array)/sizeof(int)
,或者甚至更好地使用std :: array。
std::array arr<int,5> = {10, 20, 29, 200, 2};
for(int i = 0 ; i < arr.size() ; i++)
{
std::cout << arr[i] << std::endl;
}
或
std::array arr<int,5> = {10, 20, 29, 200, 2};
for(auto& it : arr)
{
std::cout << it << std::endl;
}
后一种形式与普通原始数组一样快,但更安全。
答案 1 :(得分:7)
变量array
类似于指向包含数据的内存开头的指针。
array
的长度为5
,因此在开始处加上5可以使结尾处的位置为1。
start --|
10, 20, 29, 200, 2, (out of array)
|--- +5 -----------^
条件it != end
检查循环是否没有超出范围。
答案 2 :(得分:2)
对于任何数组或指针a
和索引i
,表达式a[i]
等于*(a + i)
。加上数组衰减(这意味着array
等于&array[0]
)意味着array + 5
将等于&array[5]
。
因此,您的循环从&array[0]
(等于array
)到一个&array[4]
(包括)循环。循环遍历array
的所有五个元素,使it
依次指向每个元素或数组。
答案 3 :(得分:2)
要了解int* end = array+5;
,应该知道如何为int array[] = {10, 20, 29, 200, 2}
布置存储器。下面代表了相同的内容,以便更好地理解。地址以十进制和十六进制给出,以便于执行算术运算。
Address table
-----------------------------------------------------------
array ===>| 100 | 104 | 108 | 112 | 116 | 120 | -----> DECIMAL
| 0x100 | 0x104 | 0x108 | 0x10C | 0x110 | 0x114 | -----> HEXADECIMAL
-----------------------------------------------------------
| | | | |
10 20 29 200 2
'array' will be pointing to 0x100
语句int* end = array + 5;
被编译为与int* end = (array + (sizeof(int) * 5));
等效的代码
因此它被评估为int* end = (0x100 + (4 * 5)) = 0x114(decimal equivalent 120);
,这是最后一个元素旁边的地址。因此end
将指向最后一个元素的旁边。
重要的是要记住,要从数组的基地址中增加或减去的值始终取决于您所用的数据类型int
,并且假设sizeof(int)
为{{1} }。
另一方面,数据类型为arr [index];被评估为4 bytes
。
答案 4 :(得分:0)
array + 5
等效于&array[5]
。
由于示例代码中的array
是由五个元素组成的数组。
int array[] = {10, 20, 29, 200, 2};
初始化
int* end = array+5;
使end
成为指向数组末尾以及循环中结束条件的指针的指针
for(int* it = array; it != end; ++it) { std::cout << *it << std::endl; }
表示一旦it
指向数组末尾(在您的示例中,它指向array[5]
),循环结束。在C ++中,这非常好,因为允许计算指向数组末尾的指针,或者将其与指向该数组元素的其他指针进行比较。但是,取消引用此类指针(例如,在您的示例中,使用该指针访问array[5]
的值)会导致未定义的行为。
在C ++ 11和更高版本中,如果函数std::begin()
和std::end()
(来自标准头文件<iterator>
)具有数组参数,则返回第一个元素的地址,并返回-过去的最后一个元素。因此,对于array
具有五个元素,您的代码在功能上等效于;
int *end = std::end(array);
for(int *it = std::begin(array); it != end; ++it)
{
std::cout << *it << std::endl;
}
它也等同于更简洁,并且由于不易出错,因此通常被首选;
for (const auto &element : array) // const since the loop body doesn't change the array
{
std::cout << element << std::endl;
}