C recursion does not recurse - c

My search did not yield any results. Also, my english is pretty bad, sorry for that.
So my program should do this:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
float rec();
int main()
{
setlocale(LC_ALL,"");
int w;
scanf("%d",&w);
printf("%f",rec(w));
return 0;
}
float rec(n)
{
if (n<1)
{
printf("Error");
}
else if (n==1)
{
return 6;
}
else if (n>1)
{
return 1/2*rec(n-1)+4;
}
return 0;
}
When the input is 1 it outputs 6, as it is supposed to.
When the input is <1 it outputs "Error0,000000".
When the input is >1 it only outputs the number that is added in
return 1/2*rec(n-1)+4;
In this case, it outputs 4. Why? Is rec(n-1) == 0?
My questions are:
Why won't it work?
How do i make it output "Error" instead of "Error0,000000" when the input is <1?

Integer division!
Here,
return 1/2*rec(n-1)+4;
1/2 will yields 0 due to integer division. So it's always going to be 4 as the final result.
Instead you can do:
return 1.0/2*rec(n-1)+4;
which will make sure the computation happens as double.
You might also simply want to add return 0; in the if (n<1) case and change the function definitio to:
float rec(int n) {... }
If you don't specify a type for n, it defaults to int in pre-C99. But this is no longer the case in C99 and C11.

The problem is mainly a type issue: try
return 1.0/2.0*rec(n-1)+4
to tell the compiler, that you want floating point arithmetic during the calculation. Otherwise, an integer division is performed and casted to float afterwards.
Fwiw: You wouldn't use a recursion for this, an iteration would fully suffice, be better understandable, perform better and needed less resources than the recursive version in c.

I would like to give you the answer of the second question.
You need a buffer for the return value of rec.
So,
float answer = rec(w);
if (NOTHING_HAPPENED)
print("%f", answer);
This will work!

In the case where n<1, you printf "Error" from the called routine, and then return 0 to be printf'd (as a float) in main. Don't do that ;-)
Personally, I'd check for the original being <1 in main as an alternative to calling rec() and printf.
This would be easier to answer if you'd tell us what it's supposed to produce.
However, I suspect your problem is related to rec() taking an integer argument, but returning a float. If you want recursive functions to behave sanely, their argument and return type should match. Quite likely your issue is that at some point you pass a decimal fraction that is approximately equal to 1, which does not get converted to 1 by the implicit type conversion.

Related

Recursive function for finding factorial of a number

