简体   繁体   中英

C - pointers in functions and void variable type?

Please explain what a prototype like this means

void *runner(void *param)
  1. How is a variable type void?
  2. What does the function name with *runner mean?
  3. Is it the address of the function?

First of all, there is absolutely no difference between void* runner and void *runner . The function's name is runner . Secondly, a function CAN be declared void which simply means that it doesn't return anything at all.

However this signature is different. It returns a void* , which simply means a pointer to an unspecified datatype. Or an easier way of thinking about it, it returns a memory address.

The same goes for the void *param , it's just accepting a memory address.

EDIT

This might make it a bit clearer:

void func(void *ptr);   // take in a generic memory address, return nothing
void *func(void *ptr);  // take in a generic memory address, return similar
void *func(void);       // Function takes no parameters (necessary in C, optional in C++)
void *func(void param); // Invalid! As you guessed, this would be pointless.
void *func();           // Preferred syntax in C++, function takes in nothing and returns a generic memory address
                        // In C this means it takes an undetermined number of arguments

void func();            // In C++: function takes in nothing, returns nothing
                        // In C: function takes in an undetermined number of arguments, returns nothing

Question 1: The variable type is void *, not void. This is a generic pointer guaranteed to be able to store a pointer to data. It might or might not be able to hold a pointer to a function, but that is another discussion.

Question 2: The function name is not *runner, it is runner. In C/C++ spaces usually do not mean much.

Question 3: No, it just means that the function returns another of those void * generic pointers. Those pointers are great for accepting any type of variable (eg before we had templates to do it for us).

Function name is not *runner , it is just runner . It's return type is void* . Again, argument type is not void . It is void* . Meaning a pointer that can point to anything.

void* is the type, not void . A void* is a pointer to "something." What it points to is not known, but the idea is for it to work as sort of a neutral pointer. It could be pointing to any particular thing, so the function being given the pointer have to have an implicit agreement as to what this thing actually points to.

For example, if you have a function void FuncName(Type *value) , the value is a pointer to a Type object. This is an explicit agreement between the caller and the function that it will be passed a Type object pointer. The compiler will prevent accidentally passing the wrong type of pointer. Using a void* means that there is no explicit agreement. There may be an implicit one, but the compiler will not prevent you from passing the "wrong" thing.

void *runner(void *param) is a function called runner which takes a single void* parameter and returns a single void * return value. Many programmers like putting the * next to a name, rather than next to the type.

C allows you to use void* as types of pointers to support writing generic functions. As a void* param can take any kind of pointer type. However great care needs to be taken while handling these pointers as they come with their own set of limitations. You cannot dereference a void* it has to be cast to a valid type. The same goes with applying pointer arithmetic.

In this case runner is a method name which take a param of the type void*, so basically it can be of any type, even a user defined ADT. However most of the functions that accepts void* do have some kind of callback which the caller registers. Then the caller is called back for data handling where the void* is passed back to the caller which then knows what was the original type of the void* so that it can then cast it to the right type.

A typical use of this is qsort method which can sort an array of any user defined type as long as the caller implement the comparator method that accepts two instances of the type(via void*) and then returns -1,0 or 1 depending on the comparison. Specifically say the qsort is being applied to ints then the comparator implementation looks like:

int compare(void * n1, void* n2)
{
   int *i = (int*) n1;
   int *j = (int*) n2;
   if (*i < *j){ (now dereference the int*) 
      return -1 
   }
   else if ( *i == *j) {
      return 0;
   } 
   else {
      return 1
   }
} 

first of all: void *runner(void *param) needs a ; at the end. with prototyping, you put a "reference" saying "ill do it later". This allows you to put it lower down in the code as to not make the top section cluttered.

Q1-Answer:
void is the return type of the function. in this case void, you wont be returning anything. if it was a void variable then you could hold anything in it but would need to typecast it to get its value.

Q2-Answer:
*runner and * runner = the same thing. void* is the return type again. void and void* are very different. Although they look the same they are VERY different. like an int* and an int one holds the address of an integer and the other holds an integer value.

Q3-Answer:
its not the address of the function (as you seem to be implying) its the return type. for instance if you have int* after your code you have you will type something like

int* function()
{
    int* a;
    *a = 5;
    //CODE HERE

    ...

    return a;
}

so it MUST return a pointer to an integer, it cant return an int because the compiler will throw an exception/error. its like trying to put a char into an int.

Check out all the documentation on www.cplusplus.com its really helpful.

HOPE THIS HELPED!

Peace.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM