您可以在此程序中解释Array 5的目的吗?

Can you explain the purpose of array+5 in this program?

本文关键字:Array 解释 程序      更新时间:2023-10-16

我了解其中大多数的工作原理,除了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;
    }
}

它应该只打印列表中的每个元素。

it != end;

表示它到达位置[5],这是最后一个(4(之后的位置。

int* end = array + 5; 

简单地创建一个指向[5]位置的变量。

它有效,但是更干净,更安全的版本是:

for(int i = 0 ; i < 5 ; i++)
{
    std::cout << it[i] << std::endl;
}

当然,您可以用sizeof(array)/sizeof(int)替换硬编码5,或者更好地使用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;
 }

后者的形式与普通的原始数组一样快,但是更安全。

变量array就像指向包含数据的内存开始的指针。

array的长度为5,因此在开始时将5添加到一个末端的位置。

start --|  
       10, 20, 29, 200, 2, (out of array)
        |--- +5 -----------^

条件it != end检查循环是否不超出边界。

对于任何数组或指针a和索引i,表达式a[i]完全等于*(a + i)。与数组衰减一起(例如,array等于&array[0](意味着array + 5等于&array[5]

因此,您的循环从&array[0](array等于(到一个&array[4](包含在内(。该循环在array的所有五个元素上都迭代,将it点指向每个元素或数组。

要了解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)4 bytes


在旁注,datatype arr [index];评估为*(arr + (sizeof(datatype) * index))

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>(如果给出了数组参数,请返回第一个元素的地址和一个past-the-last元素的地址。因此,您的代码在功能上等效,对于具有五个元素的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;
}