Recursion with pointers sum of digits - c

I tried to build a recursion function using pointers that puts the digits with an even index in one pointer and the digits with the odd index to a different one.
For example:
The input 123: 3 has the index of 0 so it will go to *even.
2 has the index of 1 so it will go to *odd.
1 has the index of 2 so it will go to *even.
and in the end *even will have the value of 1+3 = 4 and *odd will have the value of 2.
But I had problems with this function so I tried to do a simplified version of it and It didn't work.
So the simplified version puts the sum of all the digits in *sum:
void main()
{
int num = 25;
int x = 0;
sumDigits(num, &x);
printf("%d", x);
}
void sumDigits(int num, int* sum)
{
if (num >= 0 && num <= 9)
{
*sum = num;
}
else
{
*sum = *sum + num % 10;
sumDigits(num/10, sum);
}
}
But it still won't work properly.
If someone could tell me what's wrong with this function then I could understand how to it and the original one as well.

A simple solution is to handle both an even and an odd digit in each function call.
Like:
void sumDigits(unsigned int num, unsigned int* even, unsigned int* odd)
{
// Handle even digit
*even += num % 10;
num /= 10;
// Handle odd digit
*odd += num % 10;
num /= 10;
// If there are still digits to be handled
if (num)
{
// Do the recursive call
sumDigits(num, even, odd);
}
}
int main(void)
{
unsigned int num = 123;
unsigned int even = 0, odd = 0;
sumDigits(num, &even, &odd);
printf("even=%d odd=%d", even, odd);
}
That said... this problem is not suitable for recursion a simple loop will be much more efficient.
void sumDigits(unsigned int num, unsigned int* even, unsigned int* odd)
{
while (num)
{
*even += num % 10;
num /= 10;
*odd += num % 10;
num /= 10;
}
}

For starters the function sumDigits must be declared before main and according to the C Standard the function main without parameters shall be declared like
int main( void )
That is you need to write
#include <stdio.h>
void sumDigits(int num, int* sum);
int main( void )
{
//...
}
There is neither sense to declare the first parameter of the function as having the signed integer type int because it seems the function does not deal with negative numbers.
The first parameter should have the type unsigned long long. In this case you can call the function for an object of any fundamental unsigned integer type.
The function has a logical error. Its last recursive call overwrites the value stored in sum that was calculated in preceding recursive calls of the function due to this if statement
if (num >= 0 && num <= 9)
{
*sum = num;
}
Also pay attention to that the user can pass by reference the second argument that was not initialized. In this case the function will have undefined behavior.
As for your mentioned function that should calculate suns of digits in even and odd positions then it can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
void digits_sums( unsigned long long int x, unsigned int *even, unsigned int *odd )
{
const unsigned long long int Base = 10;
x == 0
? ( *even = x, *odd = x )
: ( digits_sums( x / Base / Base, even, odd ), *even += x % Base, *odd += x / Base %Base );
}
int main(void)
{
unsigned int x = 123456789;
unsigned int even;
unsigned int odd;
digits_sums( x, &even, &odd );
printf( "The sum of digits in even positions is %u\n"
"The sum of digits in odd positions is %u\n",
even, odd );
return 0;
}
The program output is
The sum of digits in even positions is 25
The sum of digits in odd positions is 20

Related

My factorial function is not returning factorial

