Semicolon - How is messing with this exercise - c

I know that I shouldn't put semicolon after a loop. But I am learning and accidentally I inserted one. And I wanted to know exactly what is happening with my error. So next time something similar happens, I know the source of the mistake.
In the following code below, in this portion of the code:
triangularNumber = 0;
for ( n = 1; n <= number; ++n )
;
I accidentally inserted a semi colon after the for loop. When I execute the entire code, it prompts the user to insert a number for calculating a TriangularNumber. But with the semicolon the result is wrong. For example, when I insert 10, the answer should be 55, but with the semicolon error it delivers to me 56. I wanted to understand why 56.
The complete code is below:
#include <stdio.h>
int main(void)
{
int n, number, triangularNumber, counter;
for(counter = 1; counter <=5; counter++)
{
printf("What Triangular Number do you want?");
scanf("%i", &number);
triangularNumber = 0;
for ( n = 1; n <= number; ++n )
**;**
triangularNumber += n;
printf("Triangular number %i is %i\n\n", number, triangularNumber);
}
return 0;
}

The other answers are all good, but to answer your question about why you get the specific number that you do (which would be 11 when you enter 10, not 56), it's because this:
for ( n = 1; n <= number; ++n )
;
does essentially nothing except loop until n is exactly 1 more than number, so when number is equal to 10, n will equal 11.
Then, this:
triangularNumber += n;
just sets triangularNumber to 11, since before the loop you set it to 0, so when it's sitting outside the loop as it does with the semi-colon there, triangularNumber += n; is basically equivalent to triangularNumber = n;.
Incidentally, if you'd defined n within the for loop, instead of at the beginning of main(), like so (you may need to put your compiler in C99 mode with -std=c99 or similar to do this):
for ( int n = 1; n <= number; ++n )
;
triangularNumber += n;
then you'd have spotted the error immediately because the program wouldn't compile, as by the time you got to triangularNumber += n; outside the loop, n would no longer be in scope. This is one good reason why limiting the scope of your variables to the minimum amount of code you need it can often be a good idea.

The second for statement has no braces, so the code runs ; number times!
You want:
for ( n = 1; n <= number; ++n )
{
**;**
triangularNumber += n;
}

Think of it like this:
loop {
do this;
and also this;
}
and more code outside the loop;
now, if you have a ";" with no code it will look like this:
loop {
;
}
and more code outside the loop;
the ; is a blank statement that gets run each time through the loop.
now if you remove the brackets take a look at this:
loop
;
and some code outside of the loop;
since there are no brackets the loop will only contain the very next line of code, in this example the empty line ";". then the line after that "and some code outside of the loop;" gets executed no matter what since it is outside of the loop.
basically, the code is interpeted as having brackets around one line of code if you don't have brackets. anything after the one line is outside of the brackets and is not in the loop.
i hope this clears things up!

The keyword for is a preface for a single statement that is run each time the loop completes. Since a semicolon ends a statement, the following loop does precisely nothing upon each iteration.
for ( n = 1; n <= number; ++n ) ;
Then execution continues to the subsequent statement (triangularNumber += n;), which is executed one time.
The same principle applies to if, while, and do keywoards as well. What gives you flexibility in all of these cases is this rule: Everything enclosed within a pair of braces is considered as one statement.
Thus, your code needs to look like one of these examples to work how you probably want it to.
for ( n = 1; n <= number; ++n ) triangularNumber += n;
-or-
for ( n = 1; n <= number; ++n )
{
triangularNumber += n;
} //everything between the braces is considered to be the one statement executed by the loop

Related

C program to find the sum of all odd integers up to n using while-loop

