C factorial program using recursion - c

The program takes an input, and should calculate the factorial of the number. However, after the number has been inputted there is a delay and the program stops
so far I haven't changed the code much from my initial attempt as I do not fully understand recursion and sunbroutines in C.
int calcFactorial(int n);
int input = 0, answer = 0;
int main()
{
int n = 0;
printf("Enter number:\n");
scanf("%d", &input);
answer = calcFactorial(input);
printf("The factorial of %d is %d.\n", input, answer);
system("pause");
return 0;
}
int calcFactorial(int n){
int factorial = 0;
if (n==0){
factorial = 1;
}
else{
factorial = n * calcFactorial(n-1);
printf(factorial);
}
return factorial;
}

This statement in the function calcFactorial
printf(factorial);
has undefined behaviour because the first parameter of the function printf is declared as const char * while you are supplying an object of the type int.
Remove the statement from the function.
Or if you want to get intermediate values then write
printf( "%d\n", factorial);
Also take into account that for the type int that usually has size of 4 bytes the maximum number for which you can get a valid value of the factorial is equal to 12.
You could use type unsigned long long int instead of the type int. In this case you can calculate the factorial for a number equal to 20.
Here is a demonstrative program
#include <stdio.h>
unsigned long long int calcFactorial( unsigned long long int n )
{
return n == 0 ? 1 : n * calcFactorial( n - 1 );
}
int main( void )
{
unsigned long long int input = 0, answer = 0;
printf( "Enter number: " );
scanf( "%llu", &input);
answer = calcFactorial( input );
printf( "The factorial of %llu is %llu.\n", input, answer );
}
Its output might look like
Enter number: 20
The factorial of 20 is 2432902008176640000.
The return statement in the function can be rewritten also the following way
unsigned long long int calcFactorial( unsigned long long int n )
{
return n < 2 ? 1 : n * calcFactorial( n - 1 );
}

However, after the number has been inputted there is a delay and the
program stops
As has already been pointed out by others, printf(factorial) has undefined behavior. It should be removed or it should be called properly (e.g. printf("%d\n", factorial)).
Not sure why you have system("pause") in there as it seems unnecessary.
Removing those two items from your code, I had no trouble running it and getting the correct answer for a factorial up to 12. Again, as has been pointed out by others, your function will only be valid up to 12! due to integer overflow.
Other than that, your code could be formatted better for the input, for example:
/* formats better than original */
printf("Enter number: ");
scanf("%d", &input);
printf("\n");
You can slim down your calcFactorial function as there is no need for the int factorial variable or the else clause. So you could make it look like this:
int calcFactorial(int n){
if (n == 0) return 1; //base case, 0! is 1
return n * calcFactorial(n - 1); //all other cases
}
I do not fully understand recursion and sunbroutines in C
Essentially, your function will be called over and over with n, and each time it is called we refer to that as an instantiation, and in each instantiation n is one less than it was in the previous instantiation. This will happen until the base case is reached (n == 0) then that instance will return to the instance before it, and this will happen until all instances have returned.
For simplicity sake, let's walk through calcFactorial(3). The base case is reached which is the instance that terminates further recursive calls and returns 1. In the instance before the base case was reached, n == 1 so that instance will return 1*1 since the instance before it returned 1. The instance before that was n == 2 so that instance returns 2*1. The instance before that was the first instance n == 3, so that instance returns 3*2. All instances have now returned and the result is 6 and that's what we expect for 3!.
You can learn more about recursion here

Related

I have a problem with a task on the computer language C

