Collatz sequence getting last number 1 repeated - c

// Define the recursive function.
int collatz(int p1)
{
// While Loop Starting
while (p1>1)
{
//when the number is even
if(p1%2==0)
{
p1 = p1/2;
printf("%d ", p1);
//using recursion
return collatz(p1);
}
// Case where number is odd.
elseif
{
p1 = 3*p1+1;
//print function
printf("%d ", p1);
//using recursion
return collatz(p1);
}
}
}
// Main body.
int main()
{
// Declare the variable and initialized it.
int p1= 4;
//print function
printf("User Entered value : %d\n", p1);
// Display the number
printf("%d\n", collatz(p1));
//End
return 0;
}
Output: I am getting the Output as :
2 ,1, 1
I should not get the last number 1 repeated.Could you please correct me where i have done mistake.Please do the needful.

You should always enable warnings when you compile a C or C++ program. Had you done do, the compiler would have warned you that your function collatz could terminate without returning a value. (What happens if the argument is 1?)
That's undefined behaviour, and so is the use of the possibly-nonexistent return value in your main function.
So it is just a quirk of chance that it happens to print 1 in main. But whatever it printed would be wrong because you seem to expect the output to be limited to what is printed in collatz.
You might try playing computer and executing your function with a pencil and paper. It won't take very long. Of course, you could also use a debugger.

Related

Why we can't compare a int variable with int return type function in c?

I tried to compare int variable with the function in two ways:
storing the int function return value in a variable then comparing with another
in value.
Directly comparing the int variable and the function call.
Here I got the answer for the first one but not for the second one.
Why does this happen?
My code:
#include < stdio.h >
int count = 0;
int countDigits(int);
int main() {
int i;
int result = countDigits(435);
for (i = 0; i < result; i++) {
printf("id %d\n", 3);
}
for (i = 0; i < countDigits(435); i++) {
printf("i =%d\n", i);
}
}
int countDigits(int n) {
if (n == 0) {
return count;
} else {
countDigits(n / 10);
count++;
}
}
We can.
It's just that your function has a logical error. Debug it, and you will be fine.
Enabling compiler warnings would have helped you. For example with GCC and Wall flag, you get:
prog.c: In function 'countDigits':
prog.c:32:1: warning: control reaches end of non-void
function [-Wreturn-type]
}
^
Tip: Think of what your function does if n us different than zero.
count is a global variable.
The function countDigits(n) adds the number of decimal digits in n to count and
If n is zero it returns 1.
If n is non-zero the return value is undefined.
Since countDigits(435) has an undefined value, anything can happen and no further analysis is necessary.
Let's assume that this obvious error is corrected by inserting return count; after count++;. In this case, the function returns the incremented count.
So we have this nice sequence:
Set result to countDigits(435).
countDigits(435) adds 3 to count and returns 3.
Set i to 0 and compare to countDigits(435).
countDigits(435) adds 3 to count and returns 6. 0 is less than 6, so the for loop continues.
Now i is 1, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 9. 1 is less than 9, so the for loop continues.
Now i is 2, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 12. 2 is less than 12, so the for loop continues.
... And so on.
Morality:
Beware of side effects. Never use and modify global variables unless you have a good reason to.
When you must use side effects, keep them prominent in your mind.
It is possible to compare a variable directly with the output of a function. However, your function countDigits has several problems.
Not all code paths return a value - you're missing a return statement in the else block. This alone makes the output of the function undefined.
It's not algorithmically correct. Have you tried debugging it? Just start with printing the output for different inputs and you'll see.
Modifying and returning a global variable count inside that function is a really bad practice - it should be local to the function. When it's global, every call to the function modifies a [possibly] already modified variable.
Others have already addressed the problem here with globals, so I will not go into details about that. Instead, here is a solution without globals:
int countDigits(int n) {
int count = 0;
while(n>0) {
n/=10;
count++;
}
return count;
}
I guess you could be philosophical about whether 0 has 0 or 1 digit, but your code implied that you wanted it to be 0. If you want it to be 1 instead, just change the first row to int count = 1.

Printing a recursive function returned value when the function contains printf

