Understanding shorthand C++ [closed] - c++

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have this code in my C++ book, and I am unsure what this code means:
for ( ; counter < fooCnt &&
(toLower(array[counter].getFooTitle()).find(x) == string::npos)
; counter++);
This is all on one line, Is there another way this code could be written? I do not understand also why is there a ";" before a variable in the beginning of the for loop....

clause 1 in a for-loop is optional. It says to loop until array[counter].getFooTitle()).find(x) is not equal to string::npos or counter >= fooCnt
&& is the short-circuit AND operator. Go back to your truth tables if your forgot this part.
counter < fooCnt && (toLower(array[counter].getFooTitle()).find(x)==string::npos) is expression-2 and counter++ is expression-3
counter is incremented thusly.
in 6.8.5.3 of the C standard:
1774 The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows:
1775 The expression >expression-2 is the controlling expression that
is evaluated before each execution of the loop body.
1776 The expression expression-3 is evaluated as a void expression
after each execution of the loop body.
1777 If clause-1 is a declaration, the scope of any
identifiers it declares is the remainder of the declaration and the
entire loop, including the other two expressions;
1778 it is reached in the order of execution before the first
evaluation of the controlling expression.
1779 If clause-1 is an expression, it is evaluated as a void
expression before the first evaluation of the controlling
expression.134)
1780 Both clause-1 and expression-3 can be omitted.
1781 An omitted expression-2 is replaced by a nonzero constant.
By the way, a for-loop can also be thought of like a while loop.

You could write it like this
int counter = 0;
bool IsNotFound = (toLower(array[counter].getFooTitle()).find(x)==string::npos);
for(;counter < fooCnt && IsNotFound;counter++)
{
// do stuff
//update IsNotFound for next iteration
IsNotFound =(toLower(array[counter].getFooTitle()).find(x) == string::npos);
}
It will loop only if IsNotFound is true.

It's the same as
for ( counter = counter; counter < fooCnt; counter++ ) {
if (toLower(array[counter].getFooTitle()).find(x) != string::npos) break;
}
e.g. counter goes from its current value, increasing by 1, until fooCnt. But if any of the titles are found, it stops early.

I will try to explain this line. At first a for loop looks like this for(init part; condition part; part for the next step). So the first ; means that the init part was skipped. Normally after the for statment is code which gets executed but in this case it was skipped with the colon.
in the condition check is this code:
counter<fooCnt && (toLower(array[counter].getFooTitle()).find(x)==string::npos)
if the condition counter<fooCnt is true the folowing code will be executed:
toLower(array[counter].getFooTitle()).find(x)==string::npos
at least after every loop the counter is increaded.
counter++

Is there another way this code could be written?
It might be clearer as
while (counter < fooCnt &&
(toLower(array[counter].getFooTitle()).find(x)==string::npos))
{
++counter;
}
i.e. while we haven't reached the limit, and we haven't found x, move on to the next one. Equivalently, loop until we reach the limit or we find x.
I do not understand also why is there a ";" before a variable in the beginning of the for loop
The for statement has three clauses, as in
for (int i = 0; i < n; ++i)
The first declares and/or initialises variables to be used in the loop - it can be empty if, as here, you don't want any. The second is evaluated before each iteration to decide whether to continue - it can be empty if you always want to continue. The third is evaluated after each iteration - it can be empty if there's nothing to update between iterations.

Yeah that's pretty ugly. I would break it down a bit.
int i = 0;
for(; i < fooCnt; ++i) {
auto lowcase = toLower(array[i].getFooTitle());
if(lowcase.find(x) != string::npos) {
break;
}
}

Related

Does the number of iterations of the 'for' loop change if the second argument changes in one of the iterations?

i've this code here:
for(i = openGates[0]; i < closeGates[0]; i++) {
if(str[i] == '(') {
closeGates.removeFirst();
openGates.removeAt(1);
}
}
If brace found, closeGates[0]'s value will change. Will it change the number of iterations?
Yes, the iteration-expression is executed after every iteration of the loop.
Reference for this answer :
https://en.cppreference.com/w/cpp/language/for
Apparently, no one decided to answer and I want to close this question so: yes, in C++ 'for' loop evaluates its conditions before every iteration thus the number of the iterations might change.

C for loop syntax understanding