I would like to ask for assistance on a program I have to create on C.
The task is as it follows: To compile a program that enters integers m, n (m < n) and finds the number of all integers in this interval that are divisible by 3. The program displays all numbers that are in the interval and are not divisible by 3.
I managed to write the code on Python, but I have no idea how to do it on C.
I will appreciate every single help you send! Thanks in advance!
First, I suggest you have a look at C's printf, scanf and loops, and then you should be fine!
However, here is a way to do it (in case you need a peek):
#include <stdio.h>
int main(void) {
int m, n;
int counter = 0;
printf("Enter m: ");
scanf("%d", &m); // reads from the standard input and puts the value into m
/* The "%d" is to tell the program that we are going to read a signed decimal
* integer.
* Note: To keep the code simpler (i.e. without input checking or
* sanitization), we just assume that the user will input
* valid integers, i.e. two integers m and n such that m < n.
*/
printf("Enter n: ");
scanf("%d", &n); // same for n
/* Now you loop over all integers that are in the interval [m, n]
* int i = m is the initialization of the loop, i.e. where you want to start
* from.
* i <= n is the condition of the loop, i.e. while i is smaller or equal to n
* i++ is done in the end of an iteration, i.e. move onto the next integer
* at the end of each iteration.
*/
printf("The numbers not divisible by 3 are:\n"); // \n means end of line
for(int i = m; i <= n; i++) {
if(i % 3 == 0) {
counter++;
}
else {
/* Note: If you are not printing a string (for example an
* integer in our case), C also requires the format "%d" (opposed to
* Python where one would have written print(i + " ")).
*/
printf("%d ", i);
}
}
printf("\n");
printf("There are %d integers in [%d, %d] that are divisible by 3\n",
counter, m, n);
return 0;
}

Why does my FirstFactorial program keep looping back to while condition even after the condition is not met

Here's the code snippet, this when run with number 4 outputs 2424242448484848288288288288576576576576. Not sure as to why would the execution would jump back to while loop after exiting the function code. Any help will be appreciated. Thank you in advance.
#include <stdio.h>
#include <string.h>
int result = 1;
void FirstFactorial(int);
void FirstFactorial(int num) {
// code goes here
while (num > 0) {
result = result * num;
num--;
FirstFactorial(num);
}
printf("%d", result);
}
int main(void) {
int var;
// keep this function call here
printf ("Enter your no.\n");
scanf("%d", &var);
FirstFactorial(var);
return 0;
}
Within the function
void
FirstFactorial(int num)
{
// code goes here
while(num > 0)
{
result = result * num;
num--;
FirstFactorial(num);
}
printf("%d", result);
}
each its iteration calls itself num times and all iterations together output the global variable result.
So for example in the first call of the function the function calls itself in the while loop for the range of values [num, 1].
Remove the while loop and do not use the global variable.
Here is a demonstrative program.
#include <stdio.h>
unsigned long long int factorial( unsigned long long int n )
{
return n < 2 ? 1 : n * factorial( n - 1 );
}
int main(void)
{
printf( "%llu! = %llu\n", 4llu, factorial( 4 ) );
printf( "%llu! = %llu\n", 20llu, factorial( 20 ) );
return 0;
}
The program output is
4! = 24
20! = 2432902008176640000
Pay attention that the maximum value you may specify is 20.
Either you implement the factorial with a loop or you do it recursively.
Both ways are feasible but your code mixes it up.
Your function mixes iterative and recursive approaches. You can correct it by removing the useless recursion which causes multiple intermediary results to be computed and printed. Defining result as a global variable is also a mistake, especially since you do not reinitialize it before the loop. Using type long long will allow for larger factorials to be computed. Adding a trailing \n after the printf conversion specifier is advisable too.
Here is a corrected version:
#include <stdio.h>
void FirstFactorial(int num) {
long long result = 1;
while (num > 1) {
result = result * num;
num--;
}
printf("%lld\n", result);
}
int main(void) {
int var;
// keep this function call here
printf("Enter your number\n");
if (scanf("%d", &var) == 1)
FirstFactorial(var);
return 0;
}

Some problems in coding a "guessing random number in C" under some conditions such as using input(), output()

