-4

I am taking a course on edx.org Introduction to C++ by Microsoft. I get unwanted output when looping through a single dimensional array. The code is below.

<#include <iostream>

int main() {
int arrayName[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 1; arrayName[i] <= 20; i++) {
   std::cout << i << std::endl;
}

The output of this is:

1
2
3
4
5
6
7
8
9
10
11 

Where does the 11 come from? And, if I make i=0, it also prints a 0. How does it print more than 10? And, when I try to change arrayName[10] to arrayName[9], I get a compiler error that there are too many initialized values:

int arrayName[10] = { 1,2,3,4,5,6,7,8,9,10 };

do {
    std::cout << i << std::endl;
    i++;
} while (arrayName[i] < 5);

The output is:

12
13
14
15
16
17
18

That do-while loop outputs 7 integers that I did not specify to be included in the arrayName[] array.

I don't know what I am doing wrong or what I am not understanding.

Please help. Thank you!

host_255
  • 361
  • 2
  • 7
  • 18
  • 2
    Accessing an array index that is outside of the array is undefined behavior. You might get 11 or 34000 or -21938... you get the idea. In short, you should not do this. Instead, change your for loop to only loop until the end of the array. – Joel Cornett Jan 04 '17 at 23:04
  • 1
    Also, arrays are indexed by 0, not 1, so `arrayName[0]` gives you the first element, while `arrayName[1]` actually gives you the second element. (And of course `arrayName[arraySize - 1]` gives you the last element). – Joel Cornett Jan 04 '17 at 23:05
  • Trying to access past the end of an array is undefined behavior. Although it probably has a completely rational explanation (for instance, you may be reading array index `i` after an increment when you access element at index ten) ultimately the exercise leads to nowhere. The proper way to deal with UB is eliminating it. – Sergey Kalinichenko Jan 04 '17 at 23:06
  • `arrayName[i] <= 20` when this condition in your program will be realized? – Raindrop7 Jan 04 '17 at 23:14
  • I'm voting to close this as "too broad", as my impression of the question is "Explain arrays, comparisons, and for loops" – Drew Dormann Jan 04 '17 at 23:17
  • @host_255 if you did write this code: `arrayName[i] <= 20`, can you tell us what *you* think it means? – Drew Dormann Jan 04 '17 at 23:18
  • "And, if I make i=0, it also prints a 0" ... "outputs 7 integers that I did not specify to be included in the arrayName[]" Take a close look at your own code. `cout << i` You're outputting the value of the integer index `i` itself, not the value from the array at position i, which would be `arrayName[i]`. – TheUndeadFish Jan 04 '17 at 23:33
  • @George `arrayName[10]` does not exist at all, it's not uninitialized and doesn't contain anything – M.M Jan 05 '17 at 04:13
  • @M.M Ah yes, thanks for pointing that out! – George Jan 05 '17 at 08:31

2 Answers2

3

First, note that arrays in c++ start at index 0. So in int arrayName[3] = {10, 42, 88}; then arrayName[1] is 42, not 10. That means the last element in this array is int arrayName[2]. There is no element at index 3.

Your array only contains 10 elements (indices 0 to 9). The standard does not specify what happens when you access an element past the end of an array, anything can happen. In your case, arrayName[10] and arrayName[11] happens to give you something less than or equal to 20, and then arrayName[12] gave you something greater than 20, ending the loop. If you try it on another computer, or even at a different time, the results will vary. It might also crash (this is the best case scenario).

See this answer for more information on undefined behavior.

Community
  • 1
  • 1
François Andrieux
  • 28,148
  • 6
  • 56
  • 87
  • @François_Andrieux Very cool. I set `i=1` in that case on purpose, because the output would then start at 1, instead of 0. I didn't the the C++ standard handles it that way. I just tried changing `<20` to `<10` and set `i=0`, but it prints `0,1,2,3,4,5,6,7,8`. `<=10` prints `0...8,9,10,11', `<=9` prints `0...8`. How do I get it to output the values I initialized, `{ 1,2,3,4,5,6,7,8,9,10 }`? – host_255 Jan 05 '17 at 03:25
  • @host_255 If you want to simply print all the values, then iterate as long as `i < 10` (where 10 is the size of your array). `for (int i = 0; i < 10; i++)` – François Andrieux Jan 05 '17 at 03:29
  • @François_Andrieux The for loop does loop through an array. I found an answer and posted it and it printed all of the items in the array. I would like a way to control how many iterations, though. Maybe you can help with that? – host_255 Jan 05 '17 at 04:06
  • @host_255 I do not understand the question in your last comment. In the loop `for (int i = 0; i < 10; i++)` the number 10 is how many iterations. `for (int i = 0; i < n; i++)` will do n iterations. – François Andrieux Jan 05 '17 at 04:08
  • @François_Andrieux What I meant was that I initialized an array, and want to iterate through it and print its values with a for loop. You just wrote `for (int i = 0; i < n; i++)`, is `n` substituted with the array, such as `for (int i = 0; i < arrayName[10]; i++)`? – host_255 Jan 05 '17 at 16:20
  • @host_255 No, `n` is substituted for the number of iterations you want. To iterate 4 tiems `for (int i = 0; i < 4; i++)`. Your loop body will execute 4 times with `i` taking the values 0, 1, 2 then 3. `int i = 0` means `i` starts with the value 0. `i < 4` means to loop *as long as* `i` is less than 4. `i++` means `i` should be incremented after each loop. – François Andrieux Jan 05 '17 at 16:21
  • @François_Andrieux I think I figured it out based on what you said: `int array1[] = {1,2,3,4,5}; for {i=0;i<5;i++){int arrayElements=array1[i]; std::cout< – host_255 Jan 05 '17 at 17:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/132422/discussion-between-francois-andrieux-and-host-255). – François Andrieux Jan 05 '17 at 17:10
-1

I finally found this: Correct way of loop through the C++ arrays, answer by https://stackoverflow.com/users/1619294/mark-garcia.

Changed my code to:

std::cout << "Looping through arrayName3 with std::array and letting the compiler determine how many objects to print:" << std::endl;
// Need to #include <array>
std::array<int, 10> arrayName3 = { 1,2,3,4,5,6,7,8,9,10 };
for (const auto& i : arrayName3) // Range-for
{
    std::cout << i << std::endl;
}

The output was what I wanted:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

This let's the compiler know it is deciding what to output. It would be great to know how to change this to control how many indices to loop through.

Community
  • 1
  • 1
host_255
  • 361
  • 2
  • 7
  • 18