简体   繁体   中英

C++ basics: ranged based for-loop and passing C-style arrays to functions

I'm trying to learn C++ but I just can't wrap my head around this code here, despite spending a good amount of time searching for an answer:

#include <iostream>

void printArray1(int (&array)[3]) {
    for(int x : array)
        std::cout << x << " ";
}

void printArray2(int array[]) { 
    for(int x : array) // compiler error, can't find begin and end
        std::cout << x << " ";
}

int main() {
    int a[3] = {34,12,88};

    for(int x : a)
        std::cout << x << " ";
    std::cout << std::endl;

    printArray1(a);
    printArray2(a);
    std::cout << std::endl;

    return 0;
}

In printArray1, we are receiving a parameter that is a reference to an array of size 3. Does this mean we are receiving the address of the entire array or are we just receiving an address to the first element in the array of size 3? Also, how is this parameter then passed to the loop?

In printArray2, we are receiving a pointer to the first element in the array, correct? In other words, we are also receiving an address just like in printArray1? Thus, the ranged-based for-loop in this function will not compile because we have no size data for the array, right?

Finally, when we attempt to print with the ranged-based for-loop in main, what exactly are we passing to the loop? Is it a pointer to the first element in the array here, and if so, why does it compile if the for-loop in printArray2 did not accept the pointer?

My understanding of C++ is still quite elementary so I really appreciate the help, thank you!

The range-based for loop works for all types that can be used with std::begin and std::end .

Arrays and pointers are not the same. An array has a fixed size, a pointer does not. Hence std::begin and std::end work for arrays - but not for pointers. That also explains why the range-based for loop works for one, but not the other.

Arrays may also decay to pointers. This happens, for example, when passed to functions that take a pointer parameter. Or, when passed to functions which take an indeterminate-sized array parameter (which is effectively the same as a pointer parameter). When that happens, size information is lost again.

So it depends on how you define the function. The first function takes an array, the second a pointer. That's why the first preserves size information and the loop works.

However, it limits what the function can take. The second function can take an int b[2] , while the first cannot.

In the [3] case, the function knows how big the array is from its type. A reference is often implemented as a pointer to the referred to thing, but in C++ great lengths are gone through to leave that an implementation detail (which sometimes enables optimizations). References are aliases for data elsewhere, subly different than pointers (which are like postal addresses). Iteration is easy when the compiler has the length, and C++ does the right thing.

In the [] case, this is C style syntax. It is not a reference. It means the same as int * array . The size of the array is neither part of tue compile time type (within the function), nor runtime state (which is a single int pointer). Clearly iteration is impossible without the length.

According to cppreference about arrays and Ranged-based for loop

In printArray1 , the array argument is an array of int references which will each one reference the first 3 values of the array that is passed as an argument.

In printArray2 , the array argument is a pointer than points to the first value of the array that is passed as an argument. With it, you can access all values of the array.

Finally, it is not a pointer but just a reference for the a array. In that particular case, what is important to know is that for each iteration, a copy of the iterated value will be performed to the x variable. If you want to prevent all those copies from happening, you should declare a reference instead.

Example:

for(int &x : a)
    std::cout << x << " ";

Btw, you should also take a look at the array container , which is the modern-style array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM