For a class project I am writing, my teacher's style guide for functions says that "input parameters must appear before out parameters." I am not too sure what they mean by this?
If I have a function
void foo(int a, int b, int* c)
{
*c = a+b;
}
In the above case a and b are inputs while c is an output.
Generally you use "outputs" in this way if you are returning an array.
C doesn't actually have "input" and "output" parameters, at least not directly. (Some languages do.) All arguments are passed by value, meaning that the function gets the value of the argument, but any modifications to the parameter are invisible to the caller.
(Terminology: A *parameter" is a named object in the body of a function, defined between the parentheses; an argument is an expression in a function call. Each argument is evaluated and the resulting value is assigned to the corresponding parameter.)
However, you can simulate "output" parameters using pointers. For example:
void foo(int in, int *out);
The pointer is passed by value, but the function can assign a value via the pointer to *out, which will be visible to the caller. (out can also be used as an input parameter, which is common for large types where passing a pointer is more efficient, or as an input/output parameter.)
So "input parameters must appear before out parameters" probably means that non-pointer parameters should appear before pointer parameters used to return values indirectly.
This is usually for void functions.
void some_function (int input_1, int input_2, char* output)
{
/* Do things with input_1 and input_2. */
/* Modify "output". */
}
The code I just gave is very vague, and the input/output parameters in a void function can be applied in many ways.
Related
I just started learning C, and I came across this in one of the example given, I know this is a function prototype, but the concept I am yet to wrap my head around is the fact that does
void function(char *);
mean when I finally declare the function, it is going take an argument char pointer argument like so
void function(char *arg){}
?
Just to answer the question you gave:
What does “void fatal(char *);” mean?
This is the prototype/declaration of the function fatal.fatal is a function, which takes a pointer to char as one and only argument.
void is the return type of the function, which in this case mean that the function does not return a value to its caller or if it does, the value returned is interpreted as invalid by the caller.
The prototype/declaration of the function fatal() is important for the compiler. In this way, primarily the compiler will get "known", how the function is later used in the following program but secondary also checks if there are any inconsistencies between the definition, declaration and the use of the function.
In C, You may omit a specific identifier for the pointer to char in the declaration of the function, but not in the definition. This a circumstance where C is different as C++; In C++ it is permissible to omit the identifier also in the definition. You can look at the respective phrases in the standards in this answer.
So in the definition of fatal in C you have to provide an identifier for the char pointer:
// Definition of function fatal().
void fatal(char *a)
{
printf("The string of (a) is: %s\n",a);
}
but you can omit this one in the declaration:
void fatal(char *);
Note: The identifier between the provided arguments, when calling the function and the parameters specified in the declaration of the function may vary, like:
// Declaration (Protoype) of function fatal().
void fatal(char* a); // parameter a (pointer to char);
int main()
{
char b[] = "Hello"; // Declaration and Initialization of array b.
printf("Let´s use the function fatal to print what the string in b is
contained of!\n");
fatal(b); // when given as argument to a function, b
// is a pointer to the first element of the char
// array of b.
}
// Definition of function fatal().
void fatal(char* a)
{
printf("The string of (a) is: %s\n",a);
}
See more about the difference between parameters and arguments here: What's the difference between an argument and a parameter?
In the more far view, there is also an important difference between "pass by value" and "pass by reference". A pointer argument/parameter is always a pass by reference. What these two especially are and how they distinct is best explained here: What's the difference between passing by reference vs. passing by value?
In this context and the context of scope visibility, it is also important to know if you have f.e. an identifier x which refers to an object in the function fatal, the same identifier of x can be used in the caller, and vice versa, to refer to a total different object in each scope. - Means, you can have the same identifier (name) for different objects in different scopes but each identifier can only used once in its scope.
Here void function(char *); is a function prototype which is simply the declaration of a function that specifies function's name, parameters and return type. It doesn't contain function body.
It gives information to the compiler that the function may later be used in the program.
It is not needed if the user-defined function is defined before the main() function.
does
[...] mean when I finally declare the function, it is going take an argument char pointer argument [...]
?
Yes, it does.
The important thing with the declaration of the function are the parameters' types. The parameters' names are not needed within the declaration
void function(char *);
but only within the function's definition
void function(char *arg)
{
}
.
It just informs the compiler what type parameters functions takes and what is the return type of it.
int main()
{
double x = foo(1,2);
}
void foo(double x)
{
printf("%f", x);
}
in this compiler does not know what parameters of the function foo are and how to pass them properly. Return type is also unknown. The compiler will assume they are int - which is not the truth in this case
https://godbolt.org/z/J8juc4
I'm thinking about the difference between:
void *signal(int, void (*)(int))(int)
and
void (*signal(int, void (*)(int)))(int)
I know the latter is from here - Example #3: The ``Ultimate'' (it's a hilarious learning experience when I was trying speak out loud to understand it):
signal is a function takes (int, void (*)(int)) as input and returns a pointer to another function that takes (int) and returns void.
For the former I'm thinking that since the last (int) will have higher precedence than * so it should be a syntax error, but from cdecl.org the result is:
["] declare signal as function (int, pointer to function (int) returning void) returning function (int) returning pointer to void [."]
So I need a check.
One has to differentiate between grammar and semantics. cdecl.org only gives you the grammatical meaning of whatever declarator you type into it. In your first example, you have indeed a grammatically correct declaration of signal as a function returning a function. However, C does not allow functions to return other functions:
N1570 6.7.6.3 §1:
A function declarator shall not specify a return type that is a function type or an array type.
So while this declaration is grammatically correct, it is semantically invalid. In other words: While the C syntax makes it possible to write "function returning a function", you're not allowed to actually have a function that returns a function in a program. Just like the English language (or any language for that matter) also allows you to express all sorts of thoughts that would physically be impossible to carry out…
The most important part here is... you don't need to learn this, it is a very poorly designed part of the language. You can scroll down to the bottom of the answer to find the sane, professional solution.
Otherwise, if you insist, it goes like this...
When trying to return a function pointer from a function, the type of the function pointer gets split up. If you want to return a function pointer void(*)(void), then this poor function pointer gets split up in 3 parts. Lets call them like this:
void is A, the return type of the pointed-at function.
(*) is B, marking this a pointer to function, rather than a function.
(void) is C, the parameters of the pointed-at function.
Then if we want to stick this as a return type into some other icky function declaration, they end up like this:
#define A void
#define B *
#define C (void)
// A (B) C equals void(*)(void)
A (B madness(int, void (*fp)(int))) C;
where A, B and C are the parts of our poor function pointer to be returned, madness is the name of the function, and the rest is some mess used as parameters by the function itself.
If we omit the B part, it will be interpreted like a function returning another function of type void f (void); which isn't valid. The syntax allows it but not the language specification.
Similarly, int foo (void) [3]; - a function returning an array, is not allowed either.
Pondering these things is the road to madness and it makes the code unreadable. Professional programmers use typedef.
Given
void (*madness(int, void (*f)(int)))(int);
replace it with:
typedef void func_t (int);
func_t* sanity (int, func_t* f);
void fun1()
{
puts("In fun1\n");
}
void fun2(void)
{
puts("In fun2\n");
}
main()
{
fun1();
fun1(5);
fun2();
}`
It is working properly but i want to catch the parameters value that i've pass, but in this format only.
I am not sure if I can comprehend what you mean by "but in this format only."
If you meant you don't have the liberty to change void fun1() to void fun1(<some suitable data type>), then you can't achieve what you are trying to.
One of the most basic and common ways to pass arguments to fun1() is by changing
void fun1()
to
void fun1(int a) //int for example
I have used int as the data type of the argument, it can be any of the following:
int
unsigned int
char
unsigned char
short
unsigned short
long
unsigned long
and so on..
There are many ways to use arguments to a function. You can possibly pick any basic standard reference book for C programming and see the chapter that deals with functions.
For a beginner, reading and more importantly understanding the C standard can be very hard, but its always the way going ahead. I'll provide you with the link to refer the C11 standard, which is the latest one.
Referring to C11 standard, section 6.5.2.2 Function calls,
If the expression that denotes the called function has a type that includes a prototype, the number of arguments shall agree with the number of parameters. Each argument shall have a type such that its value may be assigned to an object with the unqualified version of the type of its corresponding parameter.
and
An argument may be an expression of any complete object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument
In short: You can't.
A little more detailed: A function prototype with just empty argument list means the function might be called with any number of arguments. You shouldn't use this to begin with, it's obsolete because it is unsafe practice, just declare a complete prototype with all arguments.
That said, pre-standard C had a mechanism to completely dynamically fetch arguments: varargs.h. DO NOT USE THIS, it is nowadays replaced by stdarg.h which requires at least one declared argument.
I am a beginner in C.
For now I have a function like this
void mark_function(void *obj, void (*mark_obj)(void *));
To my understand, this a void function, and it has two parameter, first one is a void pointer,
and the second one is a another void function with a void parameter.
I tried a lot ways to call it, but it seems not work properly,either give me back the segmentation false or the pointer type not the same warning.
So What exactly means for this function? what parameters should pass in? and how to call it?
Any help?
Thanks alot!
Let's make it more clear first. You have a void function, called mark_function, which takes 2 parameters. The first parameter is a void pointer and the second parameter is a pointer to a function that returns void and takes as a parameter a void pointer. Let's create a function that will be apropiate to pass as parameter to mark_function.
void param(void *p) {
// function body
}
Assume a and b are 2 void pointers. I will not enter into details about their scope, but you need to pay attention to it: they must be available in the scope they are used.
Then, the mark_function will be called as:
mark_function(a, param);
Inside mark_function body you can have something like:
param(b);
, which is a call to the function passed as a parameter.
Long story short: the function pointers used as parameters are meant to make it possible for the function that requires them to perform different activities by calling different functions. The value of a pointer function is simply the name of a function that has the appropiate signature (return value and parameter list). Your function can use this to call the function provided as parameter as needed.
You should call the function with one pointer to an object, and one pointer to a function of suitable type.
int my_int;
void mark_function(void *obj, void (*mark_obj)(void *));
void my_func (void *vp)
{
/* Convert vp to a pointer to a real type */
int *ip = vp;
/* Do something with ip or *ip */
}
mark_function (&my_int, my_func);
A pointer to object (&my_int) can safely be convert to a void * and back to the same type. The resulting pointer is guaranteed to be identical to the original pointer. This allows mark_function() to perform some task regardless of the actual type that the pointer points to.
Typical examples of such tasks include sorting of arrays with a custom compare function provided by the caller, or maintaining linked lists without knowing the types of the object stored inside, an so on.
Related to [question]: How do you pass a function as a parameter in C?
Is it possible in C to pass a function that has a variable number of arguments to another function? If so, could someone point me to some documentation or fill me in? Thanks.
You can't pass a function (of any sort) as a parameter, but you can pass a pointer to a function (again, of pretty much any sort). It's usually easiest to use a typedef:
typedef int (*fptr)(char const *, ...); // e.g., match with `printf`
int apply(fptr f, char const *a, int b) {
return f(a, b);
}
You can make a function pointer, e.g.:
typedef int (*vafunc)(const char *, ...); // like printf
However, you cannot really forward the arguments, i.e. the following doesn't exist in standard C:
void call_other(vafunc f, const char * fmt, ...)
{
// want to say:
// f(fmt, ...); // How to write this???
}
GCC offers such anonymous argument forwarding as an extension, but it's not possible in standard C. You're typically expected to match each variadic function with a v... counterpart that takes a va_list argument, precisely for this purpose. (Calling f with a fixed number of arguments is possible, of course: f("abc", 1, 2, 3);)
http://www.lemoda.net/c/function-pointer-ellipsis/index.html seems to be what you seek.
You can pass a varargs function the same way as you would another function.
Here's a short test program that demonstrates passing a varargs function as a parameter:
int bar(int x, ...) {
/* In a real program, you would actually use the arguments beyond x */
return x;
}
int foo(int (*baz)(int, ...)) {
return bar(10, "ABC");
}
int main(void) {
printf("%d\n", foo(bar));
return 0;
}
It prints 10, as you might expect.
N.B. You can't actually pass a function as an argument to another function in C - instead, you can pass a function pointer, which points to the actual function as loaded from the executable. This is weaker than the first-class status of functions in functional programming languages, or even than the status of a delegate in some object-oriented languages like C#. For instance, you can't create a function on the fly in C.
Sure. They're called "variadic functions".
1) Just use an "ellipses" ("...") as the last argument in your function prototype
2) In order for the called function to "know" how many arguments were passed to it, use the macros "va_start" and friends in "stdargs":
3) 1) and 2) above are simply to have a function that has a variable #/arguments. You can also have a function pointer with a variable #/arguments. Do the same thing - just include the ellipses ("...") in your function prototype, and use "stdargs" in your function implementation.