Reputation: 1
int i, a[7] = {-6, -4, -2, 0, 2, 4, 6};
for (i = 0; i < 4 || a[i]; i++)
putchar('*');
This loop doesn't make sense to me because it prints out 8 *'s. It's for C.
So from what I understand:
0 < 4 || -6
⟶ *
1 < 4 || -4
⟶ *
2 < 4 || -2
⟶ *
3 < 4 || 0
⟶ *
4 < 4 || 2
⟶ *
5 < 4 || 4
⟶ *
6 < 4 || 6
⟶ *
So that's 7 stars so far...After this is it doing
7 < 4 || '\0'
⟶ *
This is a similar question that prints out 5 stars:
int i, a[2] = {-6, -4};
for (i = 0; i < 4 || a[i]; i++)
putchar('*');
Again I don't understand what it's doing on the last time around.
When it gets to 4 < 4 || ?
, shouldn't it break?
Upvotes: 0
Views: 43
Reputation: 8058
An integer is considered "true" if it is nonzero. All the cases in your first example where it gets as far as looking at a[I] have that value nonzero, and anything ored with true is true.
(@CyberSpock spells this out in more detail)
Upvotes: 0
Reputation: 36092
int i, a[7] = {-6, -4, -2, 0, 2, 4, 6};
for (i = 0; i < 4 || a[i]; i++)
If you look at the condition
i < 4 || a[i]
It means that the expression is true if either i
is less than 4 i.e. elements at [0-3] of the array will be true OR if a[i]
is not 0 (a[i]
is the short form for a[i] != 0
)
The array has an element that is zero, it is at a[3] but will anyway be printed because the other part of the or condition is true for that position: i < 4
When dealing with arrays like this it is good to know the size of the array and have that as the max value even if you want to break on a particular value.
int N=sizeof(a)/sizeof(a[0])
or
#define N 7
for (i = 0; i < N && a[i]; i++)
this will prevent you from reading random values from the stack (in this case).
Upvotes: 0
Reputation: 121427
Your code invokes undefined behaviour because the loop condition is bogus and leads to accessing the array beyond its bounds.
Remember there's no bounds check on arrays done by the language or any implicit null at the end of array in C. A lot of invalid code compiles just fine. It's your responsibility as a programmer to ensure your code is valid.
A correct loop condition would ensure the array is not accessed outside it's boundary:
for (i = 0; i < (sizeof a/sizeof a[0]) && a[i]; i++)
putchar('*');
Upvotes: 1
Reputation: 4079
This code has undefined behavior because it will access elements outside the array. You can see this behavior if you change your code to the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, a[7] = {-6, -4, -2, 0, 2, 4, 6};
for (i = 0; i < 4 || a[i]; i++) {
printf("Accessing element: %d\n", i);
putchar('*');
}
}
On my machine I get the following output:
Accessing element: 0
*Accessing element: 1
*Accessing element: 2
*Accessing element: 3
*Accessing element: 4
*Accessing element: 5
*Accessing element: 6
*Accessing element: 7
*Accessing element: 8
*
This is accessing 9 elements (index 8 is element 9 of a zero based index array). Once you have undefined behavior all bets are basically off. It is also possible that the program will loop until it reaches a segmentation fault.
It doesn't break when i == 4
or when i
is greater than 4 because a[i]
is true and therefore i < 4 || a[i]
is also true. a[i]
is true up to the array length and then you access something outside the array (the 8th element, index 7) and then you have undefined behavior.
Upvotes: 2