Below is the recursive function for sum of natural numbers up to n.
int calculateSum(int n) {
if (n == 0){
return 0;
}else{
return n + calculateSum(--n); //Replacing --n with n-1 works
}
}
Input: 5
If I use --n then the output is 10, but when I replace --n with n - 1 then the correct result is returned (15). Why the difference?
As surprising as it might be, the behaviour of the expression
n + calculateSum(--n);
is undefined, because --n not only evaluates to the value of n after being decremented by 1, it also changes n to the new value. The change (a side effect), however, is unsequenced in relation to the other evaluation of n (a value computation) on the left. And according to C11 Appendix J.2., the behaviour is undefined, when
A side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object (6.5).
More of the same class of errors in this question.
You can consider yourself lucky when you got a wrong value, because your compiler could have also generated code that would return the "correct value"... given the phase of the moon, and the optimization settings, or the number of lines in the calling function...
--n also modifies the local variable n; the expression n-1 just returns the decremented value to pass it on to the recursive call, but does not modify your input-parameter.
In detail for the first iteration with input 5:
Correct is return 5 + calculateSum(5-1);
With --n you would also decrement from n and end up with 4 + calculateSum(4)
#user3386109 & #Yunnosch worded it this way:
With --n you calculate the sum 0...(5-1) instead of 0...5.
See #Antti answer, it explains that it's actually undefined behaviour.
The following code snippet (a Function), you can call it in the main function which will return the sum of n natural numbers recursively
int NNumbers(int n)
{
if(n != 0)
return n + NNumbers(n-1);
else
return n;
}
In your code you are decrementing the value of n and then you are calculating the sum (i,e. Pre-Decrement), since the input is 5, it decrements 1 at each iteration and and then it will go for addition of natural numbers. so you are getting the result 10 instead of 15
Hope this helps for you :)
Thank you
Related
The following code prints a value of 9. Why? Here return(i++) will return a value of 11 and due to --i the value should be 10 itself, can anyone explain how this works?
#include<stdio.h>
main()
{
int i= fun(10);
printf("%d\n",--i);
}
int fun (int i)
{
return(i++);
}
There is a big difference between postfix and prefix versions of ++.
In the prefix version (i.e., ++i), the value of i is incremented, and the value of the expression is the new value of i.
In the postfix version (i.e., i++), the value of i is incremented, but the value of the expression is the original value of i.
Let's analyze the following code line by line:
int i = 10; // (1)
int j = ++i; // (2)
int k = i++; // (3)
i is set to 10 (easy).
Two things on this line:
i is incremented to 11.
The new value of i is copied into j. So j now equals 11.
Two things on this line as well:
i is incremented to 12.
The original value of i (which is 11) is copied into k. So k now equals 11.
So after running the code, i will be 12 but both j and k will be 11.
The same stuff holds for postfix and prefix versions of --.
Prefix:
int a=0;
int b=++a; // b=1,a=1
before assignment the value of will be incremented.
Postfix:
int a=0;
int b=a++; // a=1,b=0
first assign the value of 'a' to 'b' then increment the value of 'a'
The function returns before i is incremented because you are using a post-fix operator (++). At any rate, the increment of i is not global - only to respective function. If you had used a pre-fix operator, it would be 11 and then decremented to 10.
So you then return i as 10 and decrement it in the printf function, which shows 9 not 10 as you think.
In fact return (i++) will only return 10.
The ++ and -- operators can be placed before or after the variable, with different effects. If they are before, then they will be processed and returned and essentially treated just like (i-1) or (i+1), but if you place the ++ or -- after the i, then the return is essentailly
return i;
i + 1;
So it will return 10 and never increment it.
There are two examples illustrates difference
int a , b , c = 0 ;
a = ++c ;
b = c++ ;
printf (" %d %d %d " , a , b , c++);
Here c has value 0 c increment by 1 then assign value 1 to a so value
of a = 1 and value of c = 1
next statement assiagn value of c = 1 to b then increment c by 1 so
value of b = 1 and value of c = 2
in printf statement we have c++ this mean that orginal value of c
which is 2 will printed then increment c by 1 so printf statement
will print 1 1 2 and value of c now is 3
you can use http://pythontutor.com/c.html
int a , b , c = 0 ;
a = ++c ;
b = c++ ;
printf (" %d %d %d " , a , b , ++c);
Here in printf statement ++c will increment value of c by 1 first then
assign new value 3 to c so printf statement will print 1 1 3
The postfix increment ++ does not increase the value of its operand until after it has been evaluated. The value of i++ is i.
The prefix decrement increases the value of its operand before it has been evaluated. The value of --i is i - 1.
Prefix increment/decrement change the value before the expression is evaluated. Postfix increment/decrement change the value after.
So, in your case, fun(10) returns 10, and printing --i prints i - 1, which is 9.
i++ is post increment. The increment takes place after the value is returned.
First, note that the function parameter named i and the variable named i in main() are two different variables. I think that doesn't matter that much to the present discussion, but it's important to know.
Second, you use the postincrement operator in fun(). That means the result of the expression is the value before i is incremented; the final value 11 of i is simply discarded, and the function returns 10. The variable i back in main, being a different variable, is assigned the value 10, which you then decrement to get 9.
Explanation:
Step 1: int fun(int); Here we declare the prototype of the function fun().
Step 2: int i = fun(10); The variable i is declared as an integer type and the result of the fun(10) will be stored in the variable i.
Step 3: int fun(int i){ return (i++); } Inside the fun() we are returning a value return(i++). It returns 10. because i++ is the post-increement operator.
Step 4: Then the control back to the main function and the value 10 is assigned to variable i.
Step 5: printf("%d\n", --i); Here --i denoted pre-increement. Hence it prints the value 9.
Let's keep this as simple as possible.
let i = 1
console.log('A', i) // 1
console.log('B', ++i) // 2
console.log('C', i++) // 2
console.log('D', i) // 3
A) Prints the value of I.
B) First i is incremented then the console.log is run with i as it's the new value.
C) Console.log is run with i at its current value, then i will get incremented.
D) Prints the value of i.
In short, if you use the pre-shorthand i.e(++i) I will get updated before the line is executed. If you use the post-shorthand i.e(i++) the current line will run as if I had not been updated yet then i get increased so the next time your interpreter comes across i it will have been increased.
It has to do with the way the post-increment operator works. It returns the value of i and then increments the value.
Actually what happens is when you use postfix i.e. i++, the initial value of i is used for returning rather than the incremented one. After this the value of i is increased by 1. And this happens with any statement that uses i++, i.e. first initial value of i is used in the expression and then it is incremented.
And the exact opposite happens in prefix. If you would have returned ++i, then the incremented value i.e. 11 is returned, which is because adding 1 is performed first and then it is returned.
fun(10) returns 10. If you want it to return 11 then you need to use ++i as opposed to i++.
int fun(int i)
{
return ++i;
}
Suppose you are given arrays p[1......N] and q[1......N] both uninitialized, that is, each location may contain an arbitrary value), and a global variable count, initialized to 0. Consider the following procedures set and is_set:
set(i) {
count = count + 1;
q[count] = i;
p[i] = count;
}
is_set(i) {
if (p[i] ≤ 0 or p[i] > count)
return false;
if (q[p[i]] ≠ i)
return false;
return true;
}
A. Suppose we make the following sequence of calls:
set(7); set(3); set(9);
After this sequence of calls, what is the value of count, and what do q[1],q[2],q[3],p[7],p[3] and p[9] contain?
B. Complete the following statement "The first count elements of __________contain values i such that set (_________________) has been called".
C. Show that if set(i) has not been called for some i, then regardless of what p[i] contains, is_set(i) will return false.
I solved the A part and B part i.e q[1]=7 q[2]=3 q[3]=9 p[7]=1 p[3]=2 p[9]=3 and B will be The first count elements of q contain values i such that set(i) has been called.
I am confused with option C; it's a little tricky. Can someone help me to visualize it.
Let's assume you have called set(i_1),set(i_2),... n times.
Now you have count == n and q[1] == i_1, q[2] == i_2, ..., q[count] == i_count.
Then you call is_set(i) with i being different from all i_n.
First you access p[i] which still contains an arbitrary value v.
if v <= 0 or v > count, is_set(i) return false
otherwise (1 <= v <= count) we check q[v] which has been assigned before with i_v. And because i is different from all all i_n, i is different from i_v, thus is_set(i) returns false too
(Note since this question is tagged C: This answer assumes the elements of p and q behave as if they have values that are fixed but unknown at the time execution starts. The C standard does not make this guarantee; it permits an object which has not been initialized to behave as if it has a different value each time it is used.)
Consider a call is_set(i) for which there was no previous set(i). Assume is_set(i) returns true. Then p[i] ≤ 0 or p[i] > count must evaluate to false (or the return false would be executed), so p[i] has some value c that was the value of count in some previous call set(x) (although p[i] could have this value due to its initialize state, not due to the call set(x)).
That call set(x) set q[c] to x. Therefore q[p[i]] evaluates to q[c] and then to x, so q[p[i]] ≠ i is x ≠ i, which is true because there was a previous set(x) call but not, by our premise, a previous set(i) call. This causes the return false to be executed. That contradicts our assumption that is_set(i) returns true, so the assumption is false.
is_set(i) cannot return true when there was no previous set(i) call.
p[i] is some arbitrary value, call it x.
If x is <= 0 or > count, then the first "if" of is_set triggers and the result is false.
Otherwise, there was some call to set() made when count started out equal to x - 1. Let y be the argument to set() at that time. Then q[x] is equal to y. But we know that no call to set() was made with argument i, so y != i. Hence q[x] != i. But x is p[i], so q[p[i]] != i and the second if triggers and returns false.
This question already has answers here:
What is the difference between ++i and i++?
(20 answers)
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 4 years ago.
I've recently started trying to learn C & was doing an exercise that involved creating a recursive factorial function.
Why does the following print out an answer of 24?
#include <stdio.h>
int factorial(int n);
int main(void)
{
int n = 5;
printf("%d\n", factorial(n));
return 0;
}
int factorial(int n)
{
if (n <= 1)
return 1;
else
return n * factorial(--n);
}
If i change the last line to
return n * factorial(n - 1);
I get the expected 120.
I understand that you can't use n-- b/c it only decreases n after the line is processed but whats wrong with --n & why does it give 24?
whats wrong with --n & why does it give 24?
The problem is that --n modifies n, so your line
return n * factorial(--n);
may evaluate like:
return (n - 1) * factorial(n - 1);
because the factorial(--n) is evaluated before the n that is the first term of the expression. On the other hand, the first term could be evaluated before the second, and you'd get the result you expect. Or, something entirely different could happen, because (as M.M and David C. Rankin point out in comments) what happens when you try to use a variable and modify it in the same expression is undefined:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
So let's address your title question:
Does (--n) equal (n - 1)?
The values of --n and of n - 1 are the same, but the former expression has the side effect that it modifies n. You should really think of --n as being shorthand for the expression (n = n - 1).
i have written a small function which calculates factorial for a number in C
as follows:
int factNnumbers(int n)
{
if(n == 1)
return 1;
else
return (n*factNnumbers(--n));
}
I call the function shown above as:
factNnumbers(takeInputN());
where the function to take the input (takeInputN) is defined as:
int takeInputN()
{
int n;
printf("\n\nHow many numbers ?? \n ");
scanf("%d", &n);
return n;
}
If I change one line in my factorial code as shown below , my program works perfectly. Otherwise with the above code it prints the factorial of the number input -1 (example if number input is 5, it will print the factorial of 4). Why is this happening?.
int factNnumbers(int n)
{
if(n != 1)
return (n * factNnumbers(--n));
}
The problem is that you're both reading and modifying n in the same expression:
n * factNumbers(--n)
The evaluation of the n argument to * and of the --n subexpression are unsequenced, which gives your code Undefined Behaviour.
The easiest solution (and also, IMO, more expressive), is to say n - 1 where you mean it:
n * factNumbers(n - 1)
Your "improved" code in the bottom of the question is actually even more wrong. There, you have a control path which will return an unspecified value: a clear no-no.
Note: This answer was written while the question still had a C++ tag, and uses C++ terminology. The end effect in C is the same, but the terminology might be different.
You are invoking undefined behaviour, that it works in one version is just an accident:
return (n*factNnumbers(--n));
Do you use n first and then decrement it or the other way around? I don't know and neither does the compiler, it's free to do either of them or format your hard drive. Just use n * f(n - 1).
Also, your "working" version does not return for the n==1 case, which is illegal.
There are two causes of undefined behavior in your code:
Whether n or --n in n * factNnumbers(--n) will be evaluated first is unspecified.See this. You want just n * factNnumbers(n - 1), why decrement? You're not using decremented n afterwards (at least you didn't want to).
You're not returning a value on all control paths, what's going to be returned on n == 1? An indeterminate value that will mess up the whole result.
the rule of decrement:
X = Y-- first passes the value of I to X and decrements after
X = --I first pass and decrements the value decremented X
for your case, you decrement the value of parameter passed as argument to the function factNnumbers. Therefore remedy this error, I invite you to put (n-1) instead of (--n).
I think it’s better to use the tgamma function from math.h for double precision calculations involving factorials (such as Poisson distribution etc.): tgamma(n+1) will give you factorial(n).
Factorial function is increasing very fast, and this will work also for values too big to fit an integer type.
When n<=1 (or == 1 in your code), the factorial function has to return 1. Futhermore the your --n in you code is false and sould be n-1 as:
function factorial(n)
{
if (n<=1)
return 1;
else
return n * factorial(n-1);
}
My professor posted
int main(int argc, char **argv)
{
// enter code here
printf("Test 1: trying odd(3) AND even(2)...\n");
printf("%d\n", odd(3) && even(2));
printf("Test 2: trying odd(3) OR even(2)...\n");
printf("%d\n", odd(3) || even(2));
printf("Test 3: trying odd(4) AND even(7)...\n");
printf("%d\n", odd(4) && even(7));
printf("Test 4: trying odd(4) OR even(7)...\n");
printf("%d\n", odd(4) || even(7));
return 0;
}
int odd(int n)
{
printf("in odd!\n");
return n % 2 == 1;
}
int even(int r)
{
printf("in even!\n");
return r % 2 == 0;
}
as an assignment asking why lines 2 and 3 only return in odd! but 1 and 4 return in odd! and in even! I'm unsure as to why as I don't know the difference between the Return 1 and Return 0 commands. From what I can gather Return 1 will always return the value (in this case in odd!) but return 0 will only return it if it satisfies a certain condition?
Also: does the code int length(char *name,int start,double finish): return the length of a word in characters as a real number?
Thanks in advance to anyone that decides to help me.
This is called "Short-circuit evaluation".
...in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression...
Therefore, you have to figure out what will these two functions odd and even return:
odd(): If n % 2 == 1 , return 1, otherwise 0
even(): If n % 2 == 0 , return 1, otherwise 0
And in the main() function,
odd(3) AND even(2): odd(3) return 1, and check the return value of even(2), therefore the even() is called.
odd(3) OR even(2): odd(3) return 1, because of 'short-circuit evaluation', it doesn't need to check the even(2), therefore the even() isn't called.
odd(4) AND even(7): odd(4) return 0, because of 'short-circuit evaluation', it doesn't need to check the even(7), therefore the even() isn't called.
odd(4) OR even(7): odd(4) return 0, and check the return value of even(7), therefore the even() is called.
when evaluating a logical expressions, it checks the condition one by one and whenever the whole expression is known (whatever the remaining are) it stops evaluating them.
Example
unsigned char a = 1; // true
unsigned char b = 0; // false
case 1
if (a && b) printf("Yes");
check a: yes it is true
check b: no it is not true
Result: the expression is wrong and it doesn't print Yes
case 2
if (a && !b) printf("Yes");
checks a: yes it is true
checks b: yes it is false
Result: the expression is right and it prints Yes
case 3
if (a || b) printf("Yes");
checks a: yes it is true
checks b ?!!! WHY? no need to check b since the whole expression result is known only by checking a, do you agree?
Result: checks aand print Yes without even checking b
Project that on your code now ;)
Return 0; - the function returns 0.
Return 1; - the function returns 1.
In your case odd function returns 1 when number (n) is odd and 0 when the number is even.
This is done by "asking" if the reminder when dividing by 2 equels 1.
Also even function returns 1 when number (r) is even, and 0 when the number is odd.
This is done by "asking" if the reminder when dividing by 2 equels 0.
In your main function, and (&&) and or logical operations are done, on the results of the return values of odd and even functions.
Example:odd(3) return 1, even(2) return 1 then 1&&1 equals 1 (the result).
The logical Boolean algebra operators AND and OR (&& and ||) in C operate with an optimization known as short-circuit evaluation.
This is how the optimization works.
Imagine that you came up with a rule for yourself:
You will only date someone if they own a cat AND a dog AND a fish.
Now imagine you start talking to someone that you may be interested in dating. They say:
Well, I have a cat, I don't have a fish, but I do have a dog.
When did you stop paying attention to what they said? As soon as they said that they didn't have a fish, because as soon as they said that, they broke your "AND" rule. So, the rest of the sentence is completely irrelevant. This is short-circuiting AND.
Now imagine that you changed your rule:
You will only date someone if they own a cat OR a dog OR a fish.
Now imagine you start talking to someone that you may be interested in dating. They say:
Well, I don't have a cat, I have a fish, and I don't have a dog.
When did you stop paying attention to what they said? As soon as they said that they had a fish, because as soon as they said that, they satisfied your "OR" rule. So, the rest of the sentence is completely irrelevant. This is short-circuiting OR.
Short-circuit evaluation is a performance optimization for evaluating logical expressions.
In your example, the even() function returns true if the number passed to it is even, and the odd() function returns true if the number passed to it is even. Otherwise these functions return false. Look at each of the Boolean expressions and notice when short-circuit evaluation must occur.
There's also another way to test for even values for integral types.
int IsOdd(int x) { return (x & 1); }
int IsEven(int x) { return !(x & 1); }
If the least-significant bit is set, the number is odd. If not, it's even. This simply tests that bit. Just throwing this out there so you can eliminate the modulus operation... it's another option. Not an answer to your question, but I can't comment so...
As we know 0 indicates false-ness, 1 indicates true-ness. And the return part tells the compiler that the function must return the evaluated result to the caller module.
So, a return 1 means signal the caller module about a successful execution of the called module (with the aid of a Non-Zero quantity i.e. 1)
whereas,
return 0 presents a flag showing that there was some error/anomaly that led to the termination of the called module. So, in this case stderr shall be used to give details about such error.