My book says for programming using while-loop, we must first initialize with a number, provide the condition mentioning 'while', and then it's to be followed by the statement to partake in the loop until the condition is met as well as to increment value in the loop.
Example :
i = 1;
while(i<=10)
{
s = s + i;
p = p * i;
i++;
}
But, in case of summing of odd numbers program no such incrementing value has been shown.
And, strangely enough(for me), I get correct result w/o the use of i++. I absolutely cannot wrap my head around why that is the case. Is mentioning i++ or i+1 not really a rule within loops?
int s, i, n;
s = 0;
i = 1;
while (i <= n)
{
s = s + i;
i = i + 2;
}
This line is the incrementing value:
i = i + 2;
The first loop increments by 1 with i++. But since you only want the odd numbers, you need to increment by 2.
You can simplify this to:
i += 2;
There is no such rule that we must use i++ in every loop(and for that matter using i as a loop variable).
As #Barmar indicated, you are incrementing i using the line :
i = i + 2;
There are cases where we need to increment by 3, 10, √n, logn, etc.
There are even cases where we need to run a loop backwards hence, we decrement i.
The point is, the value of i must change at some point otherwise we'll end up in an infinite loop.

What is the correct way of using GMP integer functions in C programs?

I'm trying to calculate the index of Fibonacci number with 1000 digits.
int i = 0, cnt = 2;
mpz_t limit;
mpz_init (limit);
mpz_ui_pow_ui(limit,10UL,999UL);
mpz_t fib[3];
for (i = 0; i < 3; i++)
mpz_init2(fib[i], 1024UL);
mpz_set_ui(fib[0],1UL);
mpz_set_ui(fib[2],1UL);
I think there's something wrong with assigning 1 to 1st and last element. I know that because those elements are not changing. But the loop should be valid till cnt becomes 4782.
The condition in while loop is only satisfied 2 times if.. <=0 or 3 times if .. >=0.
while(mpz_cmp(fib[i],limit)<=0) // should be <= only, not >=
{
i=(i+1)%3;
cnt++;
mpz_add(fib[i],fib[(i+1)%3],fib[(i+2)%3]);
}
for (i = 0; i < 3; i++)
mpz_clear(fib[i]);
mpz_clear(limit);
printf("Fibonacci number with more than 1000 digits: %d\n",cnt);
Please help find the logical error in this (it is compiling perfectly).
P.S. I don't want to use in-built mpz_fib_ui.
Integer Functions
After the for loop, i=3, so the conditional statement for the while loop depends on fib[3]
Adding i=0; before the while loop fixes it, and gives me the desired output:
Fibonacci number with more than 1000 digits: 4782

OpenMP Parallel error: missing increment expression

I'm trying to pass the code to list prime OpenMP numbers, I have two problems,
The first problem is to remove the Break and that the code works
the second problem is that marks this error error: missing increment expression
List item
in the line of for (count = 2; count <= n;)
// If I add an expression as count ++ code does not work correctly.
Here is my codes :
int n, i = 3, count, c;
// n is the number's prime
for ( count = 2 ; count <= n ; )
{
for ( c = 2 ; c <= i - 1 ; c++ )
{
if ( i%c == 0 )
break;
}
if ( c == i )
{
printf("%d\n",i);
count++;
}
i++;
}
}
Depends on the rest of the code, but:
If you delete the increment in the first FOR loop, the error is obvious. You cant delete that. "count ++" is mandatory.
Check if the initial valor of count is less than n (i.e: if "n" is 1, and you start with count =2, the FOR loop will not start)
Be careful: in the first IF block, you are trying to modify the value of "count", but that variable is being used by the FOR loop to control the remaining iterations. As I said, it depends on the code functionality, but usually you dont want that to happen (modify a loop-control variable)
Without further information, I'm afraid we wont be able to help you more.re.

Are loops with and without parenthesis handled differently in C?

I was stepping through some C/CUDA code in the debugger, something like:
for(uint i = threadIdx.x; i < 8379; i+=256)
sum += d_PartialHistograms[blockIdx.x + i * HISTOGRAM64_BIN_COUNT];
And I was utterly confused because the debugger was passing by it in one step, although the output was correct. I realised that when I put curly brackets around my loop as in the following snippet, it behaved in the debugger as expected.
for(uint i = threadIdx.x; i < 8379; i+=256) {
sum += d_PartialHistograms[blockIdx.x + i * HISTOGRAM64_BIN_COUNT];
}
So is are parenthesis-free for loops treated differently in C or in the debugger, or perhaps it is particular to CUDA.
Thanks
The debugger executes one statement at a time.
Check this out:
int sum = 0; /* one assignment statement */
for (int k = 0; k < 10; k++) sum += k; /* one for statement */
and compare with this
int sum = 0; /* one assignment statement */
for (int k = 0; k < 10; k++)
{ /* for statement with the body
in a block of statements */
sum += k; /* assignment statement */
}
In the first example above, the sum += k is an integral part of the for statement; in the 2nd example, it is a full statement on its own.
There isn't any execution difference between a single statement following the "for" or a block with one statement in it. Looking at your code though, do you realise that i isn't actually incremented? Perhaps you meant to put i+=256.
As far as the debugger is concerned the brackets constitute something else to "move into" whereas the single line is just that, a single line (just like an if statement with no block).

