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
Related
Looking at code on examples on StackOverflow I've noticed two distinct prototypes for object deallocation:
struct foo *foo_create(int);
void foo_free_v1(struct foo *);
void foo_free_v2(struct foo **);
void bar() {
struct *foo = foo_create(7);
// ...
// Version 1
foo_free_v1(foo);
// Version 2
foo_free_v2(&foo);
}
The standard library function free uses the first form.
Is the second form idiomatic in C? If yes, for what purpose?
The ones that take a pointer-to-pointer do so because they have the added convenience of automatically nulling out your variable for you.
They might look like:
void foo_free_v1(struct foo *f) {
if (f == NULL) return; // This has been freed before, don't do it again!
free(f->a);
free(f->b);
free(f->c);
free(f);
}
void foo_free_v2(struct foo **f) {
if (*f == NULL) return; // This has been freed before, don't do it again!
free((*f)->a);
free((*f)->b);
free((*f)->c);
free(*f);
*f = NULL; // Null out the variable so it can't be freed again.
}
This attempts to protect against double-free bugs. How good of an idea that, is debatable. See the comment thread below.
In the first function
void foo_free_v1(struct foo *);
the original pointer used as an argument expression is passed to the function by value. It means that the function deals with a copy of the value of the pointer passed to the function.
Changing the copy does not influence on the original pointer used as an argument expression.
Consider for example the function definition
void foo_free_v1(struct foo *p)
{
free( p );
p = NULL;
}
This statement within the function
p = NULL;
does not change the original pointer to NULL. It sets to NULL the function local variable p. As a result the pointer used as an argument expression after calling the function will have an invalid value. That is a value that does not point to an existing object.
In the second function declared like that
void foo_free_v2(struct foo **);
the original pointer used as an argument expression is accepted by reference through a pointer to it. So dereferencing the pointer you have a direct access to the original pointer used as an argument expression.
Consider a possible function definition
void foo_free_v2(struct foo **p)
{
free( *p );
*p = NULL;
}
In this case in the statement
*p = NULL;
it is the original pointer that is set to NULL. As a result the original pointer does not have an invalid value.
Consider for example a sungly-linked list like
struct SinglyLinkedList
{
int data;
SinglyLinkedList *next;
};
In main you can declare the list like
struct SinglyLinkedList *head = NULL;
Then you can add new nodes to the list. As the pointer head is initialized then the function that adds new nodes will work correctly.
After that you can destroy the list.
If you will call the first function declared like
void foo_free_v1(struct SinglyLinkedList *head );
then after calling the function the pointer head declared in main will have an invalid value. That is there will be an inconsistency. The list does not have already elements but its pointer to the head ode is not equal to NULL.
Is you call the function declared lik
void foo_free_v1(struct SinglyLinkedList **head );
then indeed the pointer to the head node in main will be equal to NULL that indeed means that the list is empty. And if you have a function that checks whether a list is empty you can pass the pointer to the function without producing undefined behavior.
What is the typical prototype for a deallocation function in C?
Pass the pointer. Nothing is returned or rarely used if non-void.
void foo_free_v1(foo_type *);
Is the second form (foo_free_v2(&foo);) idiomatic in C?
No.
Classic foo_free(foo_type *) samples:
foo *f = malloc(sizeof *f);
...
free(f);
FILE *istream = fopen(...);
int count = fscanf(istream, ...);
long offset = ftell(istream, ...);
fclose(istream);
When to use foo_free_v2(&foo);?
Use foo_free_v2(&foo) when foo is not a pointer type.
Example:
typedef struct {
int object1;
int *object2;
int *object3;
...
} foo_type;
foo_type foo = { 0 };
foo_get_resources(&foo, ...);
foo_do_this(&foo, ...);
foo_do_that(&foo, ...);
foo_free(&foo);
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.
I'm a C beginner, and I came across this code while trying to implement a linked list.
struct Node *ptr = malloc(sizeof(*ptr));
The Node struct looks like this:
struct Node {
int data;
struct Node *next;
};
I'm trying to understand the first line. It seems as if malloc(sizeof(*ptr)) already knows the contents of ptr. What exactly is happening on the left side and is it happening before malloc is called?
It seems as if malloc(sizeof(*ptr)) already knows the contents of ptr.
Actually, it doesn't. The sizeof operator doesn't actually evaluate its operand (unless it's a variable length array), it just looks at its type. This means that ptr isn't actually dereferenced and is therefore a safe operation.
Only use paranthesis with sizeof if there's a type you'd like to know the size of. If you have an expression, like *ptr, it's enough to write:
struct Node *ptr = malloc(sizeof *ptr); // <- no parenthesis
The expression *ptr dereferences the pointer so it becomes a struct Node and that's what the sizeof is returning the size for.
sizeofexpression - Returns the size, in bytes, of the object representation of the type of expression. No implicit conversions are applied to expression.
It's the same size you get if you do:
struct Node *ptr = malloc(sizeof(struct Node)); // <- parenthesis needed
but the first alternative is often preferable for clarity.
You need to allocate a memory for an object of the type struct Node declared like
struct Node {
int data;
struct Node *next;
};
So in the call of malloc you need to specify the size of the memory to be allocated for an object of this type. The function malloc returns a pointer to the allocated memory.
So you can write
struct Node *ptr = malloc( sizeof( struct Node ) );
On the other hand, the expression *ptr has the type struct Node. That is the declared pointer ptr has the pointer type struct Node * and dereferencing such a pointer like *ptr yields an expression of the type struct Node.
So you may rewrite the above record also like
struct Node *ptr = malloc(sizeof(*ptr));
because in this case sizeof( struct Node ) is equivalent to sizeof( *ptr ).
That is the compiler needs to know the type of the operand of the operator sizeof that to determine the size of an object of that type.
I am trying to learn about pointers in C, and don't understand why the unary * operator was appended to the end of the word "node" in the following code snippet:
struct node* CopyList(struct node* head) {
/* code here */
}
From my understanding of pointers, one can create a pointer with a statement like
int *pointerName;
and assign a "pointee" to it with a statement like
pointerName = malloc(sizeof(int));
and then dereference the pointer with a statement like
*pointerName = 4;
which will store the integer value 4 in the 4 bytes of memory (pointee location) which is "pointed to" by the pointerName pointer.
WITH THAT BEING SAID, what does it mean when the * is appended to the end of a word, as it is with
struct node*
???
Thanks in advance!
http://cslibrary.stanford.edu/103/
The location of the * ignores the whitespace between the base type and the variable name. That is:
int* foo; // foo is pointer-to-int
int *bar; // bar is also pointer-to-int
In both cases, the type of the variable is "pointer-to-int"; "pointer-to-int" is a valid type.
Armed with that information, you can see that struct node* is a type, that type being "pointer-to-node-structure". Finally, therefore, the whole line
struct node* CopyList(struct node* head)
means "CopyList is a function taking a pointer-to-struct node (called head) and returning a pointer-to-struct node"
int *pointerName; is the same as int * pointerName; or int* pointerName;. The data type is int* in all those cases. So struct node* is just a pointer to struct node.
struct node* CopyList
To understand better you should read it from right to left. Which says CopyList is a function returning a pointer to node.
You can use '*' either with type or with function name/variable name.But it is suggested to use it with return type while declaring methods, like shown below
struct node* CopyList(struct node* head) {
/* code here */
}
when declaring pointers of a type use * with the variable name. like shown below,
int *ptr;
Declaring in that way increases readability.
For example consider this case,
int* a,b,c;
The above statement is appearing like declaring three pointer variables of base type integer, actually we know that it's equals to
int *a;
int b,c;
Keeping the * operator near the data type is causing the confusion here, So following the other way increases readability, but it is not wrong to use * in either way.
node* means that the following function/variable/structure has type 'pointer to type node'.
I need to create a completely generic linked list that can contain any type of data specified by an enum...
A node of the list has the structure:
__________________
|_____|_____|_____|
The first field is of sizeof(nodeType) bytes containing the type of information stored. The next field has an address that contains address of the information variable. The next field has the address of the next node which can be a simple node or yet another linked list..
Basically, I have a nodeType enum as:
typedef enum{
STRING, INT, NIL, LIST
} nodType;
I have allocated memory to a node pointer like this:
nodeType* node = malloc(sizeof(nodeType) + 2*sizeof(char*));
The first sizeof(nodeType) bytes contain the type of inofrmation stored. I assigned it the value STRING by the expression:
*node = STRING;
Now, I want the next sizeof(char*) bytes store the address of a char* pointer. (All pointers are of the same size on a machine?(yes, acc to me)).. So, I assign a value to it like:
char* str = strdup("Hello");
(char**)(char*(node) + sizeof(nodeType)) = &str;
But GCC flags an error as the LHS of assignment operator is not an lvalue..
I need to assign value to that address in order to go ahead to build that list.
Is there some elegant way of doing that in c apart from using a struct??
You forgot to dereference:
*(char***)((char*)node + sizeof(nodeType)) = &str;
The result of a dereference operation is always an lvalue. In general, if you want to treat a memory location p as if it pointed to a variable of type T, you need to cast it to a T * and dereference:
*(T*)(p) = my_t_value;
This applies to your situation for T = char ** and p = (char *) node + sizeof(nodeType).
But this is just terrible design. No sane could should contain ***. And moreover, you're potentially violating alignment constraints by assuming that all your elements follow contiguously in memory. A much simpler way would be something like this:
struct Node
{
struct Node * next;
nodType type;
void * data;
};
Usage:
struct Node * p = malloc(sizeof *p);
p->next = NULL;
p->type = STRING;
p->data = str;
Note that I chose to store a string directly as a char *, and not as a pointer to a char *. The unifying theme should be that the list node owns p->data and should say free(p->data); upon node removal unconditionally.