#include <stdio.h>
int c=0;
int check (int c)
{
c=c+1;
if (c<6)
return check(c);
printf("%d\n", c);
}
int main()
{
printf("%d\n",check(c));
}
The above code gives me
6
2
as the output. 6 is from the printf function inside the check function but I did'nt get why 2. If I remove the printf function inside the check function I get
5
as the output. Can anyone explain why this happens?
You are invoking undefined behavior. So it behaves oddly.
You must have a proper return statement in the check function as you are supposed to return an int.
Also having printf or not having it - doesn't change anything- it's still UB.(in this case)
I made a few modifications to your posted code so that it becomes obvious what is happening. It looks like the compiler outsmarted you, and prepended return in front of printf("%d\n", c); So the 2 that you are seeing is the number of characters printed when you print 6\n on the last iteration of check(). The 2is then passed all the way down the stack to the original call inside the main, eventually ending up on your Console window. See this reference
[printf returns the] number of characters transmitted to the output stream or negative value if an output error or an encoding error (for string and character conversion specifiers) occurred.
Consider the following code. It exhibits identical behaviour to your posted code.
#include <stdio.h>
int check(int c)
{
int ret = 0;
c = c + 1;
if (c < 6)
{
ret = check(c);
return ret;//helps inspect ret
}
//looks like the compiler inserts that return statement
ret = printf("%d\n", c);// 2 <- number of characters in "6\n".
return ret;
}
int main()
{
int c = 0;
int ret = 0;
ret = check(c);//ret comes out == 2. This is the return value of printf
printf("%d\n", ret);
getchar();
return 0;//don't forget this guy!
}
Disclaimer: Even though it appears that this is what is happening, and most likely it probably is, It is not a shortcut and I would not count on this happening every time. The behaviour is still undefined! The best thing to do is to return from functions normally.

Need reason for the occurrence of following output

main(){
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d %d",*(a+1),*(ptr-1));
}
The output of this code is coming out to be : 2 5 .
I understand why 2, but why 5 is coming for *(ptr-1)?
Also ,
main(){
while(1)
{
if(printf("%d",printf("%d")))
break;
else
continue;
}
}
This code is showing the output as : Garbage value . How and why?
printf() function returns an integer. Upon success, the return value is number of character written. And upon error, the return value is negative.
since the printf("%d") (inner one of printf("%d",printf("%d"))) will be executed first, it will most likely show some random value of a memory location. After that printf("%d",printf("%d")) will print number of values written during the previous call.
Example: 123456789010

How do you explain the discrepancy in the output of this piece of code?

This piece of code is giving unexpected output. When I comment printf of sumdig function the return value of a is 6 and b is 12 but when printf is retained a is 5 and b is 6. Please explain.
main()
{
int a,b;
a = sumdig(123);
b = sumdig(123);
printf("\na=%d b=%d",a,b);
return 0;
}
int sumdig(int n)
{
static int s=0;
int d;
if(n!=0)
{
d=n%10;
n=(n-d)/10;
s=s+d;
sumdig(n);
}
else
return s;
printf("\n s=%d",s);
}
If you don't have an explicit return statement an int c function is apt to return whatever value was returned by the last function called (although I believe the actual behavior is undefined). Therefore
you are returning the result of printf when you mean to return the value of the recursive call to sumdig.
Instead of sumdig(n);, try return sumdig(n);
Right, firstly you should compile this with as many warnings as your compiler will give you.
This'd show you that although sumdig returns a value, there's at least one code path that doesn't return anything so the caller will get rubbish.
Secondly you have a static variable that is never re-initialised so every client call will accumulate extra stuff in s.

Can I re-initialize global variable to override its value in C?

Does anyone know why my program prints -69 in below case? I expect it to print default/ garbage value of uninitialized primitive data types in C language. Thanks.
#include<stdio.h>
int a = 0; //global I get it
void doesSomething(){
int a ; //I override global declaration to test.
printf("I am int a : %d\n", a); //but I am aware this is not.
a = -69; //why the function call on 2nd time prints -69?
}
int main(){
a = 99; //I re-assign a from 0 -> 99
doesSomething(); // I expect it to print random value of int a
doesSomething(); // expect it to print random value, but prints -69 , why??
int uninitialized_variable;
printf("The uninitialized integer value is %d\n", uninitialized_variable);
}
What you have is undefined behavior, you can't predict the behavior of undefined behavior beforehand.
However it this case it's easy to understand. The local variable a in the doesSomething function is placed at a specific position on the stack, and that position does not change between calls. So what you're seeing is the previous value.
If you had called something else in between, you would have gotten different results.
Yeah.. Your function reuse two times the same segment of memory.. So, the second time you call "doesSomething()", variable "a" will be still "random".. For example the following code fill call another function between the two calls and you OS will give you differen segments:
#include<stdio.h>
int a = 0; //global I get it
void doesSomething(){
int a; //I override global declaration to test.
printf("I am int a : %d\n", a); //but I am aware this is not.
a = -69; //why the function call on 2nd time prints -69?
}
int main(){
a = 99; //I re-assign a from 0 -> 99
doesSomething(); // I expect it to print random value of int a
printf( "edadadadaf\n" );
doesSomething(); // expect it to print random value, but prints -69 , why??
int uninitialized_variable;
printf("The uninitialized integer value is %d\n", uninitialized_variable);
}

Resources