Ternary operator inside a return statement - c++

I was writing a recursive function, and encountered a problem at the return statement.
int SumOfEvenNumbers(int v[], int i)
{
if ( i > v[0] )
return 0;
return SumOfEvenNumbers(v, i+1) + (v[i]%2==0)?v[i]:0;
}
The function is called like this:
SumOfEvenNumbers(vector_indexed_from_1, 1);
//v[0] is equal to the number of elements, excluding itself
What I expected the ternary if to return was either v[i] or 0 ( in case it is even ) but apparently after printing the result of every ternary if to the screen, the only values that result from the expression are 1 and 0.
int SumOfEvenNumbers(int v[], int i)
{
if ( i > v[0] )
return 0;
cout << (v[i]%2==0)?(v[i]):(0); // either a 1 or a 0
return SumOfEvenNumbers(v, i+1) + (v[i]%2==0)?v[i]:0;
}
The way I fixed this is by initializing a variable with the result of the expression and then adding that to the return value.
int SumOfEvenNumbers(int v[], int i)
{
if ( i > v[0] )
return 0;
int rv = (v[i]%2==0)?(v[i]):(0);
return SumOfEvenNumbers(v, i+1) + rv;
}
Could anyone explain what is happening? Is it possible to avoid declaring a variable in order to obtain the correct result?

The ternary conditional operator has lower precedence than operator+.
Your code was actually parsed as
(SumOfEvenNumbers(v, i+1) + (v[i]%2==0)) ? v[i] : 0;
To get what you want, use parentheses
SumOfEvenNumbers(v, i+1) + ((v[i]%2==0)) ? v[i] : 0);
See: http://en.cppreference.com/w/c/language/operator_precedence

Could anyone explain what is happening?
Take a look at operator precedence. Here ternary conditional happens to have very low priority. In SumOfEvenNumbers(v, i+1) + (v[i]%2==0)?v[i]:0 expression it is calculated after + given you unexpected result.
Is it possible to avoid declaring a variable in order to obtain the correct result?
I cases when you are not sure about order of operators it is safe to use brackets () to indicate the order explicitly. So SumOfEvenNumbers(v, i+1) + ((v[i]%2==0)?v[i]:0) will be calculated as expected.

Related

The compiler doesnt show errors but I get no output. Whats wrong?

