Please explain the scope of for loop indices - c++

I just want to confirm a suspicion I have about loop indexes. I am using c++.
I have two for loops in my code. For one I declared my index outside of the loop, i.e
int i;
for(i = 0; i < n; i++){
. . .
}
cout << i <<endl;
And then I have later:
for(int j = 0; j<n; j++){
. . .
}
cout << j <<endl;
In the first case I see that some random number is outputted. In the second case, I get an error message about -fpermissive or something like that. I just want to confirm that the index goes out of scope whenever the loop ends, because that seems to be what is happening.
I was trying to use the index for something later on, I guess I just have to put a second index in the loop to increment as i or j do, and then I can use this value later. i.e.:
int index = 0;
for(int j = 0; j<n; j++){
. . .
index ++;
}
cout << index <<endl;
Would someone confirm this for me?

The first example::
http://codepad.org/L5VErMAh
int main( void )
{
int i, n = 10 ;
for(i = 0; i < n; i++){
// do something useful. . .
}
cout << i <<endl;
return 0 ;
}
Output:: 10
Explanation:: The scope of i and n is global for the for loop. So, they don't go invalid or undefined after the execution of for loop.
The second example:: http://codepad.org/iqNtQ1Ok
int main( void )
{
int n = 10 ;
for(int j = 0; j < n; j++){
// do something useful. . .
}
cout << j <<endl;
return 0 ;
}
Output:: name lookup of 'j' changed for new ISO 'for' scoping
Explanation:: The scope of n is global for for loop but as the j is declared inside the for loop, its scope and lifetime is local for the for loop. That means, the j will be and is destroyed after the execution of for loop. That's why, the error.
The third example:: I think, you must have got the idea that it is pretty same as the first example.
Now for your doubt, "In the first case I see that some random number is outputted." No, that can't happen unless you are doing something wrong inside the for loop. You can post the first case for loop code and we can point you out the error.

In the first case, since j is declared outside the loop, the scope of i is even the outside of the loop. So,
cout<<i<<endl;
prints the value of n. The second case, j is declared in the loop. So the scope of j is only inside the loop; So you get the error.
So the first case itself you can use the value of i at later phases
#include<stdio.h>
main()
{
int i;
for(i=0;i<5;i++)
printf("%d\n",i);
return 0;
}
gave me an output of 5.

well this one will just print n
int i;
for(i = 0; i < n; i++){
//...
}
cout << i <<endl;//prints the value of n
and this one J is declared out of scope
for(int j = 0; j<n; j++){
. . .
}
cout << j <<endl; //the compiler asks: whats a j?
and the last one does the same as the first
int index = 0;
for(int j = 0; j<n; j++){
. . .
index ++;
}
cout << index <<endl;//still prints n

Related

C++ Printing Odd numbers instead of Prime Numbers

