A for-loop without a body in C++ - 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.

Related

Can I use 2 loop statement in one loop?

is this loop statement is correct?
if not correct then what alternative way?
I am trying to o(n) loop statement like this-
for(int i=0 ; i<n ; i++ , j=n ; j<n*2 ; j++){
continue;
}
The construct is wrong, you cannot you two loops in one construct, but you can have more than one variable controlling the iteration.
For example, you can have
Two (or more) variables, i and j, initialized with certain values.
A loop controlling statement, involving operation and condition check on i and j (and others, if defined).
Finally, you can control the increment or decrement of i and j (and others, if defined).
A sample construct can be:
for (int i = 0, j = n; i < n && j < n * 2; ++i, ++j)
|^^^^^^^| -------- variable modification
| | |^^^^^^^^^^^^^^^^^| ---------------- loop condition
|^^^^^^^^^^^^^^^|--------------------------------------- initialization
What you seem to want is something like:
for (int i = 0, j = n; i < n && j < n * 2; ++i, ++j)
{
continue;
}
To help you better understand what I did and why, and how you can do such transformations in the future, you need to understand how a for loop is really handled by the compiler: As a special while loop.
For example, if you have
for (a; b; c)
{
d;
}
then that's equivalent to this:
{
a;
while (b)
{
d;
c;
}
}
If we take what you (probably) want, in the form of a while loop then it would be
{
int i = 0, j = n; // a in my example above
while (i < n && j < n * 2) // b in my example above
{
continue; // d in my example above
++i, ++j; // c in my example above
}
}
Now it's easy to translate it to the for loop I showed initially.
As noted in a comment, the while loop shown here is a little misleading, as it won't actually do the increment. But then I assume your real loop doesn't have an unconditional continue statement as the only statement in the body. That would make the loop rather meaningless. However the principle is still valid, even if the example isn't.
for(int i=0 ; i<n ; i++ , j=n ; j<n*2 ; j++){
continue;
}
The above code is wrong
but it can be written as
for(int i = 0 ,j = n; i < n ,j < n * 2; i++ ,j++)
The above code is correct
i=0 and j=n is initialization
i<n and j<n*2 is loop condition
i++ and j++ is incrementation

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;
}

Please explain the scope of for loop indices

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

C++: Number Arranging Program Not Working Properly

I have tried making a program to sort numbers of an array.
I have done my best but there is this problem: Although I do a loop to swap the numbers and arrange them, when I output the array, nothing changes and the array remains the same.
The code will make everything clearer
This is the main function:
int main(){
int arr[10];
//For loop to get from user numbers to be put into the array
for ( int i = 0; i<10; i++){
cout << "Enter the number to be recorded: ";
cin >> arr[i];
cout << endl;
}
// Set counter n to 0 ( counts numbes of number swaps)
int n = 0;
do {
//re sets counter to 0
n=0;
//Check the entire loop if arr[i] bigger than arr[i+1] and swaps their values if true then adds 1 to n
for ( int i = 0; i>9; i++){
if(arr[i]>arr[i+1]){
swap(&arr[i], &arr[i+1]);//swaps by sending the addresses of the two array elements the pointers in the swap function
n++;
}
}
}while(n>0); // if counter = 0 then end (therefore the numbers are arranged correctly since no swapping happened)
cout << "The numbers ordered are:\n\n";
// Loop to output the arranged array
for (int i =0; i<10; i++){
cout << arr[i] << ", ";
}
cout<<endl;
system("PAUSE");
return 0;}
This is the swap function:
void swap ( int *p, int *t){
int temp;
temp = *p;
*p = *t;
*t = temp;}
I hope you guys can help me with my problem here and tell me what's wrong with this code
Thank you all
Look closely at your for loop...its contents will never be executed.
for ( int i = 0; i>9; i++){ ... }
The condition i>9 should be i<9.
for ( int i = 0; i>9; i++){
^^^
here is your problem
you have initialized the i to the 0 and checking the condition is that if i is greater than 9 which is not never true so the condition of the for loop is false and so it will be terminated
it should be
for( int i = 0; i<9; i++) than the
result
i=0 condition i<9 true { come in the function body}
i=1 condition i<9 true { come in the function body}
.
.
.
i=8 condition i<9 true { come in the function body}
i=9 condition i<9 false { }

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)