I am getting an output of 24 which is the factorial for 4, but I should be getting the output for 5 factorial which is 120
#include <stdio.h>
int factorial(int number){
if(number==1){
return number;
}
return number*factorial(--number);
}
int main(){
int a=factorial(5);
printf("%d",a);
}
Your program suffers from undefined behavior.
In the first call to factorial(5), where you have
return number * factorial(--number);
you imagine that this is going to compute
5 * factorial(4);
But that's not guaranteed!
What if the compiler looks at it in a different order?
What it if works on the right-hand side first?
What if it first does the equivalent of:
temporary_result = factorial(--number);
and then does the multiplication:
return number * temporary_result;
If the compiler does it in that order, then temporary_result will be factorial(4), and it'll return 4 times that, which won't be 5!. Basically, if the compiler does it in that order -- and it might! -- then number gets decremented "too soon".
You might not have imagined that the compiler could do things this way.
You might have imagined that the expression would always be "parsed left to right".
But those imaginations are not correct.
(See also this answer for more discussion on order of evaluation.)
I said that the expression causes "undefined behavior", and this expression is a classic example. What makes this expression undefined is that there's a little too much going on inside it.
The problem with the expression
return number * factorial(--number);
is that the variable number is having its value used within it, and that same variable number is also being modified within it. And this pattern is, basically, poison.
Let's label the two spots where number appears, so that we can talk about them very clearly:
return number * factorial(--number);
/* A */ /* B */
At spot A we take the value of the variable number.
At spot B we modify the value of the variable number.
But the question is, at spot A, do we get the "old" or the "new" value of number?
Do we get it before or after spot B has modified it?
And the answer, as I already said, is: we don't know. There is no rule in C to tell us.
Again, you might have thought there was a rule about left-to-right evaluation, but there isn't. Because there's no rule that says how an expression like this should be parsed, a compiler can do anything it wants. It can parse it the "right" way, or the "wrong" way, or it can do something even more bizarre and unexpected. (And, really, there's no "right" or "wrong" way to parse an undefined expression like this in the first place.)
The solution to this problem is: Don't do that!
Don't write expressions where one variable (like number) is both used and modified.
In this case, as you've already discovered, there's a simple fix:
return number * factorial(number - 1);
Now, we're not actually trying to modify the value of the variable number (as the expression --number did), we're just subtracting 1 from it before passing the smaller value off to the recursive call.
So now, we're not breaking the rule, we're not using and modifying number in the same expression.
We're just using its value twice, and that's fine.
For more (much more!) on the subject of undefined behavior in expressions like these, see Why are these constructs using pre and post-increment undefined behavior?
How to find the factorial of a number;
function factorial(n) {
if(n == 0 || n == 1 ) {
return 1;
}else {
return n * factorial(n-1);
}
//return newnum;
}
console.log(factorial(3))

Variable Initialization in Function

I'm fairly new to coding and am currently learning C. In my C programming class, my instructor gave us the assignment of writing a program that uses a function which inputs five integers and prints the largest. The program is fairly simple even for me, but I'm facing some problems and was hoping to get some advice.
#include <stdio.h>
int largest(int x);
int main(void) {
int integer1;
largest(integer1);
return 0;
}
int largest(int x) {
int i;
for (i = 0; i < 5; i++) {
printf("Enter an integer: ");
scanf_s("%d", &x);
}
return x;
}
This is the code that I have written. The main problem that I am having is that in my main method, the IDE tells me to initialize the value of integer1. However, I'm not really sure how to do that because I'm supposed to input the value within the largest() method via the scanf_s function. How may I solve this?
The problem is here, the warning message is to warn you about the potential pitfall of using the value of an uninitialized automatic local variable. You made the call like
largest(integer1);
but you ignore the return value, so the integer1 remains uninitialized.
Remember, in view of largest(), x is a local copy of the actual argument passed to that function, any changes made to x won't be reflecting to the caller.
That said, your code is nowhere near your requirement, sorry to say. A brief idea to get there would be
Create a function.
Create a variable (say, result) and initialize with minimum possible integer value, INT_MIN
Loop over 5 times, take user input, compare to the result value, if entered value found greater, store that into result, continue otherwise.
return result.
I know that normally help for assignments shouldn't be given but I have to say that you might need to rethink what you want to do.
You are inputting an integer to the function named largest. But why are you only inputting a single integer to a function that should return the largest value. You can't do much with a single number in that case.
You should instead be inputting say an array of 5 values(as said in your assignment) to the function and let it return the largest.
The order would then be:
Read 5 values and save to an array
Call the function largest with the array as input
Let the function do it's work and return the largest value
Do what ever you want with the largest value
But if you only want to remove the warning simply type
int integer1 = 0;

Can anybody explain the error in the program i made, can anybody why i didn't workout?

how is your day :),
Take a look at the below program, the program written below is to calculate the sum of first n natural numbers, the problem is that i get the sum of n-1 natural numbers, can anybody explain why ?
and can anybody also explain why a-- instead of --a.
#include<stdio.h>
main()
{
int a,sum;
printf("Enter a number.");
scanf("%d",&a);
sum=sumnat(a);
printf("Sum of the first %d natural numbers is %d.",a,sum);
}
sumnat(a)
{
int b;
if(a==0)
{
return 0;
}
else
{
b=a+sumnat(--a);
return(b);
}
}
There were several errors, the greatest of which was undefined behaviour in the expression which uses a and also a modified value of a. You should also define your function properly, not rely on default values provided by the compiler.
#include <stdio.h>
int sumnat(int a); // function prototype
int main(void) // correct signature
{
int a, sum;
printf("Enter a number. ");
scanf("%d", &a);
sum = sumnat(a);
printf("Sum of the first %d natural numbers is %d.", a, sum);
return 0;
}
int sumnat(int a) // function has a return type and argument type
{
if(a == 0)
{
return 0;
}
return a + sumnat(a - 1); // there was no need to decrement `a`
}
Program session
Enter a number. 5
Sum of the first 5 natural numbers is 15.
Your program works for me, using gcc on Mac OSX. However, it will not work everywhere, because of this line:
b=a+sumnat(--a);
--a decrements a, but if it does so before the addition, then your result will be wrong. I'm not sure C is required to evaluate expressions strictly left-to-right (I don't think it is). At any rate, since you don't use a after that line, you could fix things this way:
b=a+sumnat(a-1);
As #self says, you should fix the program to handle negative values, and it would be a good idea to consider what is the largest natural number whose sum you can compute this way (and why that is).
There is a difference between them. One first subracts from a and than goes in the function while the other frist goes in... so it never gets subracted and you go to inifinit stack.
"and can anybody also explain why a-- instead of --a"
When you use the prefix operator --a the decrease is done before anything else, while the postfix operator a-- happens after the rest of the expression is resolved, so, lets say, while debugging your code, in a particular moment, a = 5
since the line
b=a+sumnat(--a);
is using the prefix version of the operator, the decrement would happen immediately, making a=4 and then the function sumnat would be called with argument 4
b=a+sumnat(a--);
in this case the postfix operator is being used, so first the function sumnat would be called with the argument 5, since that is the value of a in that moment, then, only when the function returns a value (which would never happen in your example, since it would be called multiple times with the same value, never reaching 0) the decrement would happen