I have been working on an assignment question for days and cannot seem to get the correct output (I've tried so many things!) The question is:
Write a program that uses two nested for loops and the modulus operator (%) to detect and print the prime numbers from 1 to 10,000.
I have been doing from 1 to 10 as a small test to ensure its working. I am getting 2,3,5,7,9 as my output, so I know something is wrong. When I increase the number from 10 to 20 it is printing 2 plus all odd numbers. I am including my code below. Thanks!!
int main() {
for (int i=2; i <=10; i++){
for (int j=2; j<=i; j++){
if (i%j==0 && j!=i) {
break;
}
else {
cout<< i <<endl;
break;
}
}
}
}
In addition to Sumit Jindal's answer inner for loop can be done by this way as well:
for(int j=2; j*j<=i ; j++)
If we think about every (x,y) ordered pair that satisfies x*y = i, maximum value of x can be square root of i.
The problem lies in the if-else branch. Your inner loop will be run exactly once because it will break out of the inner loop as a result of your if else branch.
When you first enter the inner loop the value of j is 2. Your condition will test if variable i is divisible by 2. If it is it breaks. Other wise (your else branch) will print the value of i and breaks out.
Hence printing odd numbers.
Break out of the inner loop and check whether j equals i in outer loop. You have to make j available for outer loop.
Your print statement is within the inner loop, and it should not be - it's only a prime if you run all the way through the inner loop without finding a divisor.
As a second point, you only need to check for divisors up to the square root of i, not all the way up to i.
You are breaking the inner loop after the first iteration itself, which is checking if the number(ie i) is different from j and is divisible by 2 or not (since j=2 for the first iteration)
I am getting 2,3,5,7,9 as my output
This is because every odd number fails the if and is printed in else condition
A minor correction in your code, adding a flag. Also you don't need to run the inner loop i times, infact only i/2 times is sufficient. This is simple mathematics, but will save significant number of CPU cycles (~5000 iterations lesser in your case)
#include <iostream>
int main()
{
int n = 10;
for(int i=2; i<=n; i++){
bool isPrime = true;
for(int j=2; j<=i/2; j++){
if(i!=j && i%j==0){
isPrime = false;
break;
}
}
if(isPrime)
std::cout << i << " ";
}
return 0;
}
Another version, if you don't mind output in reverse order.
int n = 10;
for (int i = n; i > 1; --i)
{
int factorCount = 0;
for (int j = 2; j <= n; ++j)
{
if (i % j == 0)
factorCount++;
if (factorCount > 1)
break;
}
if (factorCount == 1)
cout << i << endl;
}
int main() {
for (int i = 2; i <= 100; i++) {
for (int j = 2; j < i; j++) {
if (i%j == 0)
break;
if (j==i-1) // means has never run previous if blog
cout << i << endl;
}
}
return 0;
}

A for-loop without a body in C++

During a test we were asked the following question, What is the C++ program below going to print?.
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++)
cout<<i;
cout<<endl;
}
So i gave my answer as :
1
1
2
1
2
3
1
2
3
4
1
2
3
4
5
1
2
3
4
5
6
That is how i understood it. Later on i typed it in the source code, executed the code and the output was surprisingly :
1
12
123
1234
12345
123456
And then i realised that the inner for loop in the question had no body braces.
So The output of my answer is provided if the code is:
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++) {
cout<<i ;
cout<<endl;} //Note the opening and closing braces and compare with the one above.;
}
What is the main difference between the two programs regarding how they are executed?
What happens in the first for loop above in which the inner loop has no body braces.?
My teacher could not provide me with much assistance, please help.
If you don't specify the scope of the for loop with {} it will assume one instruction scope.
So this code:
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++)
cout<<i ;
cout<<endl;
}
Is equivalent to:
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++) {
cout<<i ;
}
cout<<endl;
}
Same applies to if and other loops. This can be a very hard to find bug sometimes especially if you do something like:
if (condition) ;
do_something();
It will do_somethign regardless of the condition. Thats why I personally try to avoid the if/for's without scope.
Hope this helps.
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++)
cout<<i;
cout<<endl;
}
Is equivalent to:
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++)
{
cout<<i;
}
cout<<endl;
}
So if you indent the program it will look something like this:
for (int j=1;j<=6 ; j++)
{
for ( int i = 1; i<=j ; i++)
cout<<i ;
cout<<endl;
}
What you've got going on here is that the cout << i is the ONLY thing that's exectured by teh inner for loop, this is because there's no braces around the inner for loop, so only th enext statement is executed. It's often done with if statements e.g.
if(isValid == true)
cout << "It's Valid" << endl;
cout << "This isn't part of the if block" << endl;
So the outer loop will add the endl.
It's all to do with variable scope. So the scope of i is the inner loop ONLY, whereas the int j, could be used in the inner loop as well as the outer loop.
Hope that helps a little
the inner loop only runs the line
cout << i;
the line:
cout<< endl;
is executed as part of the outer loop so the answe is
1
12
123
1234
12345
123456
if you don't specify braces for a loop it only executes the next line.
A for loop executes a single statement. Now, that can either be a compound statement (which is a group of statements within braces) or a single statement, which is an expression terminated with a semi-colon.
You're code actually has this shape:
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++)
cout<<i ;
cout<<endl;
}
where the cout<<i is the statement attached to the inner for. Notice how the outer for uses braces ({ and }) to group multiple statements into a compound statement.
Your original code is equivalent to:
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++) {
cout<<i;
}
cout<<endl;
}
1st Scenario
for(int i=1;i<=10;i++) {
for(int j=1;j<=i;j++)
cout<<j;
cout<<endl;
}
for(int i=1;i<=10;i++) {
for(int j=1;j<=i;j++) {
cout<<j;
}
cout<<endl;
}
The code above means the same to the compiler and
will give a output like
112123....Because a for loop without braces will consider only one immediate statement under its block.
2nd ScenarioA code like this (mind the space before i)
for(int i=1;i<=10;i++) {
for(int j=1;j<=i;j++)
cout<<j;
cout<<" "<<i;
cout<<endl;
}
would print
1 1
12 2
123 3
1234 4Because no matter how many statements are there written under a for loop without braces, it will only consider 1 statement only under its block, and i gave the space before i only to explain that the for loop without braces finishes executing the immediate next first then terminates the loop
Hope it helps, any more query? Happy to help :)
If to remove braces in this code snippet
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++)
cout<<i;
cout<<endl;
}
then the outer loop will be equivalent to the following
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++)
cout<<i;
}
cout<<endl;
Or that is the same
for (int j=1;j<=6 ; j++) {
for ( int i = 1; i<=j ; i++) {
cout<<i;
}
}
cout<<endl;
and the output will look like
112123123412345123456
From the C++ Standard (6.5 Iteration statements)
2 The substatement in an iteration-statement implicitly defines a
block scope (3.3) which is entered and exited each time through the
loop. If the substatement in an iteration-statement is a single
statement and not a compound-statement, it is as if it was rewritten
to be a compound-statement containing the original statement. [
Example:
while (--x >= 0)
int i;
can be equivalently rewritten as
while (--x >= 0) {
int i;
}
The example has the same sense if to substitute the while iteration statement for the for iteration statement.

Can't figure out why this output formatting loop is going infinite

My program is supposed to take in a number from user input, determine whether or not it is prime, and then if it is not, output the factors of the entered number, 5 to a line. The 5 to the line part is where everything goes haywire, the loop i wrote should work fine as far as i can tell, however no matter how much i change it around, it does one of two things, 1) goes infinite with either new lines or the first factor, or 2) outputs a line with 5 of each factor. Here's the code:
else
{
cout << "\nNumber is not prime, it's factors are:\n";
for (int x = 2; x < num; x++)
{
factor=num%x;
if (factor==0)
{
int t=0;
cout << x << "\t";
t++;
for (int t; t <= 5; t++) // THE TROUBLE LOOP
{
if(t>=5)
{
t=0;
cout << endl;
}
}
}
}
}
Replace the declaration of t in the loop since you've declared t prior to the loop:
for(; t <= 5; t++)
With int t in the loop declaration you are overriding t as an uninitialized variable that will have a garbage value.
Outside of this problem your loop is infinite since you will be resetting t to 0 whenever it equals 5.
In the for loop change the
int t
to
t=0
it is the
for(int t,t<=5,t++)
the int t part in particular that is causing the issue.
#GGW
Or this:
int t = 0;
//some code
for(t; t <= 5; t++)
//more code

