您能否在此程序中解释array + 5的目的?

时间:2019-07-06 23:23:34

标签: c++ arrays pointer-arithmetic

除了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;
    }
}

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

5 个答案:

答案 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;
}