Call an expression multiple times in an expression - c

I'm a student and new to C. One of the questions for my homework reads as follows:
max is a function that accepts two int parameters and returns the
value of the larger one. Four int variables, population1 ,
population2 , population3 , and population4 have already been
declared and initialized. Write an expression (not a statement!)
whose value is the largest of population1 , population2 ,
population3 , and population4 by calling max . (HINT: you will need
to call max three times and you will need to pass the return values
of two of those calls as arguments to max . REMEMBER: write an
expression, not a statement.)
I understand the logic of it:
Call the function max with the first two variables, the function will return the larger of the two and then take that value (somehow pass it without assigning to a fifth declared variable) and compare it to the third variable's value. Take the larger of the second pairing (again passing it without the benefit of a new variable - remember it's an expression, not a statement) and compare it to the forth value. However I haven't been able to write the correct syntax.
Also, understand that this is a 100 level class. So anything higher level will not be accepted for this particular question. No libraries to be #include(d).

Well you seem to understand how to do it, and yes the question seems to ask you to not assign returned values to new varibles. You can basically chuck in a max() as a parameter to another max(), and the return of the inner max() will be the int for the outer max() parameter.
Since c is strict, it won't compile unless the return type for the function is the same as the parameter (in this case, both are int, so it's fine)
max(2, max(3, 4)); // inner returns 4, which puts 4 into the outer max, and compares 2 to 4

Function calls can be nested. Here's a hint:
max(population1, max(...))
Can you come up with the correct code for the ...?

A function which returns something different that nothing (void) can be used inside an expression freely. An expression is defined recursively since it is made by sub-expressions until you reach terminal symbols (as constants or function calls).
So there is nothing strange in understanding the syntax, a call to max is synctatically equivalent to a numeric constant.
int x = 5;
int y = max(5,10);
int z = 5 + 10;
int k = max(5,10) + 3;
int j = max(3 + 2, 8);
These are all legal. Of course the assignment is just for clarity, as as assignment is a statement, not just an expression anymore.

Related

Recursive function for finding factorial of a number