I am doing a program for tic-tac-toe and i have a line with
for ( count = 1; count < 10 && winner == 0; count++ );
I referred to other programs and came up with this.
And I'm not very sure of what the entire line means. I have searched up online but I dont understand the meaning of initialization statement ( count = 1 ) and the test expression. And also want to clarify, count++ means increase count right?
Let's have a look at the structure of a for loop:
for ( init-statement; condition; iteration_expression) statement;
From cppreference, a for loop does the following:
Executes init-statement once, then executes statement and iteration_expression repeatedly, until the value of condition becomes false. The test takes place before each iteration.
For your case:
init statement: at the beginning count is initialized to 1
condition: check if count is less than 10 and you don't have a winner yet
iteration_expression: cout++ increases count by 1
statement: you haven't provided that, but it will be executed until the condition is false.
Syntax of for loop is
for(initialization; condition; increment/decrement){
statement;
}
initialization:
Before we start looping, we will initialize the variable to certain value.
In this case, you are initializing 'count' variable to 1
Condition:
In condition part, To stop the loop at certain point you have to provide some conditions.
In this case, condition is 'count<10 && winner==0'. Note that, you are using And(&&) operation so, loop will stop only after both of the conditions are satisfied.
increment/decrement:
Based on the problem, you can choose to increment or decrement the loop variable('count'). In this case, count++ means you are incrementing the count by 1 after each iteration.
for (initialize;condition;increment/decrement)
for loop means
you initialize the variable
you apply a condition to stop the for loop
you execute a single time the loop body (if the condition satisfied)
then you increase or decrease the value of that variable and go to step 2

What is this syntax in while loop condition?

