Here is the task I was given:
Write a function fact_calc that takes a string output argument and an integer input argument n and returns a string showing the calculation of n!. For example, if the value supplied for n were 6, the string returned would be
“6! x 6 x 5 x 4 x 3 x 2 x 1 x = 720”. Write a program that repeatedly prompts the user for an integer between 0 and 9, calls fact_calc and outputs the resulting string in a box of asterisks of the right size to surround the result. If the user inputs an invalid value, the program should display an error message and reprompt for valid input. Input of the sentinel -1 should cause the input loop to exit.
Here is my code:
#include <stdio.h>
/*Prototypes*/
void fact_calc(char [], int);
int main(void)
{
char calc[99];
int num1;
do{
printf("Enter an integer between 0 and 9 or -1 to quit: ");
scanf("%d", &num1);
fact_calc(calc, num1);
}while( num1 != -1 );
return (0);
} //end main
/*Place function definitions below*/
void fact_calc(char calc[], int num1)
{
if(num1 == 0)
char calc[] = "0! = 0 = 0";
else if(num1 == 1)
char calc[] = "1! = 1 = 0"
else if(num1 == 2)
char calc[99] = "2! = 2 x 1 = 2"
else if(num1 == 3)
char calc[99] = "3! = 3 x 2 x 1 = 6"
else if(num1 == 4)
char calc[99] = "4! = 4 x 3 x 2 x 1 = 24"
else if(num1 == 5)
char calc[99] = "5! = 5 x 4 x 3 x 2 x 1 = 120"
else if(num1 == 6)
char calc[99] = "6! = 6 x 5 x 4 x 3 x 2 x 1 = 720"
else if(num1 == 7)
char calc[99] = "7! = 7 x 6 x 5 x 4 x 3 x 2 x 1 = 5040"
else if(num1 == 8)
char calc[99] = "8! = 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 40320"
else if(num1 == 9)
char calc[99] = "9! = 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 362880"
else
printf("Invalid Entry");
}
I am getting the error:
expected
expression
ch...
^
I still have to print out the string but I can't figure out what the error means or what I am doing wrong. Thanks in advance for the help!
char calc[] = "1! = 1 = 0"
Don't you think you should be ending this line with a ;
char calc[] = "1! = 1 = 0";
Similar fix needs to be done for the rest of the lines
Your program is doing something strange. I doubt it does what you expect.
You are declaring variables inside the body of if statements. These variables will only be in scope for the body, and you don't do anything with them.
Your program can be made to work. I suggest simply making fact_calc() return literal strings rather than try to assign to variables.
/*Place function definitions below*/
char const *fact_calc(char calc[], int num1)
{
if(num1 == 0)
return "0! = 0 = 0";
else if(num1 == 1)
return "1! = 1 = 0";
else if(num1 == 2)
return "2! = 2 x 1 = 2";
else if(num1 == 3)
return "3! = 3 x 2 x 1 = 6";
else if(num1 == 4)
return "4! = 4 x 3 x 2 x 1 = 24";
else if(num1 == 5)
return "5! = 5 x 4 x 3 x 2 x 1 = 120";
else if(num1 == 6)
return "6! = 6 x 5 x 4 x 3 x 2 x 1 = 720";
else if(num1 == 7)
return "7! = 7 x 6 x 5 x 4 x 3 x 2 x 1 = 5040";
else if(num1 == 8)
return "8! = 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 40320";
else if(num1 == 9)
return "9! = 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 362880";
/* Invalid Entry */
return NULL;
}
Then your main function should declare a variable of type char const * to store the pointer returned by this function, and should check that the pointer is not set to NULL (and print "Invalid Entry" if the pointer was set to NULL).
You cannot assign strings (char arrays) in C. You should use strcpy() instead.
E.g.
strcpy(calc, "2! = 2 x 1 = 2");
Note that you should use strcpy() only if you are 100% certain calc is large enough to store the entire string. If not, use strncpy() instead. Example:
strncpy(calc, "2! = 2 x 1 = 2", 99);
calc[98] = '\0';
// a better way would be to pass 99 to your function, or to declare a macro
Finally, note that both 0! and 1! should be 1, not 0.
Related
We were having a quiz of sorts and had the following question where we had to find the error, or if there's none, the output of the given code:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
n--;
goto b;
}
return 0;
}
I don't see anything wrong with this in theory but this leads to an infinite loop with the variable going way below 0. Could anyone help me with this?
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n);
if(n!=0){
n--;
goto b;
}
return 0;
}
This would work. The version you posted does not work because it will never get to 0. It is subtracting once in the if statement, and once in the printf.
You should only have one n-- statement. otherwise even if it reaches 0, when it get the first n-- it will be decremented one more time and will become -1. (so it will never match 0).
Hence, please change your code to
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
goto b;
}
return 0;
}
The condition if (n != 0) is always getting satisfied.
On each iteration the number n decreases by 2.
So when n = 2, it gets decremented once after printf("%d\n",n--)
then the condition if (n != 0) is true, as n = 1
Inside the condition block n is decremented once again, n = 0
So the next time before reaching the condition if (n != 0), n equals to -1,
which leads to an infinite loop.
In C 012 is an octal base number, in decimal it is equal to 10.
This code:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
n--;
goto b;
}
return 0;
}
Does this:
print n (10)
subtract 1 of n (n = 10 - 1 = 9)
check if n != 0 (9 != 0 -> true)
subtract 1 of n (n = 9 - 1 = 8)
jump to b
print n (8)
subtract 1 of n (n = 8 - 1 = 7)
check if n != 0 (7 != 0 -> true)
subtract 1 of n (n = 7 - 1 = 6)
jump to b
print n (6)
subtract 1 of n (n = 6 - 1 = 5)
check if n != 0 (5 != 0 -> true)
subtract 1 of n (n = 5 - 1 = 4)
jump to b
print n (4)
subtract 1 of n (n = 4 - 1 = 3)
check if n != 0 (3 != 0 -> true)
subtract 1 of n (n = 3 - 1 = 2)
jump to b
print n (2)
subtract 1 of n (n = 2 - 1 = 1)
check if n != 0 (1 != 0 -> true)
subtract 1 of n (n = 1 - 1 = 0)
jump to b
print n (0)
subtract 1 of n (n = 0 - 1 = -1)
check if n != 0 (-1 != 0 -> true)
subtract 1 of n (n = -1 - 1 = -2)
jump to b
print n (-2)
...
...
... goes on infinitely
Note that when n will never equal to 0 when the program checks if n != 0, because in this evaluation n is always an odd number since two subtractions by 1 are made every time.
Change from b: printf("%d\n",n--); to b: printf("%d\n",n);.
or
Change from
if(n!=0){
n--;
goto b;
to
if(n!=0){
n;
goto b;
Because n-- equals n = n - 1.
Your program:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--); // n = n - 1
if(n!=0){
n--; // n = n - 1
goto b;
}
return 0;
}
for out put [10, 8, 6, 4,2, 0]
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n>0){
n--;
goto b;
}
return 0;
}
for [10,9,8,7,6,5,4,3,2,1]
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n>0){
//n--;
goto b;
}
return 0;
}
i'm a beginner in programming.
the code does get compiled but prints out values not understandable.
when i put those values inside the outer "for" by declaring extra integers, and put them into use, the code seems to properly work. What is the problem with the code below? Thanks!
#include <stdio.h>
int main( int argc, char** argv ) {
int num1, num2, i, j, k;
printf( "Enter the two Integers: " );
scanf( "%d%d", &num1, &num2 );
for ( i = (num1 < num2) ? num1 : num2; i <= (num1 > num2) ?num1 : num2; ; i++ ) {
for ( j = 1; j <= 9; j++ ) {
printf( "%d x %d = %-2d", i, j, i*j );
}
printf( "\n" );
}
return EXIT_SUCCESS;
}
You have a problem with operator precedence. The ternary operator has very low precedence, higher only than the assignment operator, compound assignment operators, and comma operator. Thus, your loop condition
i<=(num1>num2)?num1:num2
is equivalent to
(i<=(num1>num2))?num1:num2
. That expression will always evaluate to the value of either num1 or num2, so unless one of those is zero, your loop will never terminate. This also explains why you observed different behavior when you precomputed the ternary expressions.
You want this:
for(i = ((num1 < num2) ? num1 : num2);
i <= ((num1 > num2) ? num1 : num2); i++) {
But actually, I'd recommend the precomputation in the first place. The code is slightly longer, but much clearer.
For starters there is a typo in the for statement
for(i=(num1<num2)?num1:num2;i<=(num1>num2)?num1:num2;; i++)
^^^^
There is a redundant semicolon.
According to the C Standard the conditional operator is defined the following way
conditional-expression:
logical-OR-expression ? expression : conditional-expression
Relative to this expression
i<=(num1>num2)?num1:num2
then it is interpreted like
( i<=(num1>num2) ) ? num1 : num2
It is evident that you mean instead
i <= (num1 > num2 ? num1 : num2 )
Nevertheless it would be better to use one if statement before the loops than using the conditional operators in the loop.
Take into account that in any case the first loop is unsafe because the user can enter a value equal to INT_MAX. In this case the program will have undefined behavior. It is better and safe to use do-while loop.
Also for the result of multiplication it is better to use the type long long int.
The program can look the following way
#include <stdio.h>
int main(void)
{
int num1 = 0, num2 = 0;
printf( "Enter two Integers: " );
scanf( "%d%d", &num1, &num2 );
if ( num2 < num1 )
{
int tmp = num1;
num1 = num2;
num2 = tmp;
}
int i = num1;
do
{
for ( int j = 1; j < 10; j++ )
{
printf( "%d x %d = %-2lld\n", i, j, ( long long int )i * j );
}
printf("\n");
} while ( i++ != num2 );
return 0;
}
Its output might look like
Enter two Integers: 1 5
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
1 x 4 = 4
1 x 5 = 5
1 x 6 = 6
1 x 7 = 7
1 x 8 = 8
1 x 9 = 9
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
2 x 6 = 12
2 x 7 = 14
2 x 8 = 16
2 x 9 = 18
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
4 x 1 = 4
4 x 2 = 8
4 x 3 = 12
4 x 4 = 16
4 x 5 = 20
4 x 6 = 24
4 x 7 = 28
4 x 8 = 32
4 x 9 = 36
5 x 1 = 5
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25
5 x 6 = 30
5 x 7 = 35
5 x 8 = 40
5 x 9 = 45
Your weird results are due to operator precedence, the ternary operator is executed after comparing i with (num1>num2). So when you write
i<=(num1>num2)?num1:num2;
You're actually writing something like
(i<=(num1>num2))?num1:num2;
So the condition relies on the value of num1 or num2. Just add parenthesis around your ternary operator and you're good.
In i<=(num1>num2)?num1:num2, <= has higher precedence than ? :. So this expression is equivalent to:
(i <= (num1 > num2)) ? num1 : num2;
Thus, the expression always evaluates to one of num1 or num2. If they are both non-zero, then the loop continues forever.
What you actually want is:
i <= (num1 > num2 ? num1 : num2)
The etrtra ; is the problem. It means do nothing. The i++ as the 4th statement is ignored.
Anyway, complex expressions inside the for statement make code more difficult to read (by humans) same times with the negative performance effect.
I have these variables:
int dividend;
int divider;
And I have the function :
Divisibility7 (int num);
Those two variables will be at the main function, and the user will be asked to enter the dividend and divider, but in case the user enter the divider 7, then, the function above will be called.
The problem is that I have to follow specific criteria to do this. So let's say the user will enter with the dividend 7203. This happen :
I. Get the last digit of the number.
Last digit: 3
Ii. Multiply the last digit by 2
3 x 2 = 6
Iii. Get the value of the initial number, without the last digit.
720
Iv. Subtract the initial value without the last digit from the multiplication result.
fabs (720 - 6) = 714
V. Repeat the process until the result is a value less than or equal to 70
Vi. Compare the result with the table of contents (0, 7, 14, 21, 28, 35, 42, 49, 54, 63, 70) for
Determine whether or not the number is divisible by 7
Code :
int res;
int x;
int y;
int Divisibility7(int num) {
int res;
int x;
int y;
int z;
while(num > 70) {
x = num % 10; // get the last digit from the number
y = x * 2; // multiply the last digit by 2;
z = num/10; // get the first digits from the number
fabs(z - y); // subtract the first digits with the last digits;
}
}
In the part of the while, the final fabs(z-y) returns what I want, to be the first digits subtracting the last number, but the problem is that the while stop there, I have to do something to make this while go till 70 or less.
PS : I need to check if the final number from the iterations, it's a number multiplied by 7, how can I do that ? And I can't use mod for this.
You have not changed num in your while loop . Also you do no return the value . Hope the following code will be ok for you .
int Divisibility7(int num) {
int res,x,y,z;
while(num > 70) {
x = num % 10; // get the last digit from the number
y = x * 2; // multiply the last digit by 2;
z = num/10; // get the first digits from the number
num = abs(z - y); // subtract the first digits with the last digits;
}
if(num == 0 || num == 7 || num == 14 || num == 21 || num == 28 || num == 35 || num == 42 || num == 49 || num == 54 || num == 63 || num == 70) {
return 1;
}
else {
return 0;
}
}
Not sure, but I think this is what are you trying to do:
int main (void)
{
int number, lastDigitMultiplied;
scanf("%d", &number);
while(number > 70){
//get the last digit and multiply it by 2
lastDigitMultiplied = (number % 10) * 2;
//subtract the initial value without the last digit from the multiplication result.
number = number / 10 - lastDigitMultiplied;
}
if(abs(number) % 7 == 0)
printf("The result is %d and it is a multiple of 7", number);
else
printf("The result is %d and it is not a multiple of 7", number);
return 0;
}
for divisibility against 7, if you have a positive large bigint already formatted as a string, don't waste time with the regular method doing it 1 digit at a time.
powers of 10, mod 7, repeats every 6 rounds :
10^1 % 7 = 3 10^7 % 7 = 3 10^13 % 7 = 3
10^2 % 7 = 2 10^8 % 7 = 2 10^14 % 7 = 2
10^3 % 7 = 6 10^9 % 7 = 6 10^15 % 7 = 6
10^4 % 7 = 4 10^10 % 7 = 4 10^16 % 7 = 4
10^5 % 7 = 5 10^11 % 7 = 5 10^17 % 7 = 5
10^6 % 7 = 1 10^12 % 7 = 1 10^18 % 7 = 1
meaning, the effects of the digits mod 7 stay identical as long as they're in chunks of 6 digits at a time.
the largest multiple of 6-digits supported by double precision FP to full integer precision would be 12-digits at a time.
So the way to do it is to right-align the digits by padding leading edge zeros to ensure string length is a multiple of 12. Then simply add the digits onto each other, performing a single mod % 7 operation once every 9000 or so rounds of the addition loop
—- (that's when you run up against 2^53 limit; 9007 rounds if u wanna be pedantic about it)
example :
x = 71400535477047763120175175402859619447790
02233464423375355339031113233806609150957
x % 7 = 4
now try summing up chunks of 12 :
007140053547704776312017517540285961944779
002233464423375355339031113233806609150957
007140053547 7140053547
704776312017 711916365564
517540285961 1229456651525
944779002233 2174235653758
464423375355 2638659029113
339031113233 2977690142346
806609150957 3784299293303
----------------------------
3784299293303 % 7 = 4
it works exactly the same for any multiples of 6 : e.g. 6, 18, 24, and 30 --
00714005354770477631201751754
02859619447790022334644233753
55339031113233806609150957
312017 312017
517540 829557
285961 1115518
944779 2060297
002233 2062530
464423 2526953
375355 2902308
339031 3241339
113233 3354572
806609 4161181
150957 4312138
007140 4319278
053547 4372825
704776 5077601
----- -------
_ 5077601 % 7 = 4
00000000714005354770477631201
75175402859619447790022334644
23375355339031113233806609150957
464423375355339031 464423375355339031
113233806609150957 577657181964489988
000000007140053547 577657189104543535
704776312017517540 1282433501122061075
285961944779002233 1568395445901063308
---------------------------------------
1568395445901063308 % 7 = 4
00000000000000714005354770477
63120175175402859619447790022
33464423375355339031113233806
609150957
339031113233806609150957 339031113233806609150957
000000000000007140053547 339031113233813749204504
704776312017517540285961 1043807425251331289490465
944779002233464423375355 1988586427484795712865820
---------------------------------------------------
1988586427484795712865820 % 7 = 4
000000007140053547704776312017517
540285961944779002233464423375355
339031113233806609150957
000000007140053547704776312017 7140053547704776312017
517540285961944779002233464423 517540293101998326707009776440
375355339031113233806609150957 892895632133111560513618927397
892895632133111560513618927397 % 7 = 4
I am trying to understand how recursion works in the factorial function. What should I print, so that I can see what actually happens during each recursion call?
Here's the code:
#include <stdio.h>
#include <stdlib.h>
long factorial(long number) {
if(number <= 1) {
return 1;
} else {
return number * factorial(number - 1);
}
}
int main() {
int i;
for(i = 0; i <= 10; i++) {
printf("%2d ! = %ld\n", i, factorial(i));
}
return 0;
}
The following code
#include <stdio.h>
#include <stdlib.h>
long factorial (int level, long number){
int result;
printf("[%03d] Calculating: %d\n", level, number);
if(number <= 1)
{
result = 1;
}
else
{
result = number * factorial(level+1, number - 1);
}
printf("[%03d] Returning: %d\n", level, result);
return result;
}
int main(){
int i;
for(i = 0; i <= 10; i++)
{
printf("%2d ! = %ld\n", i, factorial(0, i));
}
return 0;
}
gives this output
[000] Calculating: 10
[001] Calculating: 9
[002] Calculating: 8
[003] Calculating: 7
[004] Calculating: 6
[005] Calculating: 5
[006] Calculating: 4
[007] Calculating: 3
[008] Calculating: 2
[009] Calculating: 1
[009] Returning: 1
[008] Returning: 2
[007] Returning: 6
[006] Returning: 24
[005] Returning: 120
[004] Returning: 720
[003] Returning: 5040
[002] Returning: 40320
[001] Returning: 362880
[000] Returning: 3628800
10 ! = 3628800
Where [XXX] is the current level of recursion.
Try this
long factorial (long number){
if(number <= 1){
return 1;
}else{
return number * factorial(number - 1);
}
}
Assume we pass 4 as first parameter, then function evaluates to:
long factorial (long number /*==4*/){
if(4 <= 1){//false
return 1;
}else{
return 4 * factorial(4 - 1);
}
}
Note return in else can't finish, because it calls another function - factorial (4-1).
So 4 must be multiplied by the result of factorial (3). So it goes and executes factorial(3).
Now we get
long factorial (long number /*==3*/){
if(3 <= 1){//false
return 1;
}else{
return 3 * factorial(3 - 1);
}
}
But again the return here can't finish, since it calls factorial for 3-1=2.
Now one needs to evaluate factorial (2), result of which will be multiplied by 3 and passed to previous return. Again:
long factorial (long number /*==2*/){
if(2 <= 1){//false
return 1;
}else{
return 2 * factorial(2 - 1);
}
}
We have similar problem. But now when executing factorial (2-1) the function will immediately return 1, hence above line will return 2.
This result will be plugged to the result of previous return, giving 2*3; this result - 6 - will be plugged in previous return and yield 6*4, which is the final result 24.
For something ridiculous, factor out the body of factorial:
long factorial_body(long number) {
if(number <= 1) {
return 1;
} else {
return number * factorial(number - 1);
}
}
Then, rewrite factorial to call factorial_body, printing some stuff around the call.
long factorial (long number) {
static char output[4096];
static int level;
static int index;
int saved_index;
long result;
switch (level++) {
case 1: index += snprintf(output + index, sizeof(output) - index, "= ");
default: index += snprintf(output + index, sizeof(output) - index,
"%ld x ", number + 1);
case 0: snprintf(output + index, sizeof(output) - index,
"factorial(%ld)\n", number);
}
saved_index = index;
printf("%s", output);
result = factorial_body(number);
index = saved_index;
snprintf(output + index, sizeof(output) - index,
--level ? "%ld\n" : "= %ld\n", result);
printf("%s", output);
return result;
}
factorial(10) will generate the following output:
factorial(10)
= 10 x factorial(9)
= 10 x 9 x factorial(8)
= 10 x 9 x 8 x factorial(7)
= 10 x 9 x 8 x 7 x factorial(6)
= 10 x 9 x 8 x 7 x 6 x factorial(5)
= 10 x 9 x 8 x 7 x 6 x 5 x factorial(4)
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x factorial(3)
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x factorial(2)
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x factorial(1)
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2
= 10 x 9 x 8 x 7 x 6 x 5 x 4 x 6
= 10 x 9 x 8 x 7 x 6 x 5 x 24
= 10 x 9 x 8 x 7 x 6 x 120
= 10 x 9 x 8 x 7 x 720
= 10 x 9 x 8 x 5040
= 10 x 9 x 40320
= 10 x 362880
= 3628800
I am dubious if the above output will help enhance your understanding of recursion. But, working to understand how the printing code works probably would lead to a better understanding of recursion.
Instead of print statements add whatever you would print to an array or something and then print them out in the order that they were inserted (fifo) after the recursive function is finished.
This should give you a trace of the execution of factorial, with indentation:
long factorial(long number, int depth){
printf("%*s enter, number = %d\n", 4*depth, "", number);
long result = 1;
if (number > 1) result = number * factorial(number-1, depth+1);
printf("%*s exit, result = %d\n", 4*depth, "", result);
return result;
}
I have a homework that include a new operation (a [n] b), given:
a [1] b = ab
a [n] 1 = a
2 [2] 3 = 2 [2-1] (2 [2-1] 2) 2 repeated 3 times = 2 [1] (2 [1] 2) = 222 = 16
2 [2] 2 = 2 [2-1] 2 2 repeated 2 times = 2 [1] 2 = (22) = 4
4 [3] 3 = 4 [3-1] (4 [3-1] 4) = 4 [2] (4 [2] 4) 4 repeated 3 times = 4 [2] (4 [1] (4 [1] ( 4 [1] 4))) =
= 4 [2] 4 444
I don't need a solution, I just need advice so that I can solve it myself.
What is being said here can be rephrased as follows.
For any positive integers a, b and n define
a [n] b = a [n-1] ( a [n-1] ( ... a ) ) taken b times
In a C-like language
int myoperator (a, n, b) {
int x, i;
x = a;
if (n == 1){
x = pow(a,b);
} else {
for(i = 1; i < b; i++){
x = myoperator (a, [n-1], x);
}
return x;
}
Note that the values will grow quickly and get out of the range of machine integers very soon.
Note also that a[n]b can be defined as
a [n] b = a [n-1] ( a [n-1] (b-1) ).
using this definition the for loop above can be eliminated.
int myoperator (a, n, b)
int a,n,b;
{
int x;
x = a;
if (n == 1)
x = pow(a,b);
else if (b == 1)
x = a;
else {
assert(b>1 && n>1);
x = myoperator (a, n-1, myoperator(a,n-1,b-1));
}
return x;
}