I need to convert this loop to a for loop.
Input:A number k ≥ 0
Output: Output ??
x←0
y←0
while x≤k do
x←x+1
y←y+3
return y
Also can you describe me the output of this?
Thank you.
You didn't describe what language you were thinking of, and I didn't recognize the syntax of your while example. But this C code should be a for-loop equivalent of that code.
for(x=0, y=0; x <= k; x++) y += 3;
Of course, if you only care about the result, this could be replaced by
y = 3*(k+1);
Edit: Ok, so as pseudo-code, this could be something like
y←0
for each x from 0 to k inclusive do
y←y+3
end do
return y
But I find the proper C code much clearer, myself.
Related
We have a string "4_3_1_2_6_5_9". We have to find all the combinations of operators, which when they replace the "_" with the operator it gets the number 27.
Some examples:
4+3+1-2+6*5-9=27
4*3/1+2/6*5*9=27
4-3*1+2*6+5+9=27
I know how to replace the "_" char with operator chars "+-*/", but how would the program even read it?
I don't even know how to begin,some pointers(heh, get it?) at the right direction would be appreciated.
Here are some ideas for you to get started.
You can get each of the operands in an int by doing something like this:
char s[] = "4_3_1_2_6_5_9";
int operands[7];
sscanf(s, "%d_%d_%d_%d_%d_%d_%d", operands, operands+1, ..., operands+6);
You might want to try to generate all different combinations of operators. A simple approach would be to have 6 nested for loops, each looping over your 4 available operators and assigning each of them to an underscore:
char [] operators = "+-*/";
for (int i0 = 0; i0 < 4; i1++)
for (int i2 = 0; i2 < 4; i2++)
...
for (int i5 = 0; i5 < 4; i5++) {
// here you replace the 1st underscore with operators[i0],
// the 2nd underscore with operators[i1],
// and so on with all 6 of them.
}
Then, you need a way to parse the string you've generated to get a result. This isn't so simple, because operators have different precedences (4*3/1+2/6*5*9 is equal to ((4*3)/1)+((2/6)*5*9), for example).
It might be a bit overkill for your problem, but it's still very interesting: You can build an Abstract Syntax Tree from each expression, using Dijkstra's Shunting-Yard algorithm. Those trees are easy to evaluate, and that way you can get the final result.
I hope this points you in the right directions!
How can I code, in OCaml, something like this (main() in C)
for (i=0; i<y; i++)
if (x==5)
{
y=i;
return true;
}
It would return the boolean True and y would be equal to the corresponding i value.
Basically, in OCaml, I was wondering if you could have a if like:
for i=0 to y-1 do
if x=5 then
begin
y=i
true
end
else ()
done;;
I know the lines between begin-end aren't correctly implemented. I don't even know if what I want to do is possible in OCaml. If you are someone who has knowledge on this kindly share it with me. Thanks!
If your question is about early return from a for loop, this is how you'd it:
exception Break of int
let n =
try
for i = 0 to 5 do
if i mod 2 = 0 then
raise (Break i)
done;
0
with
Break i -> i
You could also assign to a ref cell instead of passing the value in the exception, if that fits your use case better. But this isn't the kind of code you should typically be writing in OCaml. Trying to emulate C in OCaml is almost always a bad idea.
(If this is a duplicate please point me to an answer)
I have two scenarios where a loop is checking a complex expression over and over again (a complex expression would consist of math operations and retrieving data):
for (int i = 0; i < expression; i++) {
// stuff
}
for (int i = 0; i < someNumber; i++) {
if (i == expression) break;
}
I'm wondering if it's more efficient to pre-calculate the expression and check against a known value like so
int known = expression;
for (int i = 0; i < known; i++) {
// stuff
}
for (int i = 0; i < someNumber; i++) {
if (i == known) break;
}
or if it's done by the compiler automatically.
For reference, I'm running the loop ~700 000 000 times and the expression is something like structure->arr[j] % n or sqrt(a * n + b)
Is it even worth it?
If the compiler is able to detect that calculating expression will give the same result every time, it will only do the calculation once.
The tricky part is: "If the compiler is able to ...."
Compilers are very smart and will probably be successful in most cases. But why take the chance?
Just write that extra line to do the calculation before the loop as you did in your second example.
By doing that you send a clear message to the compiler about expression being constant within the loops. Further it may also help your co-workers to easier understand the code.
That said... you yourself must be sure that expression is in fact the same every time. Let's look at your example:
the expression is something like structure->arr[i] % n or sqrt(a * n + b)
Now the first one, i.e. structure->arr[i] % n depends on the loop variable i so it will be a big mistake to move the code outside the loop.
The second (i.e. sqrt(a * n + b)) looks better provided that a n b doesn't change inside the loop.
Is there a difference between for and while statements? Is it just syntax?
#include <stdio.h>
void main() {
int cent_temp = 0;
int fah_temp;
while (cent_temp <= 20) {
fah_temp = (9 * cent_temp) / 5 + 32;
printf("%d degrees C = %d degrees F\n", cent_temp, fah_temp);
cent_temp++;
}
}
This means to me....
While the value of cent_temp is less than 20 then calculate fah_temp. Then increase the value of cent_temp by 1 and check it is still less than 20; then go round the loop again.
Regarding the syntax:
printf("%d degrees C = %d degrees F\n", cent_temp, fah_temp);
This means %d means print to the screen, replace with a decimal number the value of cent_temp and %d means replace with a decimal number the value of fah_temp.
#include <stdio.h>
void main() {
int cent_temp;
int fah_temp;
for (cent_temp = 0; cent_temp <= 20; cent_temp++) {
fah_temp = (9 * cent_temp) / 5 + 32;
printf("%2d degrees C = %2d degrees F\n", cent_temp, fah_temp);
}
}
My interpretation of the above is:
for cent_temp = 0 repeat while cent_temp less than 20 and then execute cent_temp+1 at the end. So cent_temp 0 goes into the loop to calculate fah_temp and gets printed to the screen. Then cent_temp goes up by one then goes round the loop again. Here I've used %2d instead of %d to signify that it should have 2 spaces for a decimal number (and they line up when executed). Both codes will not execute if cent_temp > 20.
Similarly rearranging the statement in a do while loop has a similar effect and doesn't really have an impact on the result.
Does each type of loop have a different application?
Please correct me if I wrong!
Is there a difference between 'for' and 'while' statements? Is it just
syntax?
To me, it is just syntax.
From K&R section 3.5 Loops -- While and For, I quote:
The for statement
for (expr1; expr2; expr3)
statement
is equivalent to
expr1;
while (expr2) {
statement
expr3;
}
except for the behavior of continue.
Grammatically, the three components of a for loop are expressions.
Most commonly, expr1 and expr3 are assignments or function calls
and expr2 is a relational expression.
Notes
As user #chqrlie has mentioned in the comments, control statements like break and continue make the situation slightly murkier.
There are some situations where the modify statement is necessary in the loop body. For example Erase-remove idiom with std::set failing with constness-related error (in C++ though)
Example
As an example, let us write a loop to print all the odd numbers between 1 and 100.
int i = 1;
while (i <= 100) {
printf("%d\n", i);
i += 2;
}
for (int i = 1; i <= 100; i += 2) {
printf("%d\n", i);
}
Opinion
I am not a language expert, but in most situations in practice I find them transformable.
I personally prefer using for syntax because:
loop control structure is in one single place (the for header) making it easy to read, and
the loop variable (e.g. i) is not exposed to the outer scope.
for(cent_temp = 0; cent_temp <= 20; cent_temp++)
{ /* code */ }
is 100% equivalent to
cent_temp = 0;
while(cent_temp <= 20)
{
/* code */
cent_temp++;
}
But a do-while is different since it puts the condition check at the end.
As for when to use which loop, it is a matter of style and therefore a bit subjective. The industry de facto standard style, used by the majority of all C programmers, goes like this:
for loops should always be used when performing a known number of iterations. It is then considered the most readable form.
while loops should be used the the number of iterations is unknown in advance, or when the loop is turning complex for some reason. For example if you need to alter the loop iterator variable inside the loop body, then you should use a while loop instead of a for loop.
do while loops should be used for special cases where you need to skip the condition check the first lap of the loop, for example do { result = send(); } while(result == ok);.
I looked at my Code Complete by Steve McConnell (the bible).
Here is what you can read in chapter 16:
A for loop is a good choice when you need a loop that executes a specified number of times. [...]
Use for loops for simple activities that don't require internal loops controls. Use them when the loop involves simple increments or simple decrements, such as iterating through the elements in a container. The point of a for loop is that you set it up at the top of the loop and then forget about it. You don't have to do anything inside the loop to control it. If you have a condition under which execution has to jump out of a loop, use a while loop instead.
Likewise, don't explicitly change the index value of a for loop to force it to terminate. Use a while loop instead. The for loop is for simple uses. Most complicated looping tasks are better handled by a while loop.
In general, you would use a for loop to iterate over a finite set of values, whereas you'd use a while or do-while loop to iterate while a specific condition or set of conditions is true. In most of C's contemporaries (Basic, Pascal, Fortran, etc.), a for loop can only iterate over a scalar index:
Fortran:
DO 10 i=1,10
statements
10 CONTINUE
Pascal:
for i := 1 to 10 do
begin
statements
end;
Both of these snippets loop exactly 10 times. The index i is initialized and updated by the loop automagically. I'd have to go back and check, but I'm pretty sure you cannot write to i in the loop body.
C actually blurred the lines between a for and while loop by adding the control expression:
for ( init-expr ; control-expr ; update-expr )
statement
In C, a for loop can iterate over a scalar just like Fortran or Pascal:
for( i = 0; i < 10; i++ )
{
do_something_with( i );
}
Or it can iterate over multiple scalars:
for ( i = 0, j = 0; i < 10 && j < 10; i++, j++ )
{
do_something_with( i, j );
}
Or it can iterate over the contents of a file:
for( c = fgetc( in ); c != EOF; c = fgetc( in ) )
{
do_something_with( c );
}
Or it can iterate over a linked list:
for( cur = head; cur != NULL; cur = cur->next )
{
do_something_with( cur );
}
In Fortran and Pascal, those last three loops would have to be expressed as while loops (which I'm not going to do, because I've pretty much exhausted my Fortran and Pascal knowledge already).
The other big difference between a C for loop and those of Fortran or Pascal is that you can write to the loop index (i, j, c, or cur) in the loop body; it's not specially protected in any way.
A while or do-while loop is used to iterate as long as a specific condition or set of conditions is true:
while( control-expr )
statement
do
statement
while( control-expr );
In both a for and while loop, the condition is tested before the loop body executes; in a do-while loop, the condition is tested after the loop body executes, so a do-while loop will always execute at least once.
In C, you can use either a for loop or a while loop in many circumstances:
while ( ( c = fgetc( in ) ) != EOF )
do_something_with( c );
for ( c = fgetc( in ); c != EOF; c = fgetc( in ) )
do_something_with( c );
Both loops do exactly the same thing; it's just a matter of which one you think more clearly expresses your intent, or which you think would be easier for other people to understand.
From the point of view of algorithmic for and while are not the same. Shortly, in algorithmic, for should be used when bounds are known and while when you don't know if the condition can be met or when it can be. For is to repeat something n times (n known), which is exactly the case of your example computation; a for loop should be used (don't you think what the loop makes is more clearly stated in the for loop ?). If you want an example of a must be used while loop, look at something like Collatz sequence. From a point of view of computability, for loops can always be transformed in while loops but not the converse.
From the point of view of computer languages it is now common to fuse both, in C for example, it makes no difference, only syntactic. But remember that in some other language that could be very different, for example in Pascal for loops are very limited.
Source code is written not only to be compiled and executed by computers but also to be read and understood by humans.
A computer doesn't really mind whether a for loop, a while loop or a goto is used. On the other hand, a human expects different meanings for different structures.
computing values over a known range of inputs is best shown with a for loop;
reading a file up to its end is best shown with a while loop.
Choosing which structure to use is similar as choosing a variable name.
I have a program that I'm trying to decode. It is translated to C from another language (whose name is not spoken here), and as I want to understand how it works, I am slowly rewriting the code and simplifying it to use all the nice logical constructs C has to offer.
The following little bit keeps popping up in my code, with varying values of X and Y:
ptr[X]--;
while(ptr[X])
{
ptr[X]--;
ptr += Y;
}
ptr is of type char *, and I can't really make assumptions about the state of the array at any point because it's pretty deeply embedded in loops and dependent on input and output. I can successfully "simplify" that to:
for(ptr[X]--; ptr[X]; ptr[X]--, ptr += Y);
But that's just awful. Ever so slightly better is:
for(ptr[X]--; ptr[X]; ptr += Y) ptr[X]--;
I want to know if anyone can come up with a better simplification of the above code, I would greatly appreciate it. This occurs in no less than five places, and is impairing my ability to simplify and understand the flow control, so if anyone can provide a more consise/readable version, that would be awesome. If anyone can just offer any sort of fancy insight into that code, that would be awesome too, although I basically understand what it does.
Insight into the code for a specific X and/or Y can also help. Y tends to be between -2 and 2, and X is usually 1, for what its worth.
ptr[X] is equivalent to *(ptr + X), so we can rewrite it as follows:
for((*(ptr + X))--; *(ptr + X); (*(ptr + X))--, ptr += Y);
Now there's a lot of redundancy here, so we can simplify this to:
char *ptr_plus_x = ptr + X;
for((*ptr_plus_x)--; *ptr_plus_x; (*ptr_plus_x)--, ptr_plus_x += Y);
Then we can get rid of ptr_plus_x entirely:
ptr += X;
for((*ptr)--; *ptr; (*ptr)--, ptr += Y);
In English, we visit the memory locations at offsets X, X+Y, X+2Y, X+3Y, ..., decrementing each memory location, until we find a memory location that is 0. But, the test for 0 always occurs after the decrement, so we're really looking for the first memory location in that sequence with a value of 1. Once we find that, we decrement it to 0 and quit.
If Y is 1, then we decrement a string of consecutive memory locations going forwards, up to and including the first 1. If Y is -1, the same thing happens, but searching backwards from offset X. If Y is 0, an infinite loop occurs. If Y is any other value, the search pattern skips various entries.
It's not a very intuitive function, so I can see why you're confused.
I'll throw in:
ptr[X]--
while (ptr[X]--) ptr+=Y;
first evaluate, then decrement (for while condition, that is)
Edit: OK, i'll hate myself in the morning. Goto's are ok at this level, right?
dec: ptr[x]--
while (ptr[X]){
ptr+=Y;
goto dec;
}
(i honestly dont know whether to leave this or not.)
EDIT2: so, how about this one? (tcc didn't complain)
while (ptr[X]--?ptr[X]--,ptr+=Y:0){}
EDIT 2 1/2;
//longshot
while (ptr[X]--?ptr[X]--,ptr+=Y, ptr[X]:0){}
If all else fails..
EDIT3: Last one for tonight.
while (ptr[X]--?ptr[X]--,ptr+=Y:0){
if (!ptr[X]) break;
}//good luck with this, it has been very amusing.
The website for it-which-shall-not-be-named states:
The semantics of the it-which-shall-not-be-named states commands can also
be succinctly expressed in terms of C, as follows (assuming that p has
been previously defined as a char*):
> becomes ++p;
< becomes --p;
+ becomes ++*p;
- becomes --*p;
. becomes putchar(*p);
, becomes *p = getchar();
[ becomes while (*p) {
] becomes }
So it seems like it should be fairly easy to convert it over to C.
EDIT: Here is the Hello World BF converted to C++.
It's quite simple as is, already. Instead of trying to write less statements, I would rather try to grasp the intent and add some comment.
An example of 'a' meaning of the snippet: decrease all elements of a column (X) of a matrix of Y columns. You would need that to draw a vertical line of +'ses, for instance, in a language that has no direct assignment.
You could clarify this meaning by showing the indices directly:
// set elements of column to cGoal
for( int decrementsToGoal = cGoal; decrementsToGoal != 0; --decrementsToGoal ) {
// decrease all elements of column X
for( int row = cMaxRows; M[ row*matrixsizeY + columnX ]; --row ) {
--M[ row*matrixsizeY + columnX ];
}
}
Good luck :)