Figuring out what this function does? - c

I have to rewrite this for loop into a do while loop, but I can't figure out what this does. Please help
for(;; done = (int) sum == 5
{if (done) break;
sum += 2.6;}

Let's assume that the syntax error is resolved, so that the code reads
for(;; done = (int) sum == 5)
{
if (done) break;
sum += 2.6;
}
Now this code works as follows: the for loop has no initialization expression and no test expression, so it begins execution unconditionally. The first thing that happens is the "flag" done (an undefined object that I'm assuming is an int that may or may not be initialized to zero) is checked. If it's true (non-zero), the code breaks out of the for loop. if not, 2.6 (a double) is added to sum (an undefined object that I'm assuming is a double and that may or may not be initialized to a sensible value, or a number at all). When execution reaches the closing brace, the iteration statement in the for loop is executed, which compares sum to 5 (after converting sum to an integer value), and assigns the result of the comparison (i.e. 1 for true and 0 for false) to done.
Converting this to a while loop ought to be fairly straightforward. Simply execute these steps in order. Note that since the first piece of code to execute is checking if(done), the code more naturally lends itself to a simple while than a do-while loop.
Note that this would have been considerably clearer if you had defined the types of your variables, and provided initial values for them.

Related

While loop using a variable with no condition

So I've seen this used before some of my profs code aswel as in some of my friends who have more experience with programming.
int number = 0;
while(number) {
a bunch of code
}
My understanding is that this while loop is essentially running with no condition, i feel like it should be
while(number = 0) {
Isnt this essentially creating an infinite loop? but in the cases I've seen it used it can break out of the loop somehow.
edit:
do while that uses the argument in question. Note that the 2 functions being called in the switch case will call searchpatientdata again once they have completed.
This code is not currently wokring, but was working in a previous build and this function was the same. They also do not change the selection variable either.
The condition in a while loop can be any expression of scalar (numeric or pointer) type. The condition is treated as false if the result of evaluating the expression is equal to zero, true if it's non-zero. (For a pointer expression, a null pointer is equal to zero).
So while (number) means while (number != 0).
As a matter of style, I prefer to use an explicit comparison unless the variable is logically a Boolean condition (either something of type bool or _Bool, or something of some integer type whose only meaning values are true and false) -- but not everyone shares my opinion, and while (foo) is a very common way to write while (foo != 0).
The same applies to the condition in an if, a do-while, or a for statement.
Note that in your example:
int number = 0;
while(number) {
// a bunch of code
}
the body of the loop will never execute, because number is equal to zero when the loop is entered. More realistically, you might have:
int number = some_value;
while (number) {
// a bunch of code *that can change the value of number*
}
Any place in C where a Boolean value is required, any number will be evaluated like this:
zero → false
not zero → true
From C reference
Executes a statement repeatedly, until the value of expression becomes equal to zero. The test takes place before each iteration.
How it works?
entry control loop
condition is checked before loop execution
never execute loop
if condition is false there is no semicolon at the end of while
statement
Come to point as per OP's question yes
While (Variable_name) evaluated as True
In below Example While loop executes until condition is true
Example:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num=1;
while(true)
{
if(num==5)
{
break;
}
printf("%d\n",num);
num++;
}
return 0;
}

How to print numbers from 1-100 incremented by 5

I am trying to print numbers from 1-100 incremented by 5. This is my code:
printf( "Exercise 1" );
int number = 0;
for ( number = 0; number <= 100; number + 5 ){
printf( "%d", number );
}
Do you know what is wrong with this code?
This should fix it.
for ( number = 0; number <= 100; number +=5 )
If we look at the documentation of a for loop from cplusplus.com...
for (initialization; condition; increase) statement;
Like the while-loop, this loop repeats statement while condition is
true. But, in addition, the for loop provides specific locations to
contain an initialization and an increase expression, executed before
the loop begins the first time, and after each iteration,
respectively. Therefore, it is especially useful to use counter
variables as condition.
It works in the following way:
initialization is executed. Generally, this declares a counter variable, and sets it to some initial value. This is executed
a single time, at the beginning of the loop.
condition is checked. If it is true, the loop continues; otherwise, the loop ends, and statement is skipped, going directly to
step 5.
statement is executed. As usual, it can be either a single statement or a block enclosed in curly braces { }.
increase is executed, and the loop gets back to step 2.
the loop ends: execution continues by the next statement after it.
You had most of this right.. except the last parameter...
In your specific piece of code, that last piece of your for loop, number + 5, you need to increase your loop counter and assign it back to itself (assignment)
You can accomplish this two ways:
number = number + 5
number += 5 Since you are reassigning the same variable with it's own value plus a number, C has some built in "shortcuts" (assignment operators).
Both of these statements are equivalent, but note the better readability of list item 2.

C Programming - comma operator within while loop [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 6 years ago.
Prog 1:
#include<stdio.h>
int main()
{
int i=0;
while(i<=8,i++);
printf("%d",i);
return 0;
}
Prog 2:
#include<stdio.h>
int main()
{
int i=0;
while(i++,i<=8);
printf("%d",i);
return 0;
}
The output of Prog 1 is 1 and that of Prog 2 is 9.
Can someone explain whats going here. How the two codes are different?
The comma operator evaluates both of its arguments in turn, throwing away the result, except for the last. The last evaluated expression determines the result of the entire expression.
i<=8,i++ - here the value of the expression is the value of i++, which is the value of i before being incremented. It's 0 so the loop immediately terminates.
i++,i<=8 - here the value of the expression is the value of i<=8 which is 0 only when i is incremented to 9.
On a personal note: I think the second form, while somewhat comparable to a for loop, is less clear to the reader of the code than an actual for loop.
1 while ( condition )
2 statement;
3 more_code();
In the above code snippet, the statement can be executed repeatedly as long as condition is true. On each iteration of the while loop, condition is evaluated to either true or false. If it's false, the while loop ends and execution continues beyond it's scope (in this case, line 4 with more_code().
We are usually accustomed to enclosing parts of code that we want to be executed in loop with curly brackets { and }, but that is not mandatory. If we do not do so, the looping code will consist of single statement, the one immediately following the while part.
It could actually be argued that the more common situation, where we combine while with curly brackets enclosed block of code could be interpreted as providing this block of code in place of a single statement, with braces providing information that the block should be treated (by compiler analysing it's relation with preceding and following code) as if it was a single statement.
However, as it is perfectly valid to provide a single statement, not a usual block of code, it's worth to understand that there is a valid statement that is empty. We get an empty statement by typing a semicolon without preceding it with a code causing anything. So following is perfectly valid:
1 code;
2 ; // empty statement
3 ; // another empty statement
or in fact this:
1 code;; // a "code" statement followed by empty statement in the same line
The while( condition ) part is not terminated with a semicolon, so if it's supposed to control some actual code (apart from condition), it should not be followed by a semicolon. If it is immediately followed by a semicolon, that semicolon will constitute (and be so interpreted by compiler) an empty statement, so the looping code will be empty. If that's unintended, then the code we wanted to be looped, whether a block of code or a statement, will not be looped, but rather executed once, after (and if) loop ends.
1 int a = 0;
2 while ( a < 3 ) ; // Next line is not part of loop - only the empty statement this semicolon creates is. This loop is infinite, or in other words it will never end.
3 a++; // This won't be executed even once.
4 printf("This never happens.");
(It's worth realizing that lines are only important for us, humans, in C. Lines and indentation can be misleading if they represent the intentions of programmer, when he failed to write the code functioning as he wanted it to.)
Therefore what happens in both snippets from the question, is we get condition evaluated continuously until it yields false. To understand what's going on we need to examine the way comma operator works.
(Note, while comma as a character can be used with a completely different meaning in various places in C - I can think of function declarations, definitions and calls - in this case comma character is part of condition, therefore it acts as an operator - something akin to + or % operators.)
expression1 , expression2
Comma operator causes expression1 to be evaluated first, then expression2, and returns the value of expression2.
Upon every evaluation of condition, we will thus evaluate both expressions, (in this case both being operands, i++ and i<=8), then consider value of the right one as result of comma operand itself, and thus as value of our condition. So the loop will keep repeating as long as the right operand resolves as true.
While usually we use condition to control the execution of loop, often, as in this case, condition may have "side" effects (intentional or unintended). In our case variable i is affected by every evaluation of condition: it is increased by one.
Our example differs only in order of operands of condition, therefore pay attention to the right operand which really controls the execution of the loop.
Let's examine the second example first. In this case we have condition i++, i<=8. This means upon every evaluation we first increase i, then check if it's less than or equal to 8. So on first evaluation of condition we will increase i from 0 to 1 and conclude that 1<=8, so the loop continues. The loop so constructed will break when i becomes 9, ie. on the 9th iteration.
Now as for the first example, the condition is i<=8, ++i. Since comparison has no side effects, that is we could perform any number of comparisons in any order and if that's the only thing we did, that is if we did not perform any other action in a way or order dependent of results of the comparisons, those comparisons would do absolutely nothing. As is in our case, we evaluate i<=8 which evaluates to true or false, but we make no use of this result, just proceed to evaluating the right operand. So left operand absolutely doesn't matter. Right operand, on the other hand, has both a side effect and it's value becomes value of entire condition. Before each loop iteration we check if i++ evaluates to true or false.
i++ is a unary operator of post-incrementation. It returns value of i then increases it by one (the difference between i++ and ++i is subtle but crucial in cases like this one). So what happens is we first check whether i is true or false, then i is increased by one.
In C there is no boolean type. Integers are considered to be true if they have a non-zero value.
So upon first evaluation of i++ we get 0, that is false. This means the loop is broken without even a single iteration. However it does not break evaluation of i++, which causes i to increase by one before we're done with the loop and execution proceeds beyond it. So once we're done with the while loop, i is already 1.
If we want to be very precise in our understanding, the part where we take the result of evaluating entire condition happens, chronologically, after we are finished executing any code involved in this evaluation. So we first memorize that i was 0 at the point we got toward i++ part, then we increase i by one, and then we are finished executing condition, so we provide value of 0 to the code that decides if we should do another (in this case first) iteration or jump beyond looping part and move on. This is exact reason why everything within condition will actually happen even though the fact that loop will end was already determined: it was determined, but it was not checked and acted upon until condition finishes executing.
The expression separator operator , forces evaluation from left to right, and is also a sequencing point.
Prog 1: consider i <= 8, i++. i <= 8 is evaluated and discarded then i++ is evaluated. The entire expression has the unincremented value of i. Since i is initially 0, the while loop terminates on the first iteration. The output will be that singly incremented value of i, i.e. 1.
Prog 2: i++ is evaluated and the result discarded, then i <= 8 is evaluated with the new value of i since , is a sequencing point. So the while loop runs until i <= 8 is no longer true with the incremented value of i. The output will be 9.

"invalid controlling predicate" compiler error using OpenMP

I'm creating a basic prime number checker, based on C - determine if a number is prime , but utilising OpenMP.
int isPrime(int value)
{
omp_set_num_threads(4);
#pragma omp parallel for
for( int j = 2; j * j <= value; j++)
{
if ( value % j == 0) return 0;
}
return value;
}
When compiling with -fopenmp, GCC version 4.7.2 is erroring, stating invalid controlling predicate with respect to the for loop.
It looks like this error is caused by the j squared in the for loop. Is there a way I can work around this and still achieve the desired output from the algorithm?
return is not allowed inside the loop as it will cause exit before the curly braces.
Note the definition given below :
From the OpenMP V2.5 spec, 1.2.2 OpenMP language terminology, p2:17-
structured block - For C/C++, an executable statement, possibly
compound, with a single entry at the top and a single exit at the
bottom.
A structured block starts with the open { and ends with the closing }. The return is contained within these braces, so this program also violates the OpenMP definition for a structured block, because it has two exits (one at the return and one at the exit through the brace)
OpenMP places the following five restrictions on which loops can be threaded:
The loop variable must be of type signed integer. Unsigned integers,
such as DWORD's, will not work.
The comparison operation must be in the form loop_variable <, <=, >,
or >= loop_invariant_integer
The third expression or increment portion of the for loop must be
either integer addition or integer subtraction and by a loop
invariant value.
If the comparison operation is < or <=, the loop variable must
increment on every iteration, and conversely, if the comparison
operation is > or >=, the loop variable must decrement on every
iteration.
The loop must be a basic block, meaning no jumps from the inside of
the loop to the outside are permitted with the exception of the exit
statement, which terminates the whole application. If the statements
goto or break are used, they must jump within the loop, not outside
it. The same goes for exception handling; exceptions must be caught
within the loop.
According to the OpenMP standard (§2.5.1, p.40), the acceptable forms of the controlling predicate of the for loop are:
var relational-op b, and
b relational-op var
Your use of j * j <= value is a clear violation of this requirement. The rationale is that it requires the compiler to emit code that computes the integer square root of value at run time, with the latter being undefined for some values of value, specifically for the negative ones.
You can replace j * j <= value with j <= sqrt_value, where sqrt_value is the integer square root of value, but then would come the problem with having an alternative exit path in the structured block inside the loop. Unfortunately no easy solution exists in this case since OpenMP does not support premature termination of parallel loops.

While conditions followed by ;

I have been asked to comment some code and describe what it does. All was fine and I had a good handle on what was being done in the the cases of the switch but now I am unsure whether any of the cases are ever met. I don't have anyway to run or test this code currently as my main machine with all my regular software is down.
Does either of the cases of the switch get used besides the default with the conditions of this while loop? is i simply incremented to 32 and the rByte returned before it even makes the switch? What is with the ; after the conditions of the while? Shouldn't it be followed by {....} rather than ; ?
while(pCommand[--Ptr.Five] > 10 && ++i <32);
if(i==32)
{
return rByte;
}
switch(pCommand[Ptr.Five++])
{
case 2: ... (lots of code)
break;
case 4: ... (lots of cod)
break;
default: ...
break;
}
Also, how is the --Ptr.Five handled vs. the Ptr.Five++? My understanding is the first moves the pointer back and uses that value while the second uses the current value and post increments.
Am I missing something? Even moving past the ; after the conditions of the while and the lack of {} after the while, wouldnt the value of Ptr.Five be > 10 and therefore never be 2 or 4 ever?
With the ; behind the conditions of the while, would i just get bumped to32 and the following if would return the rByte?
The loop
while(pCommand[--Ptr.Five] > 10 && ++i <32);
decrements Ptr.Five and increments i until
pCommand[Ptr.Five] <= 10, or
i >= 32,
whichever happens first. Since the changes to the interesting variables are done in the loop condition, the loop body should be empty. (Not that it's particularly good style, but I've seen worse.)
If i == 32, the switch isn't reached, otherwise, if i < 32, you know that pCommand[Ptr.Five] <= 10, so both non-default cases can be reached.
The semicolon by itself is an empty statement. So doing e.g.
while (complicated_expression)
;
Is the same as:
while (complicated_expression)
{
}
It's often used when complicated_expression has side-effects, so no loop body is needed.
It's impossible to answer your question. Even if we assume that i starts at 0, who knows what value pCommand[Ptr.Five] has at the start of this code block?
Addressing some of the questions that can be answered, would it help if we rewrote the while like this:
while(pCommand[--Ptr.Five] > 10 && ++i <32)
{
/* do nothing as the body of the loop... nothing at all.
* Everything happens in the condition.
*/
}
The syntax with the semicolon is valid, if a bit confusing at first: think of what the semicolon means in C/C++ (terminates a statement) and then think of what the statement being terminates is in this case (hint: it's a "no operation").
The difference between --Ptr.Five and Ptr.Five-- is what you describe: the first variant (the pre-decrement) will decrement Ptr.Five and then return the resulting value; the second variant (the post-decrement) will decrement the Ptr.Five but return the value before the decrement.
while(pCommand[--Ptr.Five] > 10 && ++i <32);
doesn't have a body, but the loop condition itself has side-effects, so it does do something.
We could re-write this as:
while (1) {
--Ptr.Five;
if (pCommand[Ptr.Five] <= 10)
break;
++i;
if (i == 32)
break;
}
if (i == 32) {
/* we never hit the pCommand condition */
}
As for why:
it searches backwards through pCommand, from offset Ptr.Five to at most 32 entries earlier, looking for a value <= 10
if it doesn't find such a value within 32 entries, it returns rByte
if it does find such a value, it switches on it and does some work
PtrFive is incremented to indicate the next entry after this value, after the switch is dispatched
Also, how is the --Ptr.Five handled vs. the Ptr.Five++? My understanding is the first moves the pointer back and uses that value while the second uses the current value and post increments.
That's exactly correct. In:
pCommand[--Ptr.Five] > 10
Ptr.Five is decremented before the rest of the expression is evaluated, whereas in:
pCommand[Ptr.Five++]
the expression is evaluated with the old value of Ptr.Five, and then it's incremented right after. Here, that means the switch is based on the old entry in pCommand (the one that ended the while loop because it's <= 10), but Ptr.Five is incremented before code inside the cases executes.
A quick note on side-effects: as John Bode points out in a comment, my description of the pre-decrement and post-increment expressions isn't quite accurate.
This is because storing the new value into Ptr.Five doesn't have to happen right away.
However since it does have to happen (as if) by the next sequence point, which is here the &&, there's no real ambiguity.
This generally only becomes an issue if you string multiple interdependent side-effecting expressions together in a single statement. So, you know, try and avoid that.
Presuming i started at 0 -- The while loop is parsing through 31 elements (1-31) of the pCommand array, decrementing Ptr.Five before checking the value, looking for a value that is less than 10. If it does not find one, the function returns rByte -- it then checks the value of pCommand[Ptr.Five] before it increments... therefore, the value used in the switch is the same as the value used in the while conditional. The value could well be any of the switch conditions as we know it is less than 10

Resources