while ( (i=t-i%10 ? i/10 : !printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
I came across this on codegolf
Please explain the usage of ? and : and why is there no statement following the while loop? As in why is there a ; after the parenthesis.
There is a boolean operation going on inside the parentheses of the while loop:
while (boolean);
Since the ternary operator is a boolean operator, it's perfectly legal.
So what's this doing? Looks like modular arithmetic, printing going on over a range up to 101.
I'll agree that it's cryptic and obscure. It looks more like a code obfuscation runner up. But it appears to be compilable and runnable. Did you try it? What did it do?
The ?: is a ternary operator.
An expression of form <A> ? <B> : <C> evaluates to:
If <A> is true, then it evaluates to <B>
If <A> is false, then it evaluates to <C>
The ; after the while loop indicates an empty instruction. It is equivalent to writing
while (<condition>) {}
The code you posted seems like being obfuscated.
Please explain the usage of ? and :
That's the conditional operator. a ? b : c evaluates a and converts it to a boolean value. Then it evaluates b if its true, or c if its false, and the overall value of the expression is the result of evaluating b or c.
So the first sub-expression:
assigns t-i%10 to i. The result of that expression is the new value of i.
if i is not zero, the result of the expression is i/10
otherwise, print j, and the result of the expression is zero (since printf returns a non-zero count of characters printed, which ! converts to zero).
Then the second sub-expression, after ||, is only evaluated if the result of the first expression was zero. I'll leave you to figure out what that does.
why is there no statement following the while loop?
There's an empty statement, ;, so the loop body does nothing. All the action happens in the side effects of the conditional expression. This is a common technique when the purpose of the code is to baffle the reader; but please don't do this sort of thing when writing code that anyone you care about might need to maintain.
This is the Conditional Operator (also called ternary operator).
It is a one-line syntax to do the same as if (?) condition doA else (:) doB;
In your example:
(i=t-i%10 ? i/10 : !printf("%d\n",j)
Is equivalent to
if (i=t-i%10)
i/10;
else
!printf("%d\n",j);
?: is the short hand notation for if then else
(i=t-i%10 ? i/10 : !printf("%d\n",j)<br>
equals to
if( i= t-i%10 )
then { i/10 }
else { !printf("%d\n",j) }
Your while loop will run when the statement before the || is true OR the statement after the || is true.
notice that your code does not make any sense.
while ( (i=t-i%10 ? i/10 : !printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
in the most human-readable i can do it for u, it's equivalent to:
while (i < 101)
{
i = (t - i) % 10;
if (i > 0)
{
i = i / 10;
}
else
{
printf("%d\n",j);
}
i = ++j;
if (i < 0)
{
i = i - j;
}
else
{
i = j;
}
}
Greetings.
I am the proud perpetrator of that code. Here goes the full version:
main()
{
int t=getchar()-48,i=100,j=-i;
while ((i=t-i%10?i/10:!printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
}
It is my submission to a programming challenge or "code golf" where you are asked to create the tinniest program that would accept a digit as a parameter and print all the numbers in the range -100 to 100 that include the given digit. Using strings or regular expressions is forbidden.
Here's the link to the challenge.
The point is that it is doing all the work into a single statement that evaluates to a boolean. In fact, this is the result of merging two different while loops into a single one. It is equivalent to the following code:
main()
{
int i,t=getchar()-'0',j=-100;
do
{
i = j<0? -j : j;
do
{
if (t == i%10)
{
printf("%d\n",j);
break;
}
}
while(i/=10);
}
while (j++<100);
}
Now lets dissect that loop a little.
First, the initialisation.
int t=getchar()-48,i=100,j=-i;
A character will be read from the standard input. You are supposed to type a number between 0 and 9. 48 is the value for the zero character ('0'), so t will end up holding an integer between 0 and 9.
i and j will be 100 and -100. j will be run from -100 to 100 (inclusive) and i will always hold the absolute value of j.
Now the loop:
while ((i=t-i%10?i/10:!printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
Let's read it as
while ( A || B ) /* do nothing */ ;
with A equals to (i=t-i%10?i/10:!printf("%d\n",j)) and B equals to (i=++j<0?-j:j)<101
The point is that A is evaluated as a boolean. If true, B won't be evaluated at all and the loop will execute again. If false, B will be evaluated and in turn, if B is true we'll repeat again and once B is false, the loop will be exited.
So A is the inner loop and B the outer loop. Let's dissect them
(i=t-i%10?i/10:!printf("%d\n",j))
It's a ternary operator in the form i = CONDITION? X : Y; It means that first CONDITION will be evaluated. If true, i will be set to the value of X; otherwise i will be set to Y.
Here CONDITION (t-i%10) can be read as t - (i%10). This will evaluate to true if i modulo 10 is different than t, and false if i%10 and t are the same value.
If different, it's equivalent to i = i / 10;
If same, the operation will be i = !printf("%d\n",j)
If you think about it hard enough, you'll see that it's just a loop that checks if any of the decimal digits in the integer in i is equal to t.
The loop will keep going until exhausting all digits of i (i/10 will be zero) or the printf statement is run. Printf returns the number of digits printed, which should always be more than zero, so !printf(...) shall always evaluate to false, also terminating the loop.
Now for the B part (outer loop), it will just increment j until it reaches 101, and set i to the absolute value of j in the way.
Hope I made any sense.
Yes, I found this thread by searching for my code in google because I couldn't find the challenge post.

No checking condition in for loop C++

char i;
for (i = 1; i < 10, i++;)
{
cout << (i+1) << endl;
}
return 0;
I understand that for loop has the following syntax:
for(initialization; condition; increment)
{
}
As I run the debug, why it never checks the condition and it eventually stops at i = 0?
(Thank you Damien and Andars, I don't know why the "on purpose" statement was removed, but you interpret my question correctly. Could someone explain why the complier skips the condition before the comma, and why the loop stop at i = 0 instead of looping forever? Thanks!)
I believe he is indicating that he wrote the code that way on purpose.
To answer, i++ will always return true. The last value is the value that matters with comma separated statements, so the loop will not stop.
Edit for elaborations:
It isn't simply using a logical or, it disregards what is before the comma and only takes the last value. The value of anything non-zero is considered true, and since i starts at 1, and goes up, it will always be non-zero (until it overflows and wraps back around, which explains why i ends at 0).
If you say:
x = 4, 5, 6;
x will be equal to 6, the last value.
Change
for (i = 1; i < 10, i++;)
to
for (i = 1; i < 10; i++)
Change to
for (i = 1; i < 10; i++) //Notice correct placement of ;
It seems to me also that the code was written incorrectly on purpose. As others have mentioned, the comma operator will discard the value of the i<10 and only i++ will be evaluated as condition. This will return true until i overflows (values only from -127 to 127) and ends up at -1, when i++ will return 0 and the loop exits. Thus the final value for i will be 0.
Because you used the comma operator instead of a semi-colon

What does "for(;;)" mean?

In C/C++, what does the following mean?
for(;;){
...
}
It's an infinite loop, equivalent to while(true). When no termination condition is provided, the condition defaults to false (i.e., the loop will not terminate).
In C and C++ (and quite a few other languages as well), the for loop has three sections:
a pre-loop section, which executes before the loop starts;
an iteration condition section which, while true, will execute the body of the loop; and
a post-iteration section which is executed after each iteration of the loop body.
For example:
for (i = 1, accum = 0; i <= 10; i++)
accum += i;
will add up the numbers from 1 to 10 inclusive.
It's roughly equivalent to the following:
i = 1;
accum = 0;
while (i <= 10) {
accum += i;
i++;
}
However, nothing requires that the sections in a for statement actually contain anything and, if the iteration condition is missing, it's assumed to be true.
So the for(;;) loop basically just means:
don't do any loop setup;
loop forever (breaks, returns and so forth notwithstanding); and
don't do any post-iteration processing.
In other words, it's an infinite loop.
Loop until some break, exit, throw etc. statement inside the loop executes. Basically, you can think of a for loop as consisting of:
for (setup; test; advance)
...
If the "test" is empty it's considered to be true, and the loop keeps running. Empty "setup" and "advance" simply do nothing.
An infinite loop which continues until there is a break, exit, or goto statement.
Even if this answer suggests that both constructs are equivalent, there's a subtle difference between both for(;;) and while(1) (which both create infinite loops) in the C language (and possibly compiler-dependent).
Some compilers (Windriver DIABData for instance) complain about "condition is always true" when using while(1).
Changing to for(;;) allows to get rid of the warning, probably because the latter expression is semantically stronger to create an infinite loop on purpose, and there is no "always true" condition at all (plus it's shorter to write).
On the other hand, the C++ language doesn't make a difference about both constructs as Adrian stated in comments:
The C++ standard states that a missing condition makes the implied while clause equivalent to while(true) and for ( for-init-statement condition opt ; expression opt ) statement is equivalent to { for-init-statement while ( condition ) { statement expression ; } }