Nested for loop filling an array

I am trying to create a nested for loop that fills in values in an array from 1 to 20.
IE) array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
int array[20];
for(int i = 0; i<21; i++)
{
for(int j =1; j<21; j++)
{
array[i] = j;
cout<< array[i];
}
}
Supposedly, The array index should count up with "i", and should be equated to "j" which is also counting up. The array element is printed to the console as it is filled.
I expected 1 -20 to be printed out once, but when I run the code, 1-20 prints out multiple times. Can someone tell me the problem? Thanks!
Your outer for loop runs 21 times, your inner for loop runs 20 times each of the outer for loop iterations, so you have a total of 21 * 20 = 420 print statements.
You can simply do
for(int i = 0 ; i < array.length ; i++)
{
array[i] = i + 1;
cout << array[i] << endl;
}
If you look at your array when you're done, it will also be just a series of 20s. The first loop is saying "do this 20 times" and then the second loop is saying "set and print the value of that array element 20 times." What you need to do is include a check for whether you're assigning the correct j value to the correct array[i] value, and only set the value in that case. Something like:
if (j == i + 1) array[i] = j;
Why do you need a nested loop?
for(int i = 0; i<20; i++)
{
array[i] = i + 1;
cout<< array[i];
}
yes, you have two loops when you only need one:
for(int i = 0; i<21; i++)
{
array[i] = i + 1;
cout<< array[i];
}
In order to fill the array and to print the result you just need two simple for loops
for(int i = 0; i<20; i++)
{
array[i] = j;
}
for(int j =0; j<20; j++)
{
cout<< array[i];
}
The nested loop that you created above will do exactly what you described.
For each loop of the outer for loop it will execute the full 20 loops of the inner loop.
so in total you will execute it 21 * 20 times.
Also be careful with your index. You want to start with int i = 0 to i < 20 which loops exactly 20 times.
I don't know why you are attempting to print a single element in you array, but it isn't necessary to use nested loops here; in fact, a loop isn't required at all:
// vector version
std::vector<int> vec(20);
std::iota(vec.begin(), vec.end(), 1);
// array version
int arr[20];
std::iota(std::begin(arr), std::end(arr), 1);
If you want to print out the whole array after you've initialized it:
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, "\n"));
I see a lot of people answered about this question, so I will not repeat them, I'll just mention that you are writing outside the array size.
if you have int array[20], you should loop
for(int i = 0; i<20; i++)
the last index is 19
The outer loop 21 times repeats the inner loop
for(int i = 0; i<21; i++)
{
for(int j =1; j<21; j++)
{
array[i] = j;
cout<< array[i];
}
}
The inner loop does the same operation that is assigns elements of the array sequantial numbers. Moreover your code has a bug because due to the outer loop youare trying to access element array[20] that does not exist, because if the array was defined as
int arrat[20];
then the valid indicies are 0 - 19.
That do not bother about writing correctly required loop or loops you could use standard algorithm std::iota
For example
#include <iostream>
#include <numeric>
#include <iterator>
#include <algorithm>
int main()
{
const size_t N = 20;
int array[N];
std::iota( std::begin( array ), std::end( array ), 1 );
std::copy( std::begin( array ), std::end( array ), std::ostream_iterator<int>( std::cout, " " ) );
}
Or instead of the algorithms you could use the range based for statement. For example
#include <iostream>
int main()
{
const size_t N = 20;
int array[N];
int i = 1;
for ( int &x : array )
{
x = i++;
std::cout << x << ' ';
}
}
If you really want to use nested solution, (for example game board coordinates) then this is my solution.
// nesting arrays for example game board coordinates
#include <iostream>
int main(){
int x = 20;
int y = 40;
int array[x][y];
// initialize array of variable-sized.
for(int i = 0; i < x; ++i){
for(int j = 0; j < y; ++j){
array[i][j] = 0; // or something like i + j + (i * (y-1)) if you wish
// and send it to cout
std::cout << array[i][j] << " ";
}
std::cout << std::endl;
}
//notice, that when sent to cout like this, x and y flips on screen, but
//logics of coordinates is ok
// and then do something usefull with it
return EXIT_SUCCESS;
}
int size = 20;
for (int i = 0; i < size; i++)
{ int array[i];
array[i] = i + 1;
cout << array[i]<< " ";
}
You could populate your array with 1 for loop, and gauge the size of your array like stated above.

