why do some function names in C start with * [duplicate] - c

This question already has answers here:
What is the function of an asterisk before a function name?
(4 answers)
Closed 8 days ago.
for example:
struct entry *addentry (Struct entry *listPtr, int value){ }
why does the name have a *
I tried to understand but couldnt

The * is not part of the function name. It signifies the return value of the function, which is in this case a pointer (because of the object-of * operator) to struct entry.
It can be written as any of the following:
1) struct entry *function(...)
2) struct entry* function (...)
3) struct entry * function (...)
Which one you use is up to you.

For starters there is a typo in the first parameter declaration. Instead of
Struct entry *listPtr
there must be
struct entry *listPtr
^^^^^^
The confusion is due to the placement of the symbol * in the declaration
struct entry *addentry (struct entry *listPtr, int value){ }
Actually the following function declarations are equivalent
struct entry *addentry (struct entry *listPtr, int value){ }
struct entry * addentry (struct entry *listPtr, int value){ }
struct entry* addentry (struct entry *listPtr, int value){ }
In all the function declarations the function name is addentry and the function return type is the pointer type struct entry *.
You could even declare the function like
struct entry * ( addentry (struct entry *listPtr, int value) ){ }
It seems the function adds a new value to a list and returns the possibly updated pointer listPtr within the function to the caller.

Related

Linked list: Initialize Head with function?

