I was looking at some Rust code and saw something along the lines of this:
'running: loop {
// insert code here
if(/* some condition */) {
break 'running;
}
}
What does it mean to "label" the loop with a lifetime? What are the benefits and differences between just doing:
loop {
// insert code here
if(/* some condition */) {
break;
}
}
Loop labels
You may also encounter situations where you have nested loops and need
to specify which one your break or continue statement is for. Like
most other languages, Rust's break or continue apply to the innermost
loop. In a situation where you would like to break or continue for one
of the outer loops, you can use labels to specify which loop the break
or continue statement applies to.
In the example below, we continue to the next iteration of outer loop
when x is even, while we continue to the next iteration of inner loop
when y is even. So it will execute the println! when both x and y are
odd.
'outer: for x in 0..10 {
'inner: for y in 0..10 {
if x % 2 == 0 { continue 'outer; } // Continues the loop over `x`.
if y % 2 == 0 { continue 'inner; } // Continues the loop over `y`.
println!("x: {}, y: {}", x, y);
}
}
Related
I want to relate each if statement to the else one below it only. So when the if isn't true the else beneath it is active alone. Then the next if will be run, and the else below that one will be used if its FALSE. How can I do this?
if (.....){
}
else (....){
}
if (.....){
}
else (....){
}
if (.....){
}
else (....){
}
You could use the ternary operator in C.
The syntax is as follows
result = binaryCondition ? valueReturnedIfTrue : valueReturnedIfFalse;
The most straight-forward way of solving this would be to simply exit once you've have entered any if...else block. You can do this with either a return statement inside each conditional, or a break. As long as all of your conditionals are within a loop or outer block, this will bypass your other if...else statements.
For example:
if (a) {
return b + 1
} else {
return b + 2
}
or:
if (a) {
b += 1
break
} else {
b += 2
break
}
I have this simple loop and condition, but you see below I can't jump out of loop :
rwloop# for (z in rendered_words.size-1 downTo 0 )
{
var css_=rendered_words[z].node.attr("class")
css_?.let {
if (css_=="classzero") {
break#rwloop
}
}
}
But I receive this error in break#rwloop :
break' or 'continue' jumps across a function or a
class boundary
Drop the let lambda since the #rwloop label is not visible inside it and use this:
rwloop# for (z in rendered_words.size-1 downTo 0 )
{
var css_=rendered_words[z].node.attr("class")
if (css_ != null) {
if (css_=="classzero") {
break#rwloop
}
}
}
https://kotlinlang.org/docs/reference/inline-functions.html#non-local-returns
It states that
break and continue are not yet available in inlined lambdas, but we are planning to support them too.
So, you should
Wait until its support comes
Or use local return statement instead,
How?
The lambda is a function itself, so you can return from it, this (if it is the last thing in the for loop like your case) will make the same effect of continue
rwloop# for(z in rendered_words.size-1 downTo 0 ) {
var css_=rendered_words[z].node.attr("class")
css_?.let {
if (css_=="classzero") {
return#let
}
}
}
Kotlin considers the lambda as a boundary (it is not an inner class because it is inlined), so you can't cross it by break nor continue till now.
The code below shows the rowtotal[0], which is the return value I'm getting from an infinite loop for every iteration. I'm trying to break the loop when all three returned values from the costcheck array are the same. This is my code:
do
{
.
.
.
/*do loop body*/
.
.
costcheck[counter3]=rowtotal[0];
if(costcheck[counter3-2]==costcheck[counter3] &&
costcheck[counter3-1]==costcheck[counter3] )
{
response=1;
}
counter3++;
printf("\t\t\t Number of iterations: %d \r", stop++);
}
while(response!=1);
Just get rid of all strange, superfluous variables. You only need to save the result of the previous iteration, together with a counter which you increase each time you find a match, rather than every time in the loop.
int counter=0;
const int COUNT_N = 3;
data_t prev=FORBIDDEN; // a value that rowdata[0] can never have
while(counter != COUNT_N)
{
...
if(prev == rowdata[0])
{
counter++;
}
else
{
counter=0;
}
prev = rowdata[0];
}
just to elaborate on Lundins Answer wich is the way to go in my opinion (would have posted as a comment, but lacking reputation...)
Only thing missing is the actual loop advancement counter (counter3 in your example):
int quitCounter=0; // Counter for quiting the loop on 3 consecutive identical values
int loopCounter=0; // Your normal rowdata index
const int QUIT_COUNT_N = 3;
#define FORBIDDEN 0xffffff // or some other value that rowdata[0] can never have
data_t prev=FORBIDDEN; // a value
do
{
...
/* do loop body, provide new value for rowtotal[0] on each iteration */
/* if you need to store the consecutive values returned in rowtotal[0] in costcheck array,
make sure that it will be big enough - if you only need to break on 3 identical values,
you can skip the entire costcheck array as Lundin proposes. */
...
costcheck[counter3]=rowtotal[0];
if(prev == costcheck[counter3])
{
quitCounter++;
}
else
{
quitCounter=0;
}
prev = costcheck[counter3];
counter3++;
} while(quitCounter!= QUIT_COUNT_N )
If you really want an infinite loop, a if(costcheck[counter-1] == costcheck[counter-2] && costcheck[counter-2] == costcheck[counter-3]) will lead to failure of program, if costcheck array has less than 3 elements. You have to be sure that it does have at least 3 elemets in this array.
BUT!!!! counter does not need to be more than 3 because as far as i get it, you want to check 3 most reciently read elements. Which means for comparison, you only need to remember 3 last values that were read.
The exapmple below stores up to 3 rowtotal[0] values, and checks if they are equal. If they are, progarm exits, if not, program gets new rowtotal[0] to the "end" of costcheck array, also the oldest value: here it's costcheck[0] is lost.
I can post the code to the example which i made, to show how the logic should work.
NOTE!!! I strongly think Lundin's and Morphine's solutions are by far better than mine.
do
{
.............
if(counter < 3)
{
costcheck[counter] = rowtotal[0];
counter++;
continue;
}
else
{
if(costcheck[counter-1] == costcheck[counter-2] && costcheck[counter-2] == costcheck[counter-3])
{
response=1;
}
else
{
costcheck[counter-3] = costcheck[counter-2];
costcheck[counter-2] = costcheck[counter-1];
costcheck[counter-1] = rowtotal[0];
}
}
}
while(response!=1);
}
i have a problem in c like this:
I have a problem in the code below. The problem is this that i doing some addition part after both if conditions break.And that addiion is repeatative while loop until count>0 The problem is if i put braces in for loop then it repeats the the part inside the braces until it's condition is not false. Buti have to do addition which is like this:
We have an array data[i].freq={0,1,2,3,4,5} and data[i].next represents the next member to be added.Suppose i add 0 and 1 first i got"1" as a result and i put the result in last index of my array , like this ({0 1 2 3 4 5 1})now 0 and 1 cann not be added because they are already added(i don't have to repeat the addition on same elements), so next time the addition will be between the last index element and smallest element before the last element (but not those elements who are already added). so here the addition will be between the "1" in last index+ smallest element in right to it which is "2" Note here we have not taken in acount 0 and 1 because they are already added, the same way this 2 will not be added next time because it is being added this time and their addition wil be {0 1 2 3 4 5 1 3} we have to repeat the same until there left & element at last.
data[data_size].freq=data[i].freq+data[p].freq; // here i add the first 2 elements "0" and "1" in the example i given below.
int count=5;
do
{
for(i=0;data[i].next!=-1;i=data[i].next)//the problem is here if i put bracesit dont't do the ask which i expect it to do.
if(data[data[i].next].freq>data[data_size].freq && data[data[i].next].flag==0)
break;
data[data_size+1].freq= data[data_size].freq+ data[data[i].next].freq;
data[data_size].next=data[i].next;
data[i].next=data_size;
data_size++;
if(data[data[i].next].freq<data[data_size].freq && data[data[i].next].flag==0)
break;
data[data_size+1].freq= data[data_size].freq + data[i].freq
data[data_size].next=data[i].next;
data[i].next=data_size;
data_size++;
count--;
} while(count>0)
could any one please help me in desiging the code for what i want to achieve.
If you write
for(i=0 ..any condition)
if(condition1)
break;
if(condition2)
break;
you don't only have an unreadable mess, but you also have only the first if clause in the for loop.
If you want the for loop to extend over both, you must put them into {}:
for(...) {
if(condition1) break;
if(condition2) break;
}
My personal preference is to always use braces when the statements are in the next line. S don't write
if(condition1)
break;
as someone could be tempted to insert an andditional statement and be surprised that it doesn't work as it should, but either do
if(condition1) break;
in one line or
if(condition1) {
break;
}
add braces which are not needed for functionality, but for readability.
This is how the compiler sees your code:
int count=5;
do
{
for (i = 0; data[i].next != -1; i = data[i].next)
{
if (data[data[i].next].freq > data[data_size].freq && data[data[i].next].flag == 0)
break; // break out of the enclosing 'for' loop (goes to point A)
}
// Point A
data[data_size].next = data[i].next;
data[i].next = data_size;
data_size++;
if (data[data[i].next].freq < data[data_size].freq && data[data[i].next].flag == 0)
{
break; // break out of the outer 'do' loop (goes to point B)
}
data[data_size].next = data[i].next;
data[i].next = data_size;
data_size++;
count--;
} while (count > 0);
// Point B
Based on your code comments, I think your problem is that your 'break' statements are not taking you where you think they're taking you.
How can i give the continue statement to force the next iteration of the outer loop to take place?
for(i=0;i<strlen(name1);i++) // Outer Loop
{
for(j=0;j<strlen(name2);j++) //inner Loop
{
if(name1[i]==name2[j])
{
name1[i]='*';
continue; //If i continue here the inner loops's newxt iteration takes place
}
}
}
for(i=0;i<strlen(name1);i++) // Outer Loop
{
for(j=0;j<strlen(name2);j++) //inner Loop
{
if(name1[i]==name2[j])
{
name1[i]='*';
break; // <-- break out of loop
}
}
}
The answer by acme is perfectly correct for your code. & that should be accepted answer. I just want to address a case, when there is some more code after inner loop.
Original code:
for(i=0;i<strlen(name1);i++) // Outer Loop
{
for(j=0;j<strlen(name2);j++) //inner Loop
{
if(name1[i]==name2[j])
{
name1[i]='*';
continue; //If i continue here the inner loops's newxt iteration takes place
}
}
// <some more code here....>
}
Change it to:
for(i=0;i<strlen(name1);i++) // Outer Loop
{
for(j=0;j<strlen(name2);j++) //inner Loop
{
if(name1[i]==name2[j])
{
name1[i]='*';
break; // come out of inner loop.
}
}
if(j<strlen(name2)) // check if there was a conditional break.
continue; // skip remaining code, after inner for loop.
// <some more code here....>
}
NOTE1: Try to avoid checking of strlen() in for loop, if possible. It gets evaluated every iteration. If the string is not going to change, you can evaluate it once, store in a variable (say len_name1) & use that variable as i<len_name1, instead of function call in loop.
NOTE2: If there are multiple break statements in the inner for loop & you want to differentiate between the 2 break statement, you can set a flag just before breaking & based on its value, instead of using if(j<strlen(name2)).