I am not able to find out why my function returns the user input only rather then the factorial of the input.
#include <stdio.h>
#include <math.h>
int factorial(int x)
{
//int x;
int sum = 1;
while (x!=0){
sum = sum * x;
x--;
}
return sum;
}
int main(){
int x;
printf("Enter value of x: ");
scanf("%i",&x);
factorial(x);
printf("sum is %i", x);
return 0;
}
Your factorial function does return a new value, but then you don't actually use that value.
printf("sum is %i\n", factorial(x));
Because you are printing x which is the variable that you have stored the user input in. Your factorial function returns the result, but you are not saving it.
I think the variable names were not proper and you printed x instead of printing factorial.
#include <stdio.h>
int factorial(int x)
{
int fact = 1;
while (x!=0){
fact = fact * x;
x--;
}
return fact;
}
int main(){
int x;
printf("Enter value of x: ");
scanf("%i",&x);
printf("Factorial is %i",factorial(x));
return 0;
}
For starters the function as is
int factorial(int x)
{
//int x;
int sum = 1;
while (x!=0){
sum = sum * x;
x--;
}
return sum;
}
can invoke undefined behavior if the user will pass a negative value, and the function accepts negative values.
The function argument should have an unsigned integer type instead of the signed integer type int
For non-negative values the maximum value of the types int or unsigned int for which the factorial can be calculated is equal to 12.
So to be able to calculate the factorial for greater values you should use the type unsigned long long int. In this case the maximum value for which the factorial can be calculated correctly is equal to 20.
The function can look the following way
unsigned long long int factorial( unsigned long long int x )
{
unsigned long long int product = 1;
for ( ; 1 < x; --x )
{
product *= x;
}
return product;
}
In your program you are not using the returned value of the function.
factorial(x);
The function main can look the following way
int main( void )
{
unsigned int x;
printf( "Enter value of x: " );
if ( scanf( "%u",&x ) == 1 )
{
printf("The factorial of %u is equal to %llu\n, x, factorial( x ) );
}
return 0;
}
Now try the program by entering the value for x equal to 20 and see the program output.:)
You could check in the if statement that the user did not enter a value greater than 20 as for example
if ( scanf( "%u",&x ) == 1 && !( 20 < x ) )
Though it would be better if the function itself will check the value of the passed argument.
Failure to use function return value
As others have said:
//factorial(x);
//printf("sum is %i", x);
printf("sum is %i", factorial(x));
To improve factorial()
Since factorial is a product, change the sum name.
Cope with pathologic inputs like values less than 0 or very large. Code code exit, but maybe instead return a error value. Determination of the upper limit could be done beforehand (as below), at run time or with makefile magic.
Use a wider type to handle large values. Maybe even use an unsigned type. uintmax_t has the greatest max value. It is at least 64 bits.
Example
#include <limits.h>
#include <stdint.h>
#if UINTMAX_MAX == 0xFFFFFFFFFFFFFFFFu
#define FACTORIAL_MAX 20
#elif (UINTMAX_MAX >> 64) == 0xFFFFFFFFFFFFFFFFu
#define FACTORIAL_MAX 34
#else
#error TBD FACTORIAL_MAX
#endif
// Compute factorial.
// Return 0 on error.
uintmax_t factorial(int x) {
if (x < 0 || x > FACTORIAL_MAX) {
return 0;
}
uintmax_t product = 1;
while (x > 0) {
product = product * x;
x--;
}
return product;
}

When i use my code in local vscode its giving only 63 as answer but when i use a different online complier it works fine

This is a Luhn algorithm code and it works fine in an online complier but when I use it in my local vscode it is only giving 63 as output.
I dont know if its a memory issue as it late long variable.
i.e credit card number as input.
#include <stdio.h>
// Finds its Luhn algorithm to see if its a valid credit card number.
void checksum(long num)
{
int sum = 0;
for (int i = 0; num != 0; num /= 10, i++)
{
if (i % 2 == 0)
{
sum = sum + num % 10;
}
else
{
int digit = 2 * (num % 10);
sum = sum + (digit / 10) + (digit % 10);
}
}
printf("%d", sum);
}
int main()
{
long int num;
// Takes credit Card number as input.
do
{
printf("Number: ");
scanf("%li", &num);
} while (num < 0);
checksum(num);
return 0;
}
My inputs are like 374245455400126,378282246310005.
And output is always 63.
The result depends on the size of the type long int that can be equal either to the size of the type int or to the size of the type long long int.
So use the type long long int instead of the type long int.
Also as the program expects an unsigned value then instead of the signed type long long int it is even better to use the type unsigned long long int.

How to return 3 numbers in a function without adding them?

