Reputation: 12484
I'm trying to understand this C code from a simple priority queue, especially - why does it need the struct qnode **first
part:
int quedel(struct qnode **first, struct qnode **last, int *prio, int *val) {
struct qnode *tmp = NULL;
if((NULL == *last) && (*last == *first)) {
fprintf(stderr, "Empty queue.....\n");
return -1;
}
*val = (*first)->data, *prio = (*first)->prio;
tmp = *first, *first = (*first)->next;
if(*last == tmp)
*last = (*last)->next;
free(tmp);
return 0;
}
Upvotes: 0
Views: 98
Reputation: 477690
Since the queue itself is handled via pointers (to struct qnode
s), and since you want quedel
to have reference semantics for its first
and last
elements, you use the usual C idiom of implementing reference semantics by passing a pointer to the thing you want to refer to -- and a pointer to a pointer to a struct qnode
is, well, a double pointer.
The point of the quedel
function is to modify the actual variable inside the caller's scope, since it removes the head of the queue and changes the caller's original head pointer to a new pointer to the new head (or tail, or whichever way round this thing goes):
{
struct qnode * q = new_queue(); // or whatever
add_lots_of_elements(q); // fine; the head doesn't change,
// only its contents do
quedel(&q); // now q is something else!
}
Upvotes: 2
Reputation: 183612
Since C doesn't have pass-by-reference, only pass-by-value, this approach is the only way to make this assignment:
*first = (*first)->next;
visible to the caller.
(If first
were just a single pointer, and we wrote first = first->next
, then the code that calls this function wouldn't see the modification.)
Upvotes: 2