I am a C# programmer professionally, but trying to re-learn C. I have been writing a simple linked list in C. I have gotten it working fine when the head-node is defined in main(). But now I want to try and initialize the head-node in a function "initializeHead()".
Here is the Node definition and Main() function:
struct node
{
char value;
struct node * next;
};
int main()
{
struct node * head = NULL;
initializeHead(head, 'a');
return 0;
}
Function that initializes head node:
void initializeHead(struct node * head, char vertexCategory)
{
if (head == NULL)
{
head = malloc(sizeof(struct node));
head->value = vertexCategory;
head->next = NULL;
}
else
{
printf("\nError: Head already initialized!");
}
}
...After calling initializeHead(), it doesn't seem like anything has happened because head is still NULL.
How can this be accomplished?
The term method is not a normative term in C and C++. Use the term function instead (or member function in C++).
According to the C Standard the function main without parameters shall be declared like
int main( void )
In fact the head is already initialized in the declaration
struct node * head = NULL;
You can check for example whether a list is empty by using comparison
if ( head == NULL ) { /* ...*/ }
What you are trying to do using the function is to append a value to a list. So the function name initializeHead just confuses readers.
You can use instead either push, or push_front or some other suitable name.
The function shall be declared before its usage.
Arguments are passed to functions by values in C. The term passing by reference means in C to pass a pointer to the original object. Otherwise a function will deal with a copy of the original object.
You can imagine your function definition and its call the following way (for clarity I renamed the parameter name)
initializeHead(head, 'a');
//...
void initializeHead( /*struct node * list, char vertexCategory */ )
{
struct node *list = head;
char vertexCategory = 'a';
//...
That is function parameters are its local variables that are initialized by expressions used as arguments. So any changes of a parameter do not influence on the original argument. As it was mentioned above if you want to change an original object you have to pass it by reference that is indirectly through a pointer.
Also you should free all allocated memory by the list when the list is not used any more in the program to escape memory leaks.
The function should not issue a message . It is better if it returns a code of success or failure.
For example a function that pushes a value in a singly-linked list can look the following way
int push_front( struct node **head, char value )
{
struct node *new_node = malloc( sizeof( struct node ) );
int success = new_node != NULL;
if ( success )
{
new_node->value = value;
new_node->next = *head;
*head = new_node;
}
return success;
}
Pay attention to the first parameter declaration struct node **head. As the original head of the list has to be changed in the function then it is passed to the function by reference that is by using a pointer to it.
The function can be called like
push_front( &head, 'a' );

Declaration of a function returning a pointer

Here is my code:
#include <stdio.h>
struct entry
{
int value;
struct entry *next;
};
struct entry * findEntry (struct entry *listPtr, int match)
{
while (listPtr != (struct entry *) 0)
if (listPtr->value == match)
return (listPtr);
else
listPtr = listPtr->next;
return (struct entry *) 0;
}
int main(void)
{
struct entry * findEntry(struct entry * listPtr, int match);
struct entry n1, n2, n3;
struct entry * listPtr, *listStart = &n1;
int search;
n1.value = 100;
n1.next = &n2;
n2.value = 200;
n2.next = &n3;
n3.value = 100;
n3.next = 0;
printf("Enter value to locate: ");
scanf ("%i", &search);
listPtr = findEntry (listStart, search);
if (listPtr != (struct entry *) 0)
printf( "Found %i.\n", listPtr->value);
else
printf("Not found.\n");
return 0;
}
So for the line:
struct entry *findEntry (struct entry *listPtr, int match)
Why is there a * in front of find entry? Because it is supposed to be a function declaration but *findEntryis a pointer? I do not understand what the statement at all....
On the book the explanation is: specifies that the function findEntry() returns a pointer to an entry structure and that it takes such a pointer as its first argument and an integer as its second
In that case is the * sign needed?
Thank you
Imagine someone told you that 23+45 equals 275, and then explained it by the following logic: we have to calculate 3+4 separately and just keep 2 and 5 on both sides unchanged. This, of course, would make no sense. The proper meaning of 23+45 notation does not imply that one should rip the 3+4 piece out of it and treat it separately.
When you isolate the *findEntry from the rest of your declaration and conclude that it declares findEntry as a pointer, you actually make the same kind of mistake. There's no such entity as *findEntry in your declaration. Declaration grammar dictates that the (...) bit on the right binds to the name findEntry first. And only after that we get to considering the * to the left of the name.
This means that your declaration of findEntry begins with findEntry(...) binding, which indicates that findEntry is a function. Only after that we take into account the * bit, obtaining *findEntry(...), which tells us that findEntry is a function returning a pointer.
The syntax of C doesn't give a parameter name to the return value (because it can't be used in the code anyway). So the declaration:
struct entry * findEntry (struct entry *listPtr, int match)
Could be written:
struct entry *
findEntry (struct entry *listPtr, int match)
(and in fact is written that way in some coding standards).
And that declares a function called findEntry that returns a pointer to a struct entry (a struct entry *). Without the * the function would return a struct entry.
Why is there a * in front of find entry? Because it is supposed to be a function declaration but *findEntry is a pointer? I do not understand what the statement at all....
Yes, it indicates that findEntry is a function that returns a pointer value.
C declaration syntax is centered around the types of expressions. For example, suppose we have a pointer to an int, and we want to access the pointed-to int value. We use the unary * operator on the pointer, like so:
x = *p;
The expression *p has type int, so when we declare the pointer variable p, we do so as
int *p;
The declarator *p specifies the "pointer-ness" of p. Similarly, suppose we have a function that returns a pointer to int, and again, we want to access the pointed-to integer value. Again, we use the unary * operator on the value returned by the function:
x = *f();
The expression *f() has type int, so when we declare the function, we write
int *f(void); // void means f takes no arguments
In this case, both the "function-ness" and "pointer-ness" of f are given by the declarator *f(void).
Now, we could decide to assign the return value of f to p:
p = f();
Note that in this case we don't use the * operator on either expression, because this time we're interested in the pointer value, not the pointed-to integer value. But we still need to use the * in their declarations to indicate that they deal with pointer values.
In both expression and declaration syntax, the postfix () and [] operators bind before (have higher precedence than) the unary * operator. Thus:
T *f(); // declares f as a function returning a pointer to T
T (*f)(); // declares f as a pointer to a function returning T
T *a[N]; // declares a as an N-element array of pointer to T
T (*a)[N]; // declares a as a pointer to an N-element array of T
So when you find a somewhat complex declaration, start with the leftmost identifier an work your way out using the precedence rules above. Apply these rules recursively to any function parameters. So, given your declaration
struct entry * findEntry (struct entry *listPtr, int match);
we read it as
findEntry -- findEntry
findEntry ( ) -- is a function taking
findEntry ( listPtr ) -- parameter listPtr
findEntry ( *listPtr ) -- is a pointer to
findEntry (struct entry *listPtr ) -- struct entry
findEntry (struct entry *listPtr, match) -- parameter match
findEntry (struct entry *listPtr, int match) -- is an int
* findEntry (struct entry *listPtr, int match) -- returning a pointer to
struct entry * findEntry (struct entry *listPtr, int match); -- struct entry

How does the struct of a linked list know the type of next pointer of its own type?