Doing the 7. Reverse Integer leetcode, (intput =321 expected output = 123)
I don't know how to return my numbers from the function. I'm printing them as of right now to see if I'm solving the problem, and my stdout is fine but my output is 3.
Your input:
123
stdout:
312
Output:
3
Expected:
321
int reverse(int x)
{
int a,b,c;
c = x % 10;
b = (x / 10) / 10;
a = (x / 10) % 10 ;
printf("%d%d%d",c,b,a);
return;
}
It might be easier to generalize reverse to handle numbers of any width, not just 3 digits.
Here's some code to do that (you might have to adjust the format for the printf):
#include <stdio.h>
int
reverse(int x)
{
int y = 0;
while (x != 0) {
y *= 10;
y += (x % 10);
x /= 10;
}
return y;
}
int
main(void)
{
const char *fmt = " %3.3d";
for (int x = 0; x <= 999; ++x) {
printf(fmt,x);
printf(fmt,reverse(x));
printf("\n");
}
return 0;
}
Generalizing a bit and handling potential negative values. You have the basic approach, but, in addition, you want to determine the sign of the input and then operate on a positive value and restore the sign at the end of your function. You can do something similar to:
#include <stdio.h>
#include <stdlib.h>
int reverseint (int n)
{
int reverse = 0,
sign = n < 0 ? -1 : 1;
if (n < 0)
n = -n;
while (n) {
reverse *= 10;
reverse = reverse + n % 10;
n /= 10;
}
return sign * reverse;
}
A short example main() to demonstrate that takes the number to reverse as the first argument to the program (or uses 54321 if no argument is given) could be:
int main (int argc, char **argv) {
int n = (argc > 1) ? (int)strtol(argv[1], NULL, 0) : 54321;
printf ("n : %d\nreverse : %d\n", n, reverseint(n));
}
(note: you should validate the input to the program and the reverseint function are valid integers is in the range of int -- that is left to you)
Example Use/Output
$ ./bin/reverseint
n : 54321
reverse : 12345
$ ./bin/reverseint 0
n : 0
reverse : 0
$ ./bin/reverseint -12345
n : -12345
reverse : -54321
Alternative Using div()
The div() function also provides a nice variant that will replace both your division and modulo operations. See man 3 div. The following is equivalent to the function above but using div() instead of / and %:
int reverseint (int n)
{
/* initialize div_t with positive .quot */
div_t d = { .quot = n < 0 ? -n : n };
int reverse = 0,
sign = n < 0 ? -1 : 1;
do {
d = div (d.quot, 10); /* call div with base 10, to update quotient */
reverse *= 10; /* multiply reverse by 10 */
reverse += d.rem; /* add remainder of division */
} while (d.quot);
return sign * reverse;
}
Look things over and let me know if you have further questions.
As already said you mixed up a and b.
You can't return multiple values.
What you can do is create one number, pack the numbers in an array, pass the pointers to function, place in a struct. You could write something like this:
#include <stdio.h>
int reverse(int x)
{
int a,b,c;
int num;
c = x % 10;
b = (x / 10) % 10;
a = (x / 10) / 10 ;
num = c*100 + b*10 + a;
return num;
}
int main()
{
int x;
scanf("%d", &x);
int num = reverse(x);
printf("%d", num);
}
If you want to return all the values separately you can write something like this for example:
#include <stdio.h>
void reverse(int x , int *a, int *b, int *c)
{
*c = x % 10;
*b = (x / 10) % 10;
*a = (x / 10) / 10 ;
}
int main()
{
int x,a,b,c;
scanf("%d", &x);
reverse(x,&a,&b,&c);
printf("%d%d%d",c,b,a);
}
since you don't want to "return" a single number without the addition operation and display the reversed digits as a whole number there is a way of solving this via the usage of pointers. The code goes like this;
#include <stdio.h>
int* reverse(int);
int main() {
int inputnum;
int *p;
printf("Enter input number: ");
scanf("%d", &inputnum);
p=reverse(inputnum);
printf("\n Output number: ");
for(int i=0;i<3;i++){
printf("%d", *p );
p++;
}
return 0;
}
int* reverse(int x)
{
static int arr [3];
arr[0] = x % 10;
arr[1] = (x / 10) / 10;
arr[2] = (x / 10) % 10 ;
return arr;
}
As you can see, you don't need to use additional integer variables such as a,b,c since we will be storing the data of each operation you have done in a array and treat it as your new number as a whole in the output part. We do this since this is what you specifically asked in your question but there are so much more simpler ways on digit reversing etc. After returning the array that represents the new output number, we can ask our pointer to start from the first index of the array (which is the last digit of the input number in this case) untill the end. By increasing the pointer by 1 we display other digits of our input number as reversed. I hope this will be helpful

