I work on my tutorial in C language.
I have a small pice of code that I need to deciph.
Here is the code:
int f(){return 1;}
int g(){return 2;}
int (*h(int (*pf1)(), int (*pf2)()))(){
return (int (*) ())((pf1() > pf2())*(int)pf1 + (pf2()>pf1())*(int)pf2);
}
void main(){
int res = h(f,g)();
}
I have problem to unndestand this syntex:
int (*h(int (*pf1)(), int (*pf2)()))()
I can't understand what is the meaning of this outter parentheses ->(*h(int (*pf1)(), int (*pf2)()))
and this parentheses() at the end of the function's signature.
Also what is '*h' inside parentheses? I understand that it get two functions and trigger it.
Can I get brif explanation on questions above?
Function pointers can be tricky to read. I start by reading the inner-most parenthesis, and work my way to the outer-most parenthesis.
Here's a breakdown of that declaration:
int (*h(int (*pf1)(), int (*pf2)()))()
(*pf1)() and (*pf2)() are pointers to functions that accept no parameters (i.e. ()), and both of them return an int.
*h(int (*pf1)() , int (*pf2)()) is a function that accepts two function pointers that returnint s. So, h returns a pointer to a function that accepts nothing and returns an int
Here is a link to some examples of the syntax, and a more elaborate breakdown:
https://www.cprogramming.com/tutorial/function-pointers.html
Added:
Since the original code that was provided segfaults, I wrote two different implementations that compare two integers and return the bigger one.
First, look at j. It's just a regular function that accepts two parameters that happen to be function pointers. Those function pointers are then used within the function. And because we said j returns an int, we return the actual integer by calling pf1() or pf2() with ().
Now look at h. In this scenario, h is going to return a pointer *. So we still call the function pointers pf1() and pf2() in h, but when we return, we DO NOT use () because we want to return the whole function pointer (either pf1 or pf2).
Lastly, look at main and see the difference between how j and h are used. Again, j is just a regular function. However, h uses the this syntax: h(f,g)() because h returns a pointer to a function which we then want to call using () to get the actual integer result for printing.
Hope this helps provide a little more clarity with a working example! Good luck!
#include <stdio.h>
int f(){return 1;}
int g(){return 2;}
int j(int (*pf1)(), int (*pf2)())
{
return ((pf1() > pf2() ? pf1() : pf2()));
}
int (* h( int(*pf1)() , int(*pf2)() ) ) ()
{
return (pf1() > pf2() ? pf1 : pf2);
}
int main()
{
int res1 = j(f,g);
int res2 = h(f,g)();
//print values returned by calling f and g.
printf("f: %d \ng: %d\n", f(),g());
//print result of calling j(f,g)
printf("res1: %d\n", res1);
//print result of calling h(f,g)()
printf("res2: %d\n", res2);
return 0;
}
main calls the function returned by h and returns that result. h compares the output of f and g and returns the function which returns the larger value (else it returns 0). Since the output of g is greater than f, h returns g. Hence main returns 2.
Related
So take the following code, I was reading some lecture notes on function pointers, and I came across this:
int (*Convert(const char code))(int, int) {
if (code == ‘+’) return ∑ // Takes two ints, and adds
if (code == ‘-’) return &Difference; // Takes two ints, and subtracts
}
int main () {
int (*ptr)(int,int);
ptr = Convert(‘+’);
printf( “%d\n”, ptr(2,4));
}
I'm usually used to seeing something like this when calling a function that returns a function pointer, and to me, this makes sense since I have all the parameters laid out here, the char, and the two int's:
Convert('-')(5, 6);
But in the way it was written in the notes, I can't really grasp what's exactly going on here. Can someone tell how exactly does this work? Does it have to do with assigning (*ptr)(int, int) the function's address or something?
Can someone tell how exactly does this work? Does it have to do with
assigning (*ptr)(int, int) the function's address or something?
Function Convert() returns a pointer to a function -- either a pointer to Sum() or a pointer to Difference(), depending on its argument (or it terminates without specifying a return value, which is bad news for you if you do anything at all with the return value). That function pointer is stored in variable ptr, which is declared to have the same type as Convert() returns. The pointed-to function can then be called by use of the function-call operator, ().
Perhaps it would be a bit clearer if rewritten in this equivalent way, with use of a typedef:
typedef int (*op_function)(int, int);
op_function Convert(const char code) {
if (code == ‘+’) return ∑ // Takes two ints, and adds
if (code == ‘-’) return &Difference; // Takes two ints, and subtracts
}
int main () {
op_function ptr;
ptr = Convert(‘+’);
printf( “%d\n”, ptr(2,4));
}
Either there is a typo or you mean the function name AddSub instead of Convert.
For example
int (*AddSub(const char code))(int, int) {
if (code == ‘+’) return ∑ // Takes two ints, and adds
if (code == ‘-’) return &Difference; // Takes two ints, and subtracts
}
[Note: Pay attention to that using the operator & is redundant due to the implicit conversion of a function designator to pointer to the function as for example
int (*AddSub(const char code))(int, int) {
if (code == ‘+’) return Sum; // Takes two ints, and adds
if (code == ‘-’) return Difference; // Takes two ints, and subtracts
}
-end note.]
So calling the function like
AddSub('-');
you will get an expression of the type pointer to function of the type int( int, int ). And you can again supply arguments to the returned pointer that to call the pointed function like
AddSub('-')(5, 6);
To make it more clear you can rewrite the expression above like
( AddSub('-') )(5, 6);
It is the same as this code snippet
int ( *ptr )( int, int ) = AddSub(‘+’);
printf( “%d\n”, ptr(2,4));
but without the intermediate variable ptr.
printf( “%d\n”, AddSub( '+' )(2,4) );
Pointers to functions keep reference to the function and can be called, but they behave exactly the same as other pointers. The syntax is confusung many people and this is one of the places where hiding pointers behind the typedefs makes sense but it is not necessary
#include <stdio.h>
#include <stdlib.h>
typedef int func(int, int);
int Difference(int a, int b){
return a - b;
}
int Sum(int a, int b){
return a + b;
}
func *Convert(const char code) {
if (code == '+') return Sum; // Takes two ints, and adds
if (code == '-') return Difference; // Takes two ints, and subtracts
}
int main () {
func *ptr;
ptr = Convert('+');
printf( "%d\n", ptr(2,4));
}
In the Wikipedia article https://en.wikipedia.org/wiki/Pure_function#Impure_functions it says that the following function is not pure.
int f(int* x)
{
return *x;
}
Why is that? The function would return the same value for the same argument right? Would it be considered pure if it was a non-mutable reference, as in the following?
int f2(const int* x)
{
return *x;
}
f isn't pure because its return value isn't necessary the same for the same arguments. You could call f twice with the same inputs and get different outputs. The following program demonstrates this:
#include <stdio.h>
int main() {
int i = 3;
int * const x = &i;
printf("%d\n", f(x));
i = 4;
printf("%d\n", f(x));
return 0;
}
Because x doesn't change between the two calls, the second call to f(x) could be optimized away (in favour of reusing the result from the first call) if f was pure. Obviously, that could produce the wrong result, so f isn't pure.
f2 isn't pure for the same reason.
Rule 1 says:
Its return value is the same for the same arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams from I/O devices).
The point is that the argument is not the value pointed by x but rather the address of the pointer. You're passing an address to the function.
Since you can change the pointed data and pass the same address then you have different return values.
Of course this wouldn't be true if f or f2 returned int* instead that int. In that case the same argument would lead to the same return value.
How would I pass a variable from one function to another in C? For example I want to pass the sumOfDice from function roll and use sumOfDice for the passLine function: Here is my code:
int roll()
{
int dieRollOne = (random()%6) + 1;
int dieRollTwo = (random()%6) + 1;
printf("On Dice One, you rolled a: %d\n", dieRollOne);
printf("On Dice Two, you rolled a: %d\n", dieRollTwo);
int sumOfDice = dieRollOne + dieRollTwo;
printf("The sum of you Dice is: %d\n", sumOfDice);
return sumOfDice
}
int passLine(int sumOfDice)
{
// other code
printf("the sum of dice is: %d\n", sumOfDice);
}
I would have used global variable for sumOfDice, but we are not allowed to. Would I have to pass with asterisk, like: int *num;
Nasim, this is one of the most fundamental concepts in C. It should be well-explained in any C book/tutorial you use. That said, everybody needs to learn somewhere. In order to pass values to/from a function, you start with the declaration of a function.
A function in C may receive any number of parameters but may only return a single value (or no value at all). A function requires those parameters specified in its parameter list. A function declaration takes the form of:
type name (parameter list);
The type is the return type for the function (or void). The parameter list contains the type of variables that are passed to the function. While you will normally see a parameter list in a declaration that contains both the type and name, only the type is required in the declaration. A function definition provides the function code and the function return. The parameter list for a function definition will contain both the type and name of the parameters passed.
(note: you may see old K&R function definitions without any type relying on the fact that the default type is int. That type definition/parameter list is obsolete. see Function declaration: K&R vs ANSI)
Now that you have had a Cliff's-notes version of how to declare/define a function, a short example should illustrate passing/returning values to and from a function. This first example shows the function definitions that precede the main function. In this case no separate declaration is required:
#include <stdio.h>
int bar (int x) {
return x + 5;
}
int foo (int a) {
return bar(a);
}
int main (void) {
int n = 5;
printf ("\n n = %d, foo(%d) = %d\n\n", n, n, foo(n));
return 0;
}
(note: function bar is placed before function foo because function foo relies on bar. A function must always have at minimum a declaration before it is called.)
Another example showing the common use of providing function declarations before main with the function definitions below would be:
#include <stdio.h>
int foo (int);
int bar (int);
int main (void) {
int n = 5;
printf ("\n n = %d, foo(%d) = %d\n\n", n, n, foo(n));
return 0;
}
int foo (int a) {
return bar(a);
}
int bar (int x) {
return x + 5;
}
(note: even though the function foo is defined before bar here, there is no problem. Why? Because bar is declared (at the top) before foo is called. also note: the declaration are shown with the type only, just to emphasize a point, you will normally see int foo (int a); and int bar (int x); as the declarations.)
Use/Output
The output of both is:
$ ./bin/func_pass_param
n = 5, foo(5) = 10
I hope this has cleared up some of the basics for you. If not, you can ask further, but you are far better served finding a good C book or tutorial and learning the language (at least the basics) before you attempt to compile and run a program -- it will take you far less time in the long run.
I know the title for this is horrendous and for this I am sorry; I honestly had no idea how to ask my question as I am not well educated on this matter. Below there is a small bit of code that my question concerns as I have NO idea what is going on or if it is even valid! Although, I suspect it is valid.
return(*scriptFunction[x])(arguments);
From my understanding, you can only return 1 value in C (you can have multiple return statements but that is different and off topic). What is the above statement actually doing?
The code:
return(*scriptFunction[x])(arguments);
actually is only returning one value.
The variable scriptFunction will be an array of function pointers(1). You look up element number x of that array, and call that function, passing the argument arguments. Then the return value from that function is what you return to your caller.
Other than the function pointer aspect, it's no different to return sqrt(42).
By way of example, the following program demonstrates how this can be done:
#include <stdio.h>
// Two simple functions which add a fixed value.
int fnPlus3 (int n) { return n + 3; }
int fnPlus7 (int n) { return n + 7; }
// An array holding those two functions.
int (*scriptFunction[])(int) = { fnPlus3, fnPlus7 };
int main (void) {
// Call first function in array.
int x = 0;
printf ("%d\n", (*scriptFunction[x])(100));
// Then call second one.
x = 1;
printf ("%d\n", (*scriptFunction[x])(100));
return 0;
}
Although it prints the return value from the function rather than returning it again, it still uses the same expression and you can see it calls a different function based on the value of x:
103
107
(1) Or some form of equivalent, such as a pointer to an array of function pointers, or a pointer to a single function pointer (assuming x is always set to zero in that latter case).
Presumably scriptFunction is an array of pointers to functions. *scriptfunction[x] is then the dereferenced pointer to function (the x-th one). Finally, *scriptfunction[x](arguments) represents the invocation of that function applied to arguments, so the result of that function is what's returned in the end.
Side comment: the * is not really necessary. A pointer to function does not need to be dereferenced to call the function, i.e. you can use
return scriptFunction[x](arguments);
instead.
From the looks of it, it seems the line return (*scriptFunction[x])(arguments); scriptFunction is an array of function pointers, and this is simply invoking the function at position indexed by variable x and sending arguments variable contents as its input.
The return value of this invoked function is what ultimately gets returned.
This working example should be useful:
#include <iostream>
using namespace std;
void func_a(int i)
{
cout << "func_a: " << i << endl;
}
void func_b(int i)
{
cout << "func_b: " << i << endl;
}
int main()
{
void (*funcs[])(int) = { func_a, func_b };
for(int i = 0; i < 2; ++i)
(*funcs[i])(i+1);
return 0;
}
The output is below:
➜ /tmp g++ test.cpp -o test
➜ /tmp ./test
func_a: 1
func_b: 2
Also, for future reference, you should consult: How to ask good questions?
int func(void) [5];
Why is above line not valid in c ? As anyone knows, function can be used as variable. But, I don't understand why compiler gives error .
Why I used that line is because I have tried to create 5 function-variable. To do so, I wrote like that, shown above.
Because it doesn't meet the C language valid syntax?
May be you should specify what are you trying to do with that sentence in order to get the answer you might be looking for.
This is not legal C syntax, period.
It is invalid in C++ too because functions cannot be put in arrays (you are trying to declare an array of five functions). However, the following works both in C and C++:
int (*func[5])(); // C++ version
int (*func[5])(void); // C version
and declares an array of five function pointers.
If you instead want a function which returns an array, in C you do
int *func(void);
and in C++ you do
int* func();
or
int (&func())[5];
which returns a reference to an array of five integers.
From the C standard (n1256):
6.7.5.3 Function declarators (including prototypes)
Constraints
1 A function declarator shall not specify a return type that is a function type or an array
type.
Functions cannot return array types or other function types. Functions can return pointers to those types, though:
int (*func(void))[5];
The syntax is a little weird looking, but it breaks down as follows:
func -- func
func(void) -- is a function taking no parameters
*func(void) -- returning a pointer
(*func(void))[5] -- to a 5-element array
int (*func(void))[5] -- of int
This isn't as useful as it looks: if you try to return a pointer to a local array, such as
int (*func(void))[5]
{
int arr[5] = {0,1,2,3,4};
return &arr;
}
the array no longer exists when the function returns; the pointer value you get back won't point to anything meaningful anymore.
If you're trying to create an array of functions, you have a similar problem; you cannot have an array of function types (6.7.5.2, paragraph 1, which includes the sentence "The element type shall not be an incomplete or function type"), although you can have an array of pointers to functions:
int (*func[5])(void);
This breaks down as
func -- func
func[5] -- is a 5-element array
*func[5] -- of pointers
(*func[5])(void) -- to functions taking no parameters
int (*func[5])(void) -- and returning int
Example:
int f0(void) { return 0; }
int f1(void) { return 1; }
int f2(void) { return 2; }
int f3(void) { return 3; }
int f4(void) { return 4; }
int main(void)
{
int (*func[5])(void) = {f0, f1, f2, f3, f4};
int i;
for (i = 0; i < 5; i++)
printf("f%d = %d\n", i, (*func[i])()); // or just func[i]()
return 0;
}
It is trying to declare a function that returns an array. This is not allowed - and it's nothing to do with syntax, it's a semantic rule, as demonstrated by the following (which has exactly the same problem, but is obviously syntactically fine):
typedef int FiveInts[5];
FiveInts func(void);
This is part of the "arrays are special" type rules in C. Function return values are not lvalues, and the only context in which a non-lvalue array could be used is as the subject of the sizeof operator. This makes functions returning array types completely useless.
try :
int *func(void);