Range Based For Loop C++ Array Assignment

For loop vs For each loop for arrays

What is the difference between for loops and for each loops regarding with using arrays? Can you give example of how for each loop can be used ? What are the advantages ?

@kevinkjt2000 This an example of a range-based for loop (which someone referred to it as for each loop).






I don't know where exactly I can use it ? and what is the advantage of it comparing to a regular for loop?
Kourosh23, the problem with your code is that arrays don't have range-for loops. Range-for loops approximately equals to this while compile:

Since arrays don't have begin() and end(), no corresponding code can be generated for range-for loop.
@BlueSquirrelJQX
Using the range based for loop is fine with arrays.

Generally range based for loops can be used with all containers where begin()/end() can be used (either as member or as free functions) which includes arrays.

what is the advantage of it comparing to a regular for loop?
It is shorter. There is no more secret behind.
@BlueSquirrelJQX , it is mentioned in my book that range-for loops exist like the example that I provided.


@coder777, I heard someone mentioned that this kind of for loop offers a better solution when we do not know how many values the array contains, so we don't know the size of the array which can be a bit frustrating. However, using for each loop can print the values out even if the size is unknown.

I know that you already mentioned "There is no more secret behind" , but does my explanation provide any further clue to what else they might do ?
@Kourosh23: Size of arrays can still be determined by .

The size of the array must be known in order to use it in a range based loop. In other words: You can't do more with a range based loop than a normal loop. Actually a range based loop is more limited.
You could use an ifinite iterator and have a break statement:


Functional programming languages typically do stuff like this and rely on lazy evaluation (such as a in the middle of a loop of infinite values)


Edit: I decided to give another go at this infinite range-based for code after work, so above is my edited example.
Edit 2: I liked this other syntax a bit better even though it made the code longer.
Actually a range based loop is more limited.

But compact and expressive.

Says very clearly that here we do something with each element of range bar.

We can write this loop without digging up how many elements are in that range. The compiler will do it for us. The less we have to write, the less we do make mistakes.


That is not as versatile as the old syntax (although you can do black magic and obscure tricks to defeat the clarity with almost every bit of the language).

To quote http://thbecker.net/articles/rvalue_references/section_04.html
As we all know, the First Amendment to the C++ Standard states: "The committee shall make no rule that prevents C++ programmers from shooting themselves in the foot."
There is nothing wrong with using a range based loop when possible.
@kevinkjt2000,

For your code:




You have given the elements of the array, so doesn't that easily indicate the size of the array?
It does. The compiler counts the elements in the initializer and uses that info to construct the array. The info is available.

Both of these use that info:
Topic archived. No new replies allowed.

In lesson 6.3 -- Arrays and loops, we showed examples where we used a for loop to iterate through each element of an array.

For example:

While for loops provide a convenient and flexible way to iterate through an array, they are also easy to mess up and prone to off-by-one errors.

C++11 introduces a new type of loop called a for-each loop (also called a range-based for loop) that provides a simpler and safer method for cases where we want to iterate through every element in an array (or other list-type structure).

For-each loops

The for-each statement has a syntax that looks like this:

for (element_declaration : array) statement;

When this statement is encountered, the loop will iterate through each element in array, assigning the value of the current array element to the variable declared in element_declaration. For best results, element_declaration should have the same type as the array elements, otherwise type conversion will occur.

Let’s take a look at a simple example that uses a for-each loop to print all of the elements in an array named fibonacci:

This prints:

0 1 1 2 3 5 8 13 21 34 55 89

Let’s take a closer look at how this works. First, the for loop executes, and variable number is set to the value of the first element, which has value 0. The program executes the statement, which prints 0. Then the for loop executes again, and number is set to the value of the second element, which has value 1. The statement executes again, which prints 1. The for loop continues to iterate through each of the numbers in turn, executing the statement for each one, until there are no elements left in the array to iterate over. At that point, the loop terminates, and the program continues execution (returning 0 to the operating system).

Note that variable number is not an array index. It’s assigned the value of the array element for the current loop iteration.

For each loops and the auto keyword

Because element_declaration should have the same type as the array elements, this is an ideal case in which to use the auto keyword, and let C++ deduce the type of the array elements for us.

Here’s the above example, using auto:

For-each loops and references

In the for-each examples above, our element declarations are declared by value:

This means each array element iterated over will be copied into variable element. Copying array elements can be expensive, and most of the time we really just want to refer to the original element. Fortunately, we can use references for this:

In the above example, element will be a reference to the currently iterated array element, avoiding having to make a copy. Also any changes to element will affect the array being iterated over, something not possible if element is a normal variable.

And, of course, it’s a good idea to make your element const if you’re intending to use it in a read-only fashion:

Rule: Use references or const references for your element declaration in for-each loops for performance reasons.

Rewriting the max scores example using a for-each loop