Example of a while loop that can't be written as a for loop

I know a while loop can do anything a for loop can, but can a for loop do anything a while loop can?
Please provide an example.
Yes, easily.
while (cond) S;
for(;cond;) S;
The while loop and the classical for loop are interchangable:
for (initializer; loop-test; counting-expression) {
…
}
initializer
while (loop-test) {
…
counting-expression
}
If you have a fixed bound and step and do not allow modification of the loop variable in the loop's body, then for loops correspond to primitive recursive functions.
From a theoretical viewpoint these are weaker than general while loops, for example you can't compute the Ackermann function only with such for loops.
If you can provide an upper bound for the condition in a while loop to become true you can convert it to a for loop. This shows that in a practical sense there is no difference, as you can easily provide an astronomically high bound, say longer than the life of the universe.
Using C
The basic premise is of the question is that while loop can be rewritten as a for loop. Such as
init;
while (conditional) {
statement;
modify;
}
Being rewritten as;
for ( init; conditional; modify ) {
statements;
}
The question is predicated on the init and modify statements being moved into the for loop, and the for loop not merely being,
init;
for (; conditional; ) {
modify;
}
But, it's a trick question. That's untrue because of internal flow control which statements; can include. From C Programming: A Modern Approach, 2nd Edition you can see an example on Page 119,
n = 0;
sum = 0;
while ( n < 10 ) {
scanf("%d", &i);
if ( i == 0 )
continue;
sum += i;
n++;
}
This can not be rewritten as a for loop like,
sum = 0;
for (n = 0; n < 10; n++ ) {
scanf("%d", &i);
if ( i == 0 )
continue;
sum += i;
}
Why because "when i is equal to 0, the original loop doesn't increment n but the new loop does.
And that essentially boils down to the catch,
Explicit flow control inside the while loop permits execution that a for loop (with internal init; and modify; statements) can not recreate.
While loops can be more helpful when the number of loop iterations are not known while for loops are effective when the loop iterations are known.
Consider the following code snippet for student marks, but the number of students is not known
ArrayList studentMarks = new ArrayList();
int score = 100;
int arraySize = 0;
int total = 0;
System.out.println("Enter student marks, when done press any number less than 0 0r greater than 100 to terminate entrancies\n");
while(score >= 0 && score < 101) {
System.out.print("Enter mark : ");
score = scan.nextInt();
if(score < 0 | score > 100)
break;
studentMarks.add(score);
arraySize += 1;
}
// calculating total, average, maximum and the minimum values
for(int i=0;i<studentMarks.size();i++) {
total += studentMarks.get(i);
System.out.println("Element at [" + (i+1)+"] : " +studentMarks.get(i));
}
System.out.println("Sum of list element is : " + total);
System.out.println("The average of the array list : " + (total/(studentMarks.size())));
Collections.sort(studentMarks);
System.out.println("The minimum of the element in the list is : " + studentMarks.get(0));
System.out.println("The maximum of the element in the list is : " + studentMarks.get(studentMarks.size()-1));
scan.close();
While loop does not have as much flexibility as a for loop has and for loops are more readable than while loops. I would demonstrate my point with an example. A for loop can have form as:
for(int i = 0, j = 0; i <= 10; i++, j++){
// Perform your operations here.
}
A while loop cannot be used like the above for loop and today most modern languages allow a for each loop as well.
In my opinion, I could be biased please forgive for that, one should not use while loop as long as it is possible to write the same code with for loop.
In C-like languages, you can declare for loops such as this:
for(; true;)
{
if(someCondition)
break;
}
In languages where for is more strict, infinite loops would be a case requiring a while loop.

Resources