What does it mean when the first "for" parameter is blank?

I have been looking through some code and I have seen several examples where the first element of a for cycle is omitted.
An example:
for ( ; hole*2 <= currentSize; hole = child)
What does this mean?
Thanks.
It just means that the user chose not to set a variable to their own starting value.
for(int i = 0; i < x; i++)
is equivalent to...
int i = 0;
for( ; i < x; i++)
EDIT (in response to comments): These aren't exactly equivalent. the scope of the variable i is different.
Sometimes the latter is used to break up the code. You can also drop out the third statement if your indexing variable is modified within the for loop itself...
int i = 0;
for(; i < x;)
{
...
i++
...
}
And if you drop out the second statement then you have an infinite loop.
for(;;)
{
runs indefinitely
}
The for construct is basically ( pre-loop initialisation; loop termination test; end of loop iteration), so this just means there is no initialisation of anything in this for loop.
You could refactor any for loop thusly:
pre-loop initialisation
while (loop termination test) {
...
end of loop iteration
}
Some people have been getting it wrong so I just wanted to clear it up.
int i = 0;
for (; i < 10; i++)
is not the same as
for (int i = 0; i < 10; i++)
Variables declared inside the for keyword are only valid in that scope.
To put it simply.
Valid ("i" was declared outside of the loops scope)
int i = 0;
for (; i < 10; i++)
{
//Code
}
std::cout << i;
InValid ("i" does not exist outside the loop scope)
for (int i = 0; i < 10; i++)
{
//Code
}
std::cout << i;
It means that the initial value of hole was set before we got to the loop
That means loop control variable is initialized before the for loop .
For C code,
int i=0;
for( ; i <10 ; i++) { } //since it does not allow variable declaration in loop
For C++ code,
for(int i=0 ; i <10 ; i++) { }
You could omit any of the parameters of a for loop.
ie: for(;;) {} is about the same as while(true) {}
It means that the initial value of hole was set before we got to the loop.
Looks like a list traversal of some kind.
Suppose you wanted to
for (hole=1 ; hole*2 <= currentSize; hole = child)
But the value of hole just before the for loop was already 1, then you can slip this initilization part of the loop:
/* value of hole now is 1.*/
for ( ; hole*2 <= currentSize; hole = child)