I am getting an output of 24 which is the factorial for 4, but I should be getting the output for 5 factorial which is 120
#include <stdio.h>
int factorial(int number){
if(number==1){
return number;
}
return number*factorial(--number);
}
int main(){
int a=factorial(5);
printf("%d",a);
}
Your program suffers from undefined behavior.
In the first call to factorial(5), where you have
return number * factorial(--number);
you imagine that this is going to compute
5 * factorial(4);
But that's not guaranteed!
What if the compiler looks at it in a different order?
What it if works on the right-hand side first?
What if it first does the equivalent of:
temporary_result = factorial(--number);
and then does the multiplication:
return number * temporary_result;
If the compiler does it in that order, then temporary_result will be factorial(4), and it'll return 4 times that, which won't be 5!. Basically, if the compiler does it in that order -- and it might! -- then number gets decremented "too soon".
You might not have imagined that the compiler could do things this way.
You might have imagined that the expression would always be "parsed left to right".
But those imaginations are not correct.
(See also this answer for more discussion on order of evaluation.)
I said that the expression causes "undefined behavior", and this expression is a classic example. What makes this expression undefined is that there's a little too much going on inside it.
The problem with the expression
return number * factorial(--number);
is that the variable number is having its value used within it, and that same variable number is also being modified within it. And this pattern is, basically, poison.
Let's label the two spots where number appears, so that we can talk about them very clearly:
return number * factorial(--number);
/* A */ /* B */
At spot A we take the value of the variable number.
At spot B we modify the value of the variable number.
But the question is, at spot A, do we get the "old" or the "new" value of number?
Do we get it before or after spot B has modified it?
And the answer, as I already said, is: we don't know. There is no rule in C to tell us.
Again, you might have thought there was a rule about left-to-right evaluation, but there isn't. Because there's no rule that says how an expression like this should be parsed, a compiler can do anything it wants. It can parse it the "right" way, or the "wrong" way, or it can do something even more bizarre and unexpected. (And, really, there's no "right" or "wrong" way to parse an undefined expression like this in the first place.)
The solution to this problem is: Don't do that!
Don't write expressions where one variable (like number) is both used and modified.
In this case, as you've already discovered, there's a simple fix:
return number * factorial(number - 1);
Now, we're not actually trying to modify the value of the variable number (as the expression --number did), we're just subtracting 1 from it before passing the smaller value off to the recursive call.
So now, we're not breaking the rule, we're not using and modifying number in the same expression.
We're just using its value twice, and that's fine.
For more (much more!) on the subject of undefined behavior in expressions like these, see Why are these constructs using pre and post-increment undefined behavior?
How to find the factorial of a number;
function factorial(n) {
if(n == 0 || n == 1 ) {
return 1;
}else {
return n * factorial(n-1);
}
//return newnum;
}
console.log(factorial(3))

How does this code that prints 1 to 1000 work in C?

I've seen a C program that prints 1 to 1000 without using any looping structure or conditional statements, but I don't understand how it works. Can anyone go through the code and explain each line?
See live demo here. Why does it result in a runtime error?
#include <stdio.h>
#include <stdlib.h>
int main(int i)
{
printf("%d\n",i);
((void(*[])()){main, exit})[i / 1000](i + 1);
return 0;
}
((void(*[])()){main, exit})[i / 1000](i + 1);
This line create a two-element array of function pointers, with the first element containing the main function, and other element containing the exit function.
It then indexes this array by i / 1000. This either gets the main function if i < 1000 or the exit function when i == 1000.
It then calls the function pointer that it just indexed with i+1 as the argument.
It's a recursive function, with the stopping condition determined with an array index rather than a conditional. I don't think it's valid C however; main's signature is wrong, and the cast to a function pointer removes the return type from the main function.
Breaking down the line that you asked about
((void(*[])()){main, exit})
This is an array literal, which creates an unnamed temp array of two function pointers, and initializes those pointers to point at main and exit
[i / 1000]
This indexes that temp array. Integer division truncates towards 0, so when 0 <= i < 1000, this gets element 0 (the pointer to main) and when 1000 <= i < 1999, it gets element 1 (the pointer to exit)
(i + 1);
This calls the pointed at function with i+1 as an argument.
There are a bunch of things here that are undefined behavior. Declaring main as having a single int argument is illegal according to the standard, though generally will work, getting the number of command line arguments as the single argument. Getting a pointer to main is likewise undefined, as main is a special function that may have a non-standard calling convention.
This code is a good example of how far you can bend C without breaking it. You shouldn't attempt to understand this until you can write understandable C.
Here are the key features and assumptions:
First, assume that the program is called without arguments. The parameter i is in the place usually called argc, so it will have the initial value 1 (the number of elements in the array of arguments, usually called argv).
Next, assume that the single-argument form of main doesn't cause any problems. Officially supported forms of main are with no arguments, 2 arguments (argc, argv), and sometimes 3 arguments (argc, argv, envp).
So the first printf prints 1.
Next we have a compound literal. It might be easier to understand if you look at a simpler one first:
(int[]){10,20}
That's an anonymous array of 2 ints, with values 10 and 20. int[] is the type. It goes in parentheses before a braced list of values. So what's this:
(void(*[])()){main, exit}
void(*[])() is a type. It means array of function pointers with the signature void (*foo)(). The type name in parentheses followed by a braced list is compound literal, just like the (int[]){10,20} example. In this case, it creates an array of 2 function pointers whose elements are main and exit.
Assume that the mismatch between the function pointer type (returns void) and main (returns int) doesn't cause a problem.
This:
((void(*[])()){main, exit})[i / 1000]
is our anonymous array of 2 elements, inside some redundant parentheses, followed by [i / 1000]. That's just normal array indexing syntax. If i/1000 is 0, you get the first element of the array (thearray[0]), which is main. That happens for all i is between 0 and 999. If i/1000 is 1, which happens when i==1000, we're looking at thearray[1], which gets us the second element: exit.
So far, we have an expression taht is equal to main when i<1000 and equal to exit when i==1000.
Now look at the whole statement:
...that_big_thing_that_is_either_main_or_exit...(i + 1)
A function pointer, followed by a parenthesized argument list. That's a function call. Whichever function we chose from the array, now we're going to call it, providing an argument that is equal to the incoming argument (i) plus 1.
So the first call, when i is 1, selects main for the function and i+1 = 1+1 = 2 for the argument. It calls main(2).
main(2) does a printf which prints the 2, and then calls main(3).
main(3) does a printf which prints the 3, and then calls main(4).
...and so on until...
main(999) does a printf which prints the 999, and then calls main(1000).
main(1000) does a printf which prints the 1000, and then calls exit(1001).
None of the calls to main ever return, and the return 0 never happens, because the exit terminates the process. The fact that the process returns an exit code of 1001 rather than 0 appears to be the reason for ideone's "runtime error" message.
The main function is called recursively.
void print_nb(int n)
{
if (n <= 1000)
{
printf("%d\n", n);
print_nb(n + 1);
}
}
Like Sourav Ghosh said, it's prohibited to use with main() recursively, better use another function.

C - Code::Blocks 13.12: Which one will work fine, or both? Is there a difference between both? Or it is allowed in C standard?

Example 1:
while(npw(x,i)/ftr(i)>0.00001) {
t+=npw(x,i)/ftr(i);
i++; //normal increase i
}
or
while(npw(x,i)/ftr(i)>0.00001)
t+=npw(x,i++)/ftr(i++); //increase i inside function's parameters
Example 2: (x is a 'float')
int n=(int)x; //normal cast
printf("x! = %.0lf\n",ftr(n));
or
printf("x! = %.0lf\n",ftr((int)x)); //directly cast inside function parameters
t+=npw(x,i++)/ftr(i++);
May not do whatever you expect it to do, since the order of execution of the two increment operations in unspecified. I.e. you don't know which function will get the incremented i, and which function will get the incremented incremented i as an argument.
Also, whichever i is incremented first, it will be completely different from the previous piece of code, where i is incremented only once.
The other examples look correct. The last two pieces of code are different only semantically.

Passing number between functions in C

I'm very new to C, and am writing a few programs to try and understand how variables can be passed and changed in between functions. I wrote a simple program below:
int number;
int test( int number ) {
number = 3;
return(number);
}
int main () {
printf ("\nPlease enter in any number between (10 - 99,999)!\n");
scanf("%d", &number);
test(number);
printf ("\nYour number probably wasn't: %d\n", number);
}
The point was to enter in a number, but no matter what you enter that number would be changed to 3. For some reason though when i call test on that number, it will not change to 3 but instead be whatever the user entered. Note that I am trying to change the variable number, and not have any other variable hardcoded as 3.
How come this does not work?
Change
test(number);
to
number = test(number);
Otherwise the value returned by test will be discarded and you will get the number you entered, not 3.
Another way to get the desired effect is to pass the pointer to number:
void test( int *number ){..}
and call the function as
test(&number);
Some answers suggested that to use number as global variable. I advice you that do not use global variable when it is unnecessary.
You are changing a local variable in the function test, not the actual variable. You want number = test(number); as the second to last line in your main() function.
Your function test doesn't deal with the original number that you passed to it. Instead, it gets a copy of this variable and plays around with it locally. Any changes you make to number in this function will get lost (unless you pass in a reference, which you will learn about later, presumably). The correct way to get around this is, as you have already done, return the value of number. However, you don't use that returned value at all. When you say number = test(number);, you are telling the computer to take that returned value and assign it to the original number (the one in your main), which is what you want.
int number; //a
int test( int number ) { //b
number = 3;
return(number);
}
Within test, there are actually two variables named number,
a (which is the number used in main too), and b which has priority.
You´re changing the parameter b to 3.
However, the parameter is only a copy of the original passed value in main
(as usual in C and C++), and gets discarded and the end of test.
Furthermore, you´re not using the return value in main, so 3 is gone.
Perhaps you misunderstand the idea of 'variable scope'.
int number;
The first occurrence of the variable 'number' is declared outside of all functions (and braces). Hence, it has "global" scope.
int test( int number ) {
The variable 'number' defined as an argument to test() has a limited scope. Its life, and visibility, is limited to the braces of the test() function. Outside these braces, this 'number' variable does not exist.
The 'global' variable 'number' and the 'test()' variable 'number' are distinct from each other, each with its own unique value.
Being they are named the same, the 'global' variable 'number' becomes inaccessible inside the 'test()' braces. Hence, any manipulation of the 'number' within the braces of 'test()' does not have any effect on the 'global' variable 'number'.
number = 3;
The above has no effect on the 'global' variable 'number'. Rather it only initializes the 'local' variable 'number' to 3.
return(number);
The above will return the value of the 'local' variable 'number' (3).
}
int main () {
printf ("\nPlease enter in any number between (10 - 99,999)!\n");
scanf("%d", &number);
The line above sets the 'global' variable 'number' to a value entered by the user.
test(number);
The line above passes the value of the 'global' variable 'number' to test. It does not capture the 'return' value (3) returned by test. If desired, the above line could be rewritten:
number=test(number);
The above line would set the 'global' variable 'number' to the return value of test (3).
printf ("\nYour number probably wasn't: %d\n", number);
}
All answers so far seem to ignore the fact that you are trying something which does not make much sense. You are returning what is basically a constant from your function, but using a passed value as some intermediate storage while that is completely unnecessary. Either of those two will work:
void test( int& number ) {//We don't need to return anything, because we pass number by reference, and so changes made to it will persist outside this functions scope
number = 3;
}
int test(){
return 3; //We just return 3, we don't need any arguments passed to the functions in this version
}
Now in the first case you call the functions as
test(number); //number will be changed by test because it's passed by reference
in the second case you call the functions as
number = test(); //Here test just returns 3 and we assign that value to number.
Edit:
Just for completeness sake I will add the third version that you can use:
void test(int* number){//Here we pass a pointer to an integer to test
*number = 3;//and change the value pointed to be number to 3. Read * as 'value pointed at by'. So this says 'value pointed at by number = 3'
}
in this case you call the function as
test(&number)//read & as 'pointer to'. So now we pass 'pointer to a' to test.
Note that this version is basically a less elegant and more error prone version of the first version I mentioned (at least in this specific scenario). Their usage and effects are more or less equal, but in the first version you do not need to concern yourself with dereferencing and the general fact that you are working with pointers.
Your code never does anything with the value test returns. Your code would be easier to understand if you didn't call both variables (the one in main and the one in test) number.
You have 2 options. One is
number = test(number);
Second is refer Pointers in C. Pass by address would do the trick for you.
It doesn't work because you're doing a pass by value instead of a pass by reference. If you want the value of number to be always 3 without doing an assign when you call the function, then you should do something like:
void test(int *number){
*number = 3;
}
and call like:
test(&number);

How a discarded value can be used later in the program

About the expression statement(an example)
i = 1;
it is said that after assigning 1 to i the value of entire expression is being discarded. If the value is discarded then how this can be used later in the program,for example
printf("%d",i);
?
I know this is very basic question but I am really confused with discarded.
The value of the expression is indeed discarded, but this expression has a side effect - it changes the value of i. So next time you will access this variable, you will read the new value, which is 1.
The term "discarded" is more helpful when you do things like foo(5); or even simply "hello";. Since the expression "hello" does not have any side effect, and its value is dicarded, it is does absolutely nothing. When a compiler encounters it, as a stand alone statement:
"hello";
It may simply ignore it altogether, as if it does not exist at all. This is what happens when you call functions, or use operators:
4+5;
sin(2.6);
These expressions, too, have no side effect, and their values are ignored. When you do something like
printf("hello");
This is an expression, too. Its value is the total number of characters written. This value is ignored. But the expression must not be comletely ignored, since it has an important side effect: it prints these characters to the standard output.
So let's build a function instead of using the assignment operator (since C has no references, we'll use pointers):
int assign_int(int* var, int value) {
*var = value;
return *var;
}
now, back to your example, you do something like:
assign_int(&i, 1);
the value returned from assign_int is discarded. Just like in the printf() case. But since the function assign_int has a side effect (changing the value of i), it is not ignored by the compiler.
The important point is the i = 1 has two properties.
It changes the value stored in the variable i to be 1
It is an expression and has a value (which is also 1);
That second part is interesting is a case like
if ( (i=1) == 2 ) { // ...
or
y = 3 + (i = 1); // assign 4 to y
The line
the value of entire expression is being discarded.
refers to the value of the expression (my #2), but does not affect assignment to variable i (my #1).

Resources