struct node
{
int data;
node* pointerToNextNode;
};
Here pointerToNextNode is the type of struct node, and it is declared inside the struct.
How does the struct know the type of next pointer of its own type - when it itself hasn't been formed yet?
There is no keyword extern used. How does this work?
It doesn't need to know the structure, it's enough to know the type name, namely struct node — and that has already been defined.
Same result you can obtain by forward type declaration:
struct node; // declare the struct not defining it
struct node *pointer; // declare variable
void foo()
{
if(pointer != NULL) // OK, we use the pointer only
if(pointer->x == 0) // invalid use - struct contents unknown yet
return;
}
struct node { // supply a definition
int x;
};
void bar()
{
if(pointer != NULL)
if(pointer->x == 0) // OK - struct contents already known
return;
}
Here pointerToNextNode is the type of struct node
No, it's not. It's of type struct node *
struct node* pointerToNextNode; allocates memory for a pointer variable of type struct node.
It does not allocate memory for struct node, so, till point, it does not need to know about the size and representation of struct node. Only the (data)type name is sufficient.
Also, it's worthy to mention, without a typedef in place, node* pointerToNextNode; should not be valid. It should be written like below
typedef struct node node;
struct node
{
int data;
node* pointerToNextNode;
};
BTW, private: is not C thing, if i'm not wrong.
for me this doesn't compile using CC -- and exactly because of what you said.
you would have to use struct node * to make the compiler aware you want memory for a pointer

Casting from void* to struct

I am passing data of type struct Person to a linked list, so each node's data pointer points to a struct Person.
struct Person {
char name[16];
char text[24];
};
I am trying to traverse the list and print the name/text in each node by calling
traverse(&list, &print);
Prototype for traverse is:
void traverseList(struct List *list, void (*f)(void *));
List is defined as:
struct List {
struct Node *head;
};
My print function accepts a void * data :
print(void *data) { .... }
I know I have to cast the data to struct Person, correct?
struct Person *person = (struct Person *)data;
printf("%s", person->name);
I know this is not sufficient since I am getting an "initialization from incompatible pointer type" warning. How can I successfully cast a void* in this case? Thank you.
The problem's not with the cast, or even with the way you're passing the function around. The problem is that your declaration of print is missing a return type, in which case int is usually assumed. The compiler is complaining because you're passing an int (*)(void*) to a function that's expecting a void (*)(void*).
It's easy to fix: simply add void in front of your print function declaration. See:
https://gist.github.com/ods94065/5178095
My print function accepts a void * data
I would say, rewrite your print function by accepting struct Person * .
Your traverseList function accepts a function pointer (which takes a void pointer), but it doesn't accept an argument for that void data. It seems that this is what you're after:
void print (void* data)
{
printf("%s", ((struct Person*)data)->name);
}
void traverseList (struct List *list, void(*f)(void*), void* data)
{
f(data);
}
Then you can call traverseList:
traverseList (&list, &print, &person);

what does typedef struct node *NODE indicate?

struct node
{
int coef;
int exp;
struct node *link;
};
typedef struct node *NODE;
It defines NODE as a synonym for the type struct node *, so when you'll be declaring a variable of type NODE you'll be actually declaring a pointer to struct node.
Personally, I don't think that such declaration is a good idea: you're "hiding a pointer" (which is almost always a bad idea), and, moreover, you are not highlighting this fact in any way into the new name.
It makes NODE a typedef for a struct node *.
NODE becomes an alias for struct node*.
EDIT: Okay, for the comment (if I write my answer as comment, it would be too long and not formatted):
There's no different way to write this. Here, typedef is used just to create a synonym/alias for pointer to struct node.
An example for usage would be:
void f()
{
// some code
NODE p = NULL;
// do something with p
// for example use malloc and so on
// like: p = malloc( sizeof( struct node ) );
// and access like: p->coef = ..; p->expr = ..
// do something with p and free the memory later (if malloc is used)
}
is the same as
void f()
{
// some code
struct node* p = NULL;
// do something with p
}
Using NODE makes it just shorter (anyway, I wouldn't advise such typedef, as you're hiding, that it's a pointer, not a struct or other type, as mentioned in #Matteo Italia's answer).
The format, you're referring: "typedef struct{}type_name format" is something else. It's kind of a trick in C, to avoid writing struct keyword (as it's obligatory in C, and NOT in C++). So
typedef struct node
{
//..
} NODE;
would make NODE alias for struct node. So, the same example as above:
void f()
{
// some code
NODE p;
// do something with p
// note that now p is automatically allocated, it's real struct
// not a pointer. So you can access its members like:
// p.coef or p.expr, etc.
}
is the same as
void f()
{
// some code
struct node p;
// do something with p
}
NOTE that now, p is NOT a pointer, it's struct node.
simply tells you can create pointer of node type using only NODE every time instead of writting struct node * everytime
what does typedef struct node *NODE indicate?
UPPERCASE IS NO GOOD
Reserve ALL UPPERCASE identifiers for MACROS.

Resources