Here’s the example at the top of the lesson rewritten using a for each loop:

Note that in this example, we no longer have to manually subscript the array. We can access the array element directly through variable score.

For-each loops and non-arrays

For-each loops don’t only work with fixed arrays, they work with many kinds of list-like structures, such as vectors (e.g. std::vector), linked lists, trees, and maps. We haven’t covered any of these yet, so don’t worry if you don’t know what these are. Just remember that for each loops provide a flexible and generic way to iterate through more than just arrays.

For-each doesn’t work with pointers to an array

In order to iterate through the array, for-each needs to know how big the array is, which means knowing the array size. Because arrays that have decayed into a pointer do not know their size, for-each loops will not work with them!

Similarly, dynamic arrays won’t work with for-each loops for the same reason.

Can I get the index of the current element?

For-each loops do not provide a direct way to get the array index of the current element. This is because many of the structures that for-each loops can be used with (such as linked lists) are not directly indexable!

Conclusion

For-each loops provide a superior syntax for iterating through an array when we need to access all of the array elements in forwards sequential order. It should be preferred over the standard for loop in the cases where it can be used. To prevent making copies of each element, the element declaration should ideally be a reference.

Note that because for each was added in C++11, it won’t work with compilers that don’t have support for C++11.

Quiz

This one should be easy.

1) Declare a fixed array with the following names: Alex, Betty, Caroline, Dave, Emily, Fred, Greg, and Holly. Ask the user to enter a name. Use a for each loop to see if the name the user entered is in the array.

Sample output:

Enter a name: Betty Betty was found. Enter a name: Megatron Megatron was not found.

Hint: Use std::string as your array type.

1) Show Solution

#include <iostream>

intmain()

{

    constintnumStudents=5;

    intscores[numStudents]={84,92,76,81,56};

    intmaxScore=0;// keep track of our largest score

    for(intstudent=0;student<numStudents;++student)

        if(scores[student]>maxScore)

            maxScore=scores[student];

    std::cout<<"The best score was "<<maxScore<<'\n';

    return0;

}

#include <iostream>

 

intmain()

{

    intfibonacci[]={0,1,1,2,3,5,8,13,21,34,55,89};

    for(intnumber:fibonacci)// iterate over array fibonacci

       std::cout<<number<<' ';// we access the array element for this iteration through variable number

 

    return0;

}

#include <iostream>

 

intmain()

{

    intfibonacci[]={0,1,1,2,3,5,8,13,21,34,55,89};

    for(auto number:fibonacci)// type is auto, so number has its type deduced from the fibonacci array

       std::cout<<number<<' ';

 

    return0;

}

    intarray[5]={9,7,5,3,1};

    for(auto element:array)// element will be a copy of the current array element

        std::cout<<element<<' ';

    intarray[5]={9,7,5,3,1};

    for(auto&element:array)// The ampersand makes element a reference to the actual array element, preventing a copy from being made

        std::cout<<element<<' ';

    intarray[5]={9,7,5,3,1};

    for(constauto&element:array)// element is a const reference to the currently iterated array element

        std::cout<<element<<' ';

#include <iostream>

intmain()

{

    constintnumStudents=5;

    intscores[numStudents]={84,92,76,81,56};

    intmaxScore=0;// keep track of our largest score

    for(constauto&score:scores)// iterate over array scores, assigning each value in turn to variable score

        if(score>maxScore)

            maxScore=score;

    std::cout<<"The best score was "<<maxScore<<'\n';

    return0;

}

#include <vector>

#include <iostream>

 

intmain()

{

    std::vector<int>fibonacci={0,1,1,2,3,5,8,13,21,34,55,89};// note use of std::vector here rather than a fixed array

    for(constauto&number :fibonacci)

        std::cout<<number<<' ';

 

    return0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#include <iostream>

 

intsumArray(intarray[])// array is a pointer

{

    intsum=0;

    for(constauto&number :array)// compile error, the size of array isn't known

        sum+=number;

 

    returnsum;  

}

 

intmain()

{

     intarray[5]={9,7,5,3,1};

     std::cout<<sumArray(array);// array decays into a pointer here

     return0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

#include <iostream>

#include <string>

 

intmain()

{

    conststd::stringnames[]={"Alex","Betty","Caroline","Dave","Emily","Fred","Greg","Holly"};

    std::cout<<"Enter a name: ";

    std::stringusername;

    std::cin>>username;

 

    boolfound(false);

    for(constauto&name :names)

        if(name==username)

        {

            found=true;

            break;

        }

 

    if(found)

        std::cout<<username<<" was found.\n";

    else

        std::cout<<username<<" was not found.\n";

 

    return0;

}

0 thoughts on “Range Based For Loop C++ Array Assignment

Leave a Reply

Your email address will not be published. Required fields are marked *