I'm supposed to write a small code that generates a random number between 2 and 100 and then checks if its a perfect number. I don't get any bugs from the compiler but the output doesn't show my cout lines like " x is a perfect number". Can someone help me with finding the reason?
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
bool PerfectCheck(int x) {
int t; // divisor
int sum; // sum of divisors
for (t = 0; t <= x; t++ ) {
if (x%t == 0) {
sum = sum + t;
}
}
if (sum == x)
return true;
else
return false;
}
int main() {
srand(time(NULL));
int x = rand()%(100-2+1)+2;
if (PerfectCheck(x) == true )
cout << x << "is a perfect number.";
else
cout << x << "is not a perfect number.";
return 0;
}
There are three problems in your PerfectCheck function. First, you don't initialize the sum variable, so it can start off with any value whatsoever; you should set it to zero explicitly in the declaration.
Second, your for loop starts with t as zero, and you check x % t. The modulo operator implicitly involves a division, so using a left-hand value of zero has the same issue as trying to divide by zero, which will cause a crash.
Third, when checking for a perfect number, don't use that number itself in the sum; so, stop your loop with t < x instead of t <= x.
Also, as mentioned in the comments, you can simplify the return statement. The code below works, in the tests I have performed:
bool PerfectCheck(int x)
{
int sum = 0; // sum of divisors - MUST BE INITIALIZED (to zero)
for (int t = 1; t < x; t++) { // DO NOT INCLUDE X ITSELF!!
if (x % t == 0) {
sum += t;
}
}
return (sum == x); // This will already give a "true" or "false" bool value.
}
You could actually make the code a tiny bit more 'efficient', by initializing sum to 1 and then starting the loop from t = 2 (all numbers divide by 1, after all).
Feel free to ask for further clarification and/or explanation.
if (x%t == 0) calculates the remainder after dividing x by t and compares the result with 0. That statement is correct, but look at the previous code for (t = 0; t <= x; t++ ) {. The first value of t is 0, so you have a division by zero. More than likely that is crashing your program which is why you see no output. Change for (t = 0; t <= x; t++ ) { to for (t = 1; t <= x; t++ ) {.
Also I believe the definition of a perfect number does not include division by the number itself. So the for loop should actually be for (t = 1; t < x; t++ ) {.
Finally you are using the sum variable to add up the divisors but you do not give it an initial value. Your code should say int sum = 0;.
Three errors in a ten line program (plus various style issues). Imagine how many errors here might be in a 5000 line program. Programming is tricky, you have to be very focused and get your code exactly right, nearly right is not good enough.

Is there a more efficient way of checking if an element is inside given intervals?

Suppose I have a variable x (double) that lies between 0 and 100. If x is in any of the intervals (0+10*n,5+10*n), with n (int) =0,...,9, then I return n, otherwise I break. I was thinking of doing this
bool test = false;
int k;
for(int i=0; i<10; i++){
if((0+10*i)<x<(5+10*i)){
k = i;
test = true;
}
}
if(test) return k;
else break;
would this be correct? If so, is there any other way that avoids loops?
It depends which intervals you have in mind. Since your intervals have a pattern to them, you can use a mathematical formula instead of a loop:
if(((int)x % 10) < 5) return (int)(x / 10);
else break;
(The % here is the modulo operator.)
Since C++'s % operator doesn't work on doubles, you can either cast x to an integer (as shown), or use the fmod function (works for non-integer intervals).
you can use % operator to get it's mod. get x % 10 and check if result of mod between 0 and 5. it can be faster than that.

What is the use of "and N" in this code?

C++ Code:
#include<iostream>
using namespace std;
int main()
{
int N;
cin>>N;
int *A = new int[N];
int i=0;
for(i=0;i<N;i++)
cin>>A[i];
while(cout<<A[--N]<<' ' and N);
delete[] A;
return 0;
}
Print the integers of the array in the reverse order in a single line separated by a space.
Does anyone know what is "and N" do in cout statement?
It's a cryptic way of writing:
while( (cout<<A[--N]<<' ') and (N != 0) );
// output is successful and N is not equal to zero.
It could be written more clearly as:
for ( ; N != 0; --N)
{
cout << A[N-1] << ' ';
}
Since it's theoretically possible for N to be negative, it will be better to use:
for ( ; N > 0; --N)
{
cout << A[N-1] << ' ';
}
N is an integer variable, value of type int can be implicitly converted to bool (non zero becomes true and zero becomes false). So the expression basically sais execute when result of operator<< converted to bool is true and N is not equal to zero. Logically this code
while(cout<<A[--N]<<' ' and N);
is equal to:
do {
bool b1 = cout<<A[--N]<<' ';
bool b2 = N;
} while( b1 and b2 );
actual code is a little different due to short circuit but that differences are unimportant in this case.
The part and N that can be also written like && N of the while statement
while(cout<<A[--N]<<' ' and N);
that as it has been pointed out can be rewritten like
while(cout<<A[--N]<<' ' && N != 0);
checks that N that is being decreased (A[--N]) in each iteration of the loop is not equal to 0.
So the loop outputs elements okf the array in the reverse order.
The word and is a so-called alternative token for the primary token &&.
It is just a way of writing the code by some programmers.
It is actually written as
while( (cout<<A[--N]<<' ') and (N != 0) );
Basically 'and' operator returns true when both operands are non zero values.
So cout will give number of characters it printed which will be non zero in this case and until the value of N becomes zero your loop will be execute.

C++ ? operator with continue operator in for loop

I have a method which looks like this:
bool Perfect(int num) {
int sum = 0;
for (int i = 1; i < num; i++)
{
num%i == 0 ? sum += i : continue;
}
return sum == num ? true : false;
}
I'm trying to combine here ? operator with continue operator...
So logically if the statement here is false in this line:
num%i == 0 ? sum += i : continue;
I will just skip the iteration or do nothing?
If I do it like this the compiler reports an error like:
expected an expression
And in case like this:
num%i == 0 ? sum += i
It says:
Expected a ':'
Is there any way to use continue with ? operator or just simply avoid false case somehow ???
bool Perfect(int num) {
int sum = 0;
for (int i = 1; i < num; i++)
{
if(num % i == 0)
sum += i;
}
return sum == num;
}
Use an if statement. No need of continue since you have no other statement after sum += i.
C++ and C have both statements and expressions (notice that an assignment or a function call is an expression, and that expressions are statements). They are different syntactic (and semantical) things.
You could have coded (but this is weird style as a statement reduced to a ?: conditional expression) inside your for loop:
(num%i == 0) ? (sum += i) : 0;
(when num%i is non-zero, that evaluates to 0 which has no significant side effect; BTW that last occurrence of 0 could be 1234 or any constant integral expression)
Some programming languages (notably Scheme, read SICP) have only expressions (and no statements).
The ternary ?: operator applies to expressions and gives an expression (so can't be used for statements).
Conditional statements use the if keyword. In your case it is much more readable (because you are using sum += i only for its side effect) and an if statement is here easier to understand.
You can't use a ternary operator in this way. You would normally use it for assigning a value to a variable based on an expression being true or false. Eg.
int j, i,
j = (i == 2) ? 5: 10;
If i is equal to 2 then j is given the value of 5 else if i is not equal to 2 then j is given the value of 10.

Can someone explain this if statement for me?

I'm new to programming, can someone take two minutes to explain this statement for me? how can I write it like this :
if (condition) {...} else {...}
if (myFunction(i == 8? (j + 1): j, (j + 1) % 9))
{
return true;
}
The function is called with two arguments. First one uses a ternary operator to check if i (the index) is 8; if so, increment j, else leave j as is.
Second argument increments j by 1, it uses primary expression operator around j+1 because arithmetic + has lower precedence than modulus (%) http://www.swansontec.com/sopc.html. If j is 1 and we increment by 1, then 2 % 9 is 2, since the modulo operation returns the remainder. This assumes C style syntax.
int arg1 = i == 8 ? (j + 1) : j;
int arg2 = (j + 1) % 9;
if (myFunction(arg1,arg2))
{
return true;
}
else
{
return false;
}