recursive functions in C: is return always necessary?

this is my first time playing with recursive functions, and this function that I wrote returns the size of a string if it contains only letters in ascending order, and if not it returns -1.
I don't understand why it works for both codes, after I took out the second "return". Is one more wasteful than the other? Would appreciate some insight.
with "return only_ascending_letters(string, index+1);"
#include <stdio.h>
int only_ascending_letters(char string[], int index);
void main() {
char string1[]="Hi my name is pete";
char string2[]="aabcdefg";
printf("the first string is %d and the second one is %d\n",only_ascending_letters(string1,0),only_ascending_letters(string2,0));
}
int only_ascending_letters(char string[], int index){
if(!string[index]) return index;
if(((string[index]>='a'&&string[index]<='z')||(string[index]>='A'&&string[index]<='Z'))&&((string[index]<=string[index+1])||!string[index+1]))
return only_ascending_letters(string, index+1);
else return -1;
}
with "only_ascending_letters(string, index+1);"
#include <stdio.h>
int only_ascending_letters(char string[], int index);
void main() {
char string1[]="Hi my name is pete";
char string2[]="aabcdefg";
printf("the first string is %d and the second one is %d\n",only_ascending_letters(string1,0),only_ascending_letters(string2,0));
}
int only_ascending_letters(char string[], int index){
if(!string[index]) return index;
if(((string[index]>='a'&&string[index]<='z')||(string[index]>='A'&&string[index]<='Z'))&&((string[index]<=string[index+1])||!string[index+1]))
/*Took out the return*/ only_ascending_letters(string, index+1);
else return -1;
}
Yes, you absolutely need the return. Note that C language rules are a bit lax about this issue, and if you hadn't used the return value, it would be fine without it. However, you use the return value, so you need the return statement.
What you see is probably caused by the implementation detail that function on some architectures return (integral values) by setting a well known register to that value (eax on i386). Therefore, if the bottommost recursive call does return and set this register, and the calls in-between don't stomp on that register, you see that it sort of works. However, you mustn't rely on that.
Note that good compilers will recognize this is a tail-recursive call and compile both variant basically the same way.
First of all, main() returns an int (actually, a type compatible with int).
Second, you should format your code more. Whitespace is your friend, as are line breaks. It was hard to tell whether the code without return was actually correct because most of it ran offscreen.
Third, you should always work with all [reasonable] warnings enabled. Doing so would have caught the missing return condition, as well as the void main().
As for the answer, #jpalecek has done a great job providing it. I would only like to add that undefined behavior is a beast. If you rely on it, a "working" program may stop doing so just because you decided to compile it again, played some music while running it, or the phase of the moon changed.
All I could find in the [99] standard was §6.9.1 clause 12:
If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.
You have two exit conditions. You either run off the end of the string, in which case your condtion of ascending characters is met and you return the length of the string, or you find a character that fails your ascending test, in which case you return -1.
Not returning the value from the call to the recursive function may work on some implementations of the compiler but with a different compiler or different optimisation flags, it may well not work so you should keep the return in your code.

Is there a syntactic error that I'm overlooking in this loop

Hey guys could you please spot the semantic error that's in the code below, it seems OK to me but my instructor claims that there still is an "syntactic" error.
This is a simple program that prints a simple series starting from 256.
The series depends on the value of the variable a which is 256 in this case.
Hence in this case the series looks like 256,16,4,2,1. */
#include <stdio.h>
#include <math.h>
int main()
{
int a = 256;
int square_root_a;
printf("%d\n", a);
repeat:
square_root_a = sqrt(a);
if (square_root_a >= 2)
{
printf("%d\n", square_root_a);
a = square_root_a;
goto repeat;
}else{
printf("%d\n", 1);
} return 0;
}
You declare a as an integer, which will round the result of sqrt() to the nearest integer.
I guess you're supposed to use double.
Well, if it's not about the goto, or the int-ness of the variables, then my guess is your teacher means something subtle, like the printfs in both branches of the if. They have exactly the same purpose! Why write two statements that do the same, if it's possible to use only one? Just move the first one to above the if, and delete the second one.

Resources