Cannot do a simple function using call by value method in C - c

I am trying to test this method (call by value) i recently learned, but for unkown reasons for me, the code isn't working, can someone explain me why? (sorry for the mess by the way)
#include <stdio.h>
#include <stdlib.h>
void fact(int i);
int main() {
int x;
scanf("%d", x);
//function called:
fact(x);
printf("value of x! = %d", x);
return 0;
}
//factorial definition:
void fact(int i){
int j=0;
for(i=1; j>1; j--){
i= i * j;
return;
}
}

If you are using a call to a function by value to make calculations with the passed argument then to get the result of the calculations in the caller the function must return a value. That is its return type should not be void.
The definition of the function fact does not make sense. In the for loop the parameter i is reassigned to 1. The loop itself never iterates because another variable j is set to 0. So it can not be greater than 1.
int j=0;
for(i=1; j>1; j--){
The function can be defined the following way
//factorial definition:
unsigned long long int fact( unsigned int i )
{
unsigned long long int f = 1;
while ( i > 1 ) f *= i--;
return f;
}
The factorial is defined for unsigned natural integers.
In main you need to declare a variable of the type unsigned int like
unsigned int x;
This call of scanf
scanf("%d", x);
is incorrect. The function needs to accept its integer argument by reference to change it.
scanf( "%u", &x );
To get the result of the function fact you have to introduce one more variable
unsigned long long int result = fact( x );
And to output it you should write
printf( "value of %u! = %llu\n", x, result );
Here is a demonstrative program.
#include <stdio.h>
unsigned long long int fact( unsigned int );
int main(void)
{
unsigned int x;
scanf( "%u", &x );
unsigned long long int result = fact( x );
printf( "value of %u! = %llu\n", x, result );
return 0;
}
//factorial definition:
unsigned long long int fact( unsigned int i )
{
unsigned long long int f = 1;
while ( i > 1 ) f *= i--;
return f;
}
If to enter the number 20 then the function output will be
value of 20! = 2432902008176640000
Pay attention to that 20 is the maximum number the factorial of which can be stored in an object of the type unsigned long long int.
If you want that the function accepted its argument by reference and returned the result in the argument then you have to declare the variable x as having the type unsigned long long int.
Here is a demonstrative program.
#include <stdio.h>
void fact( unsigned long long int * );
int main(void)
{
unsigned long long int x;
scanf( "%llu", &x );
printf( "value of %llu! = ", x );
fact( &x );
printf( "%llu\n", x );
return 0;
}
//factorial definition:
void fact( unsigned long long int *x )
{
unsigned long long int f = 1;
while ( *x > 1 ) f *= ( *x )--;
*x = f;
}
If to enter 20 then the program output will be the same as shown above.
value of 20! = 2432902008176640000

Scanf takes a pointer to the variable, to return something from a void function you must call it by reference with a pointer to the return variable and not by its value.

Problem 1:
scanf("%d", x);
Should be:
scanf("%d", &x);
The & is very important.
Problem 2
In function fact, you start j at 0:
int j=0;
Your loop only runs while j>1:
for(i=1; j>1; j--){
Tell me: When is 0 ever >1??
Your loop will never run.
Problem 3:
You expect that calling fact(x); will change the value of x.
In C, a function cannot change one of its arguments; arguments are passed "by-copy".
If you wish to change an object (variable) in the caller, you must pass a pointer to it:
void fact(int* i);
[...]
//function called:
fact(&x);
[...]
//factorial definition:
void fact(int* i){
int j=0;
for(*i=1; j>1; j--){
*i= *i * j;
return;
}
}

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;
}

To calculate power of a number using call by reference

#include <stdio.h>
void power(int *x,int *y);
int main()
{
int m,n;
printf("Enter the number and power :-");
scanf("%d%d",&m,&n);
power(&m,&n);
}
void power(int* x, int* y)
{
int i,result=1;
if(*y==0)
printf("The result = 1");
else
{
for(i=0; i<*y; i++)
{
result *= (*x);
}
printf("The result of %d^%d = %d",*x,*y,result);
}
}
The result of 10^10 comes out to be 1410065408 I don't know what am I doing wrong
you visibly have an overflow, probably your intare on 32bits
using long long :
#include <stdio.h>
void power(long long *x,long long *y);
int main()
{
long long m,n;
printf("Enter the number and power :-");
scanf("%lld%lld",&m,&n);
power(&m,&n);
}
void power(long long* x, long long* y)
{
long long i,result=1;
if(*y==0)
printf("The result = 1");
else
{
for(i=0; i<*y; i++)
{
result *= (*x);
}
printf("The result of %lld^%lld = %lld",*x,*y,result);
}
}
Compilation and execution:
pi#raspberrypi:/tmp $ gcc -Wall p.c
pi#raspberrypi:/tmp $ ./a.out
Enter the number and power :-10 10
The result of 10^10 = 10000000000pi#raspberrypi:/tmp $
To be sure to use 64b int you can use int64_t
You're using int for the result, and it doesn't fit. You need to use long. The size of int is 32 bits which has a max signed value of 2147483647.
Your given program uses 4-bytes integer which is capable to hold the values between -2,147,483,648 to 2,147,483,647 but 10^10 is too large to hold it.
Taking the appropriate type (such as long long) to hold such large outcome will easily solve your issue (notice the comments as an explanation to the code):
#include <stdio.h>
// The function signature
void power(int *x, int *y);
int main(void) {
int bs, pw;
printf("Enter the value of base and power: ");
// Verifying the inputs
if (scanf("%d%d", &bs, &pw) != 2)
// If the values were incorrectly entered, then it returns
// with an error code without further actions
return 1;
power(&bs, &pw);
return 0;
}
// The function definition
void power(int *x, int *y) {
long long result = 1;
// Dereferencing and using assignment operator for self-multiplication with
// the dereferenced 'x'
for (int i = 0; i < *y; i++)
result *= *x;
printf("Results: %lld\n", result);
}
A sample test case:
Enter the value of base and power: 10 10
Results: 10000000000
Works on OnlineGDB as well.

Compiler Error C2440 in C

I'm finishing a program that I found in my C book but I ran into some issues.
I'm just about done but I keep getting this error
Error 1 error C2440: 'function' : cannot convert from 'double [15]' to '
Why am i getting this compiler error?
void arrayRead(double, int*);
void arrayList(double, int*);
void arraySum(double, int*, int*);
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<ctype.h>
int main()
{
int num, sum = 0;
double array[15];
printf("How many doubles (numbers) would you like in the array (20 max)?\n");
scanf("%d", &num);
printf("Thank you! Now give me %d different doubles (numbers) please!\n", num);
arrayRead(array, &num);
printf("Here are all of your integers again!\n");
arrayList(array, &num);
arraySum(array, &num, &sum);
printf("The sum of these numbers = %d\n", sum);
return 0;
}
void arrayRead(double array[], int* num)
{
for (int i = 0; i < *num; i++)
{
scanf("%lf", &array);
}
}
void arrayList(double array[], int*num)
{
for (int i = 0; i < *num; i++)
{
printf("%.2f\n", array);
}
}
void arraySum(double array[], int*num, int* sum)
{
for (int i = 0; i < *num; i++)
{
*sum = array + *sum;
}
}
best to place prototypes after any #include statements,
just in case the prototype uses something defined in the header file
The size of the array must be a positive number,
so use '%u' to input a positive numbe
and define the max variable as unsigned
The parameters to functions and the parameters passed when calling those functions need to have matching types (or the function type be a 'promotion' of the passed type.
since the array is doubles, all the references should also be double, like the sum variable.
appropriate horizontal white space makes the code much easier to read
do not #include header files those contents are not being used.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
//#include <ctype.h>
// prototypes
void arrayRead( double*, unsigned );
void arrayList( double*, unsigned );
void arraySum ( double*, unsigned, double* );
int main( void )
{
unsigned num;
double sum = 0.0;
printf( "How many doubles (numbers) would you like in the array (20 max)?\n" );
if( 1 != scanf( "%u", &num ) )
{
perror( "scanf for size of array failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
// need to add check that user entered value is in range 1...20
double array[ num ];
printf( "Thank you! Now give me %u different doubles (numbers) please!\n", num );
arrayRead( array, num );
printf( "Here are all of your integers again!\n" );
arrayList( array, num );
arraySum( array, num, &sum );
printf("The sum of these numbers = %lf\n", sum);
return 0;
} // end function: main
void arrayRead( double array[], unsigned num )
{
for ( unsigned i = 0; i < num; i++ )
{
scanf("%lf", &array[i]);
}
} // end function: arrayRead
void arrayList( double array[], unsigned num )
{
for ( unsigned i = 0; i < num; i++ )
{
printf("%.2f\n", array[i]);
}
} // end function: arrayList
void arraySum( double array[], unsigned num, double* sum )
{
for ( unsigned i = 0; i < num; i++ )
{
*sum = array[i] + *sum;
}
} // end function: arraySum
Here is the output from a simple run of the answer code:
How many doubles (numbers) would you like in the array (20 max)?
5
Thank you! Now give me 5 different doubles (numbers) please!
1 1 1 1 1
Here are all of your integers again!
1.00
1.00
1.00
1.00
1.00
The sum of these numbers = 5.000000
The functions you have declared have different signatures than the functions you have defined.
Be careful in the declaration you use double instead of double *. It is not the same.
When you call the arrayRead function and company, the compiler sees only the declared functions as the defined functions are after the calls. So the parameters doesn't match.
By the way, in the defined functions you forgot to write the index. You are using the pointer and this can't work. You need to write array[i] inside each loop.

How to show bytes of float

I personally use a function show_bytes as follows:
#include<stdio.h>
typedef char *byte_pointer;
void show_bytes (byte_pointer x)
{
int length = sizeof(float);
int i;
for(i = 0;i <length;i++)
{
printf("%2x",*(x+i));
printf("\n");
}
}
int main()
{
float obj;
printf("please input the value of obj:");
scanf("%f",&obj);
show_bytes((byte_pointer) &obj);
}
when i input 120.45,which should be 0x42f0e666
please input the value of obj:120.45
66
ffffffe6
fffffff0
42
why so many 'f' before the e6 and f0 while i use %.2x.
Your function should be:
void show_bytes (byte_pointer x)
{
int i;
for(i = 0; i <sizeof(float); i++)
{
printf("0x%2X\n", (unsigned int)(*(x++) & 0xFF));
}
}
or
typedef uint8_t *byte_pointer;
void show_bytes (byte_pointer x)
{
int i;
for(i = 0; i <sizeof(float); i++)
{
printf("0x%2X\n", *(x++));
}
}
In your code the problem is that the pointer type is signed an is promoted to signed int by printf.
%2X format does not limit the output digit, tells only to printf that the result string must be at least 2 characters long.
First solution: the value is promoted to signed int but the passed
value is truncated to the LSB.
Second example: value is truncated by the type of pointer, that
is unsigned char.
The rule is: to raw access memory, always use unsigned types.

Unable to get a factorial function to work in C

I cannot get the following code to work.
#include <stdio.h>
// I am not sure whethere I should void here or not.
int main() {
// when the first bug is solved, I put here arg[0]. It should be
// similar command line parameter as args[0] in Java.
int a=3;
int b;
b = factorial(a);
// bug seems to be here, since the %1i seems to work only in fprintf
printf("%1i", b);
return 0;
}
int factorial(int x) {
int i;
for(i=1; i<x; i++)
x *= i;
return x;
}
How can you get the code to work?
You're modifying your loop terminating variable (x) inside the loop. Currently your code blows up after a few iterations, when x overflows the range of a 32 bit integer and then becomes negative and very large, hence terminating the loop.
It should be:
int factorial(int n) {
int i, x = 1;
for (i = 2; i <= n; ++i) {
x *= i;
}
return x;
}
Better yet, you should use long instead of int for the variable x and the return value, because n! gets very large very quickly.
AInitak gave the right answer, but I want to add that one way you can find the bug in your code is to print out the values of i and x in the factorial loop.
int factorial(int x) {
int i;
for(i=1; i<x; i++)
{
x *= i;
printf("%d, %d\n", i, x);
}
return x;
}
This gives you the output
1, 3
2, 6
3, 18
4, 72
5, 360
6, 2160
7, 15120
8, 120960
9, 1088640
10, 10886400
11, 119750400
12, 1437004800
13, 1501193216
14, -458131456
-458131456
This makes it easier to see what's going wrong. The loop doesn't stop where you expect it to for the reasons AInitak explained.
It's bad style in C to leave out void when defining or declaring a function. So put it in
int main(void)
While it doesn't change anything about the number of parameters the function has (the function has zero parameters without that void either), it will declare the function as one that accepts only zero arguments, while it won't tell anything about the amount and types of accepted arguments when you omit the void. However, both versions with and without void are correct.
Read this answer about that matter too.
#include<stdio.h>
#include<stdlib.h>
int main(int c,char *v[])
{
int x,y;
int *num;
if(c==1)
{
printf("Usage : programName : number");
return 0;
}
num=(int *)malloc(sizeof(int));
*num=atoi(v[1]);
x=1;y=1;
while(x<=*num)
{
y=y*x;
x++;
}
printf("Factorial of %d is %d ",*num,y);
free(num);
return 0;
}
What error message do you get?
First off, declare your function factorial before main. Also, pay attention to correct indentation. Your declaration of function main is correct, by the way.
I would suggest to use also double or unsigned long for factorial computation in order to be able to compute the greater value of the factorial function.
double fact( double n)
{
if ( n == 1)
return 1;
return n*(fact(n-1));
}
A more elegant non-recursive function.
#include<stdio.h>
long long int fact(long long int);
long long int fact(long long int n){
long long int num = 1;
long long int fi = 0;
for(long long int i=2;i<=n;i++){
for(long long int j=1;j<=i;j++){
fi += num;
}
num = fi;
fi = 0;
}
return num;
}
int main(){
long long int n;
scanf("%lld",&n);
printf("%lld\n",fact(n));
return 0;
}

Resources