How I can Gave The Variable To The Array in c [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am trying to solve a problem, I have one integer variable such as
unsigned int x = 456;
Now I want to decompose my integer to an array of its digits, like so:
unsigned int i[] = {4,5,6};
Then I want to convert each element of the array to a string or char.
Any ideas?
I use Avr studio
#include <stdio.h>
int main(){
unsigned int x = 456;
int len = snprintf(NULL, 0, "%u", x);
unsigned int i[len];
unsigned int wk = x;
for(int k=len-1;k>=0;--k, wk/=10)
i[k]=wk % 10;
for(int k=0;k<len;++k)
printf("%u", i[k]);
char string[len+1];
for(int k=0;k<len;++k)
sprintf(string+k, "%u", i[k]);
printf("\n%s\n", string);
return 0;
}
The easiest way to convert an integer to a string is to use a library function such as snprintf().
If you don't have the standard C library, you can use the classic remainder/division trick:
void uint_to_string(char *buf, unsigned int x, unsigned int digits)
{
buf[digits] = '\0';
while(digits > 0)
{
buf[--digits] = '0' + (x % 10);
x /= 10;
}
}
Note that the above builds the string "backwards" (right to left) since that's easiest. It will generate a 0-padded result, you can fix that by adding code to break out of the loop (after the digit is generated on the first line of the loop's body) if x == 0.
main()
{
unsigned int x = 456;
char i[3];
int j,k;
for (j=0; x!=0; j++){
i[j] = x%10 + '0';
x /= 10;
}
for (k=0; k<j; k++)
printf("%c ", i[k]);
return 0;
}
The answer to this is slightly dependent on your actual problem. Do you need the array of digits, or is this merely the intermediate step you yourself came up with to convert an unsigned integer to a string?
If all you need is the string, it would be much simpler to use a function such as sprintf or snprintf.
#include <stdio.h>
//...
unsigned int x = 456;
char digits[50]; // 50 is chosen arbitrarily
snprintf(digits, 50, "%u", x);
//...
Will yield a null-terminated string in digits that looks exactly like the string representation of x, with the caveat that if x is more than 50 digits it will just do as much as it can. (Though I'm not sure an unsigned int can even have more than 50 decimal digits off the top of my head)
If you want the char* to be exactly the correct size to hold the number, it's only a little more difficult.
#include <stdio.h>
// ...
unsigned int x = 456;
int numDigits = snprintf(NULL, 0, "%u", x); // snprintf returns the number of characters that could potentially be written.
char digits[numDigits];
sprintf(digits, "%u", x);
// ...
Without the standard library available, it gets a bit more hairy, but not unmanageably so. Unfortunately, you're going to need two passes that do almost exactly the same things: one to count the digits and one to actually assign them to your array.
int main( void ) {
// ...
unsigned int x = 456;
int numDigits = countDigits(x);
char digits[numDigits+1]; // The +1 is for null-termination
fillDigitArray(digits, x, numDigits);
// ...
}
int fillDigitArray(char *digits, int x, int numDigits) {
int i;
// This requires perhaps a little explaining
// By far the easiest way to get individual digits of a number is with
// x % 10, but this gives us the righthand-most digits
// Thus by counting DOWN, we're filling our buffer from the RIGHT
// making up for the "backwards" nature.
digits[numDigits] = 0;
for (i = numDigits-1; i >= 0; i--) {
digits[i] = '0' + (x%10);
x /= 10;
}
}
int countDigits(int x) {
// Special case
if( x == 0 ) {
return 1;
}
int numDigits;
while(x > 0) {
x /= 10;
numDigits++;
}
return numDigits;
}
Extracting it into an array of unsigned ints is similar, just make digits an unsigned int * rather than a char *, and instead of making digits[i] = '0' + x%10 make it digits[i] = x%10.
Edit: In the interest of fully explaining the example, x%10 is "x mod 10", which can roughly be stated as "give me the rightmost digit of x". x /= 10, while dividing x by 10 and overwriting x with the new value, is essentially just our way of saying "make the right-most digit of x what is currently in the 10's place".
The '0'+ x%10 part is admittedly a bit of magic. The actual ASCII character value for the number "0" isn't actually 0, but the digits 0-9 are laid out in order. So if the rightmost digits of x is 0, we get '0'+0, which is '0', and if we get the rightmost digit as 9 '0'+9' becomes '9'. Using this allows us to bypass an ugly if or switch statement to map the number to the right character.
Getting each digit is a math/logic problem. You need to use the modulus operator which gives you the remainder of the division of the operands.
#include <stdio.h>
static char digits[10];
int main(void) {
int number = 4056;
int remainder = 0;
int i = 0;
while(number > 0 && digits[i] >= 0) {
remainder = number % 10;
number /= 10;
digits[i] = 48 + remainder;
i++;
}
for(i--; i >= 0; i--) {
printf("%c", digits[i]);
}
printf("\n");
}

How do I turn an integer into an array of digits without using strings?

For example take 123 and put it into an array where that is a[3] = {1, 2, 3}?
Without converting it to a string and iterating over it.
You can get the decimal digits of a number by using integer division and modulo.
//Pseudo code
int[MAX_SIZE] result;
int index = 0;
while (workingNumber > 0)
{
digit = workingNumber % 10;
result[index] = digit;
workingNumber = workingNumber / 10; //Must be integer division
index++;
}
#include <math.h>
...
int number = 5841;
int size = log10(number) + 1;
int arr[size];
int i = size;
while(i >= 0)
{
arr[--i] = number % 10;
number /= 10;
}
First, keep in mind that in C the only real difference between "array of char" and "string" is to be a string, you put a NUL-terminator at the end of the array of char.
Assuming you wanted (for example) to create an array of int (or long, or something else other than char), you'd typically take the remainder when dividing by 10 and convert it to a digit by adding '0'. Then divide the number by 10 and repeat until it's reduced to zero. That creates the numbers from least to most significant, so you normally deposit them at the end of the array and work backward toward the beginning.
#include <stdio.h>
#include <math.h>
#define LEN 3
int main(int argc,char* argv[])
{
int i = 123;
int a[LEN];
int digit;
int idx = log10(i);
do {
digit = i % 10;
i /= 10;
a[idx--] = digit;
} while (i != 0);
printf("a: { %d, %d, %d }\n", a[0], a[1], a[2]);
return 0;
}

Resources