I tried going beyond just guessing random numbers. The conditions were these:
use input() numbers used from 1 to100 and if inserted numbers that are out of this range, to show a line to re-enter a number
use output() to show the output(but show the last line```You got it right on your Nth try!" on the main())
make the inserted number keep showing on the next line.
Basically, the program should be made to show like this :
insert a number : 70
bigger than 0 smaller than 70.
insert a number : 35
bigger than 35 smaller than 70.
insert a number : 55
bigger than 55 smaller than 70.
insert a number : 60
bigger than 55 smaller than 60.
insert a number : 57
You got it right on your 5th try!
I've been working on this already for 6 hours now...(since I'm a beginner)... and thankfully I've been able to manage to get the basic structure so that the program would at least be able to show whether the number is bigger than the inserted number of smaller than the inserted number.
The problem is, I am unable to get the numbers to be keep showing on the line. For example, I can't the inserted number 70 keep showing on smaller than 70.
Also, I am unable to find out how to get the number of how many tries have been made. I first tried to put it in the input() as count = 0 ... count++; but failed in the output. Then I tried to put in in the output(), but the output wouldn't return the count so I failed again.
I hope to get advice on this problem.
The following is the code that I wrote that has no errors, but problems in that it doesn't match the conditions of the final outcome.
(By the way, I'm currently using Visual Studio 2017 which is why there is a line of #pragma warning (disable : 4996), and myflush instead of fflush.)
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#pragma warning (disable : 4996)
int input();
int random(int);
void myflush();
void output(int, int);
int main()
{
int num;
int i;
int ran;
srand((unsigned int)time(NULL));
i = 0;
while (i < 1) {
ran = 1 + random(101);
++i;
}
num = input();
output(ran, num);
printf("You got it right on your th try!");a
return 0;
}
int input()
{
int num;
printf("insert a number : ");
scanf("%d", &num);
while (num < 1 || num > 100 || getchar() != '\n') {
myflush();
printf("insert a number : ");
scanf("%d", &num);
}
return num;
}
int random(int n)
{
int res;
res = rand() % n;
return res;
}
void myflush()
{
while (getchar() != '\n') {
;
}
return;
}
void output(int ran, int num) {
while (1) {
if (num != ran){
if (num < ran) {
printf("bigger than %d \n", num); //
}
else if (num > ran) {
printf("smaller than %d.\n", num);
}
printf("insert a number : ");
scanf("%d", &num);
}
else {
break;
}
}
return;
}
There are many problem and possible simplifications in this code.
use fgets to read a line then scanf the line content. This avoids the need of myflush which doesn’t work properly.
the function random is not needed since picking a random number is a simple expression.
if the range of the random number is [1,100], you should use 1+rand()%100.
there is no real need for the function output since it’s the core of the main program. The input function is however good to keep to encapsulate input.
you should test the return value of scanf because the input may not always contain a number.
Here is a simplified code that provides the desired output.
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#pragma warning (disable : 4996)
int input() {
char line[100];
int num, nVal;
printf("insert a number : ");
fgets(line, sizeof line, stdin);
nVal = sscanf(line, "%d", &num);
while (nVal != 1 || num < 1 || num > 100) {
printf("insert a number : ");
fgets(line, sizeof line, stdin);
nVal = sscanf(line, "%d", &num);
}
return num;
}
int main()
{
int cnt = 0, lowerLimit = 0, upperLimit = 101;
srand((unsigned int)time(NULL));
// pick a random number in the range [1,100]
int ran = 1 + rand()%100;
while(1) {
cnt++;
int num = input();
if (num == ran)
break;
if (num > lowerLimit && num < upperLimit) {
if (num < ran)
lowerLimit = num;
else
upperLimit = num;
}
printf("bigger than %d and smaller than %d\n", lowerLimit, upperLimit);
}
printf("You got it right on your %dth try!\n", cnt);
return 0;
}
I am unable to find out how to get the number of how many tries have been made.
Change the output function from void to int so it can return a value for count, and note comments for other changes:
int output(int ran, int num) {//changed from void to int
int count = 0;//create a variable to track tries
while (1) {
if (num != ran){
count++;//increment tries here and...
if (num < ran) {
printf("bigger than %d \n", num); //
}
else if (num > ran) {
printf("smaller than %d.\n", num);
}
printf("insert a number : ");
scanf("%d", &num);
}
else {
count++;//... here
break;
}
}
return count;//return value for accumulated tries
}
Then in main:
//declare count
int count = 0;
...
count = output(ran, num);
printf("You got it right on your %dth try!", count);
With these modifications, your code ran as you described above.
(However, th doesn't work so well though for the 1st, 2nd or 3rd tries)
If you want the program to always display the highest entered number that is lower than the random number ("bigger than") and the lowest entered number that is higher then the random number ("smaller than"), then your program must remember these two numbers so it can update and print them as necessary.
In the function main, you could declare the following two ints:
int bigger_than, smaller_than;
These variables must go into the function main, because these numbers must be remembered for the entire duration of the program. The function main is the only function which runs for the entire program, all other functions only run for a short time. An alternative would be to declare these two variables as global. However, that is considered bad programming style.
These variables will of course have to be updated when the user enters a new number.
These two ints would have to be passed to the function output every time it is called, increasing the number of parameters of this function from 2 to 4.
If you want a counter to count the number of numbers entered, you will also have to remember this value in the function main (or as a global variable) and pass it to the function output. This will increase the number of parameters for the function to 5.
If you don't want to pass so many parameters to output, you could merge the contents of the functions output and input into the function main.
However, either way, you will have to move most of the "smaller than" and "bigger than" logic from the function output into the function main, because that logic is required for changing the new "bigger_than" and "smaller_than" int variables which belong to the function main. The function output should only contain the actual printing logic.
Although it is technically possible to change these two variables that belong to the function main from inside the function output, I don't recommend it, because that would get messy. It would require you to pass several pointers to the function output, which would allow that function to change the variables that belong to the function main.
I have now written my own solution and I found that it is much easier to write by merging the function output into main. I also merged all the other functions into main, but that wasn't as important as merging the function output.
Here is my code:
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#pragma warning (disable : 4996)
int main()
{
const char *ordinals[4] = { "st", "nd", "rd", "th" };
int num_tries = 0;
int bigger_than = 0, smaller_than = 101;
int input_num;
int random_num;
srand( (unsigned int)time( NULL ) );
random_num = 1 + rand() % 101;
for (;;) //infinite loop, equivalent to while(1)
{
printf( "Bigger than: %d, Smaller than: %d\n", bigger_than, smaller_than );
printf( "enter a number: " );
scanf( "%d", &input_num );
printf( "You entered: %d\n", input_num );
num_tries++;
if ( input_num == random_num ) break;
if ( input_num < random_num )
{
if ( bigger_than < input_num )
{
bigger_than = input_num;
}
}
else
{
if ( smaller_than > input_num )
{
smaller_than = input_num;
}
}
}
printf( "You got it right on your %d%s try!", num_tries, ordinals[num_tries<3?num_tries:3] );
return 0;
}
Also, I made sure that the program would print "1st", "2nd" and "3rd", whereas all the other solutions simply print "1th", "2th", "3th". I used the c++ conditional operator for this.

Why do I get an endless loop from my code?

#include <stdio.h>
int main() {
int num;
int square;
int sum;
while (num) {
if (num > 0) {
scanf("%d", &num);
square = num * num;
sum = square + sum;
printf("%d \n", sum);
}
}
return 0;
I'm trying to produce the sum of squares for positive numbers, and when the first negative number is inputted, the loop ends. Result needs to be left justified by 10 spaces.
The code has undefined behavior: the first time you test the value of num, it is uninitialized. If by chance it happens to not be negative, you scan a new value and add its square to uninitialized variable sum, producing more undefined behavior, it the value input was negative, the next test fails and the loop repeats forever.
Left justifying in a 10 space width is obtained with the %-10d conversion format.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int num, square, sum = 0;
while (scanf("%d", &num) == 1 && num != 0) {
square = num * num;
sum = square + sum;
printf("%-10d\n", sum);
}
return 0;
}
If you want the number to be right justified in a 10 space width so all output values align properly, use the %10d format instead.
If you input large numbers or too many items, you will eventually exceed the range of type int. You can try and increase the range of variables square and sum by making them long long int or even as commented by PeterJ unsigned long long int, and allow for larger values to be computed:
int main(void) {
int num;
unsigned long long square, sum = 0;
while (scanf("%d", &num) == 1 && num != 0) {
square = (long long)num * num;
sum = square + sum;
printf("%21llu\n", sum);
}
return 0;
}
Note that (long long)num * num will be converted to unsigned long long that has a range at least as large in the positive values.
Using uninitialized variable leads to undefined behavior.You are using uninitialized local variable num in your while loop. num can have any value in it. If the value is smaller than 0 the loop will run forever. It will also loop for ever if the value smaller than 0 is entered using scanf.
For undefined behavior please check lines from standard
6.3.2.1 Lvalues, arrays, and function designators
If the lvalue designates an object of automatic storage duration that
could have been declared with the register storage class (never had
its address taken), and that object is uninitialized (not declared
with an initializer and no assignment to it has been performed prior
to use), the behavior is undefined.
I hope, this might help ending the loop
#include <stdio.h>
int main() {
int num = 0;
int sum = 0;
while (num >= 0) {
scanf("%d", &num);
if (num>=0) {
sum = ( num * num ) + sum;
printf(" %d\n", sum);
}
}
return 0;
}

How to get the number of digits of an integer?

The program below is sufficent enouhgh to find the length of any string length that is given to the input, however, i need to find the length of an integer variable, rather than a string.
Entering a number to this does work, but not if i scan s as a int type.
int main()
{
char s[1000];
char i;
int u=5;
do
{
char s[1000];
char i;
int u=5;
system("cls");
printf("Enter a string: ");
scanf("%s",s);
for(i=0; s[i]!='\0'; ++i);
printf("Length of string: %d",i);
getch();
}
while(u==5);
getch();
}
So all i need is either this little program modified to accept intger variables, or a way to transform a calculated int variable into a string.
Any ideas?
Edit: Length = Amount of characters so 25 has 2, 3456 has 4 etc
You can calculate the length of n in base m with the formula:
ceil(log(n + 1, m))
Where ceil is the ceiling (round up) function, and log(a, b) is logarithms of a in base b.
You may use the below code to find the number of digits of an integer:
int count=0;
while(n!=0)
{
n/=10;
++count;
}
Where n is your input integer and count will be the it's length.
If you want to read an integer as an integer i,e with %d and count number of digits in that integer, have a look at below code snippet.
int no,length=0;
printf("Enter number");
scanf("%d",&no);
while(no!=0)
{
length+=1;
no=no%10;
}
printf("Length=%d",length);
To determine the number of characters to print a decimal number (assuming value is the int), you could do the following:
int intlen = 0;
if (value < 0) // for negative values, allow a char for the minus sign
{
value = -value;
++intlen;
}
while (value >= 10) // as long as the value is 1 or more,
{
value /= 10; // divide by 10,
++intlen; // ...and add one to the length
}
++intlen; // add one for last digit (even if it's zero)
It's probably easier to use the ceil/log function described above, but this one does not require the math library (if that is an issue)
Another brute-force approach would be as follows:
char temp[12];
int intlen = sprintf(temp,"%i",value);
This utilizes the fact that sprintf returns the number of characters placed in the string buffer.
#include<stdio.h>
main()
{
int count=1,n;
scanf("%d",&n);
while(n/=10)
count++;
printf("result=%d",count);
}
count gives the number of digits in number n

Resources