Reputation: 453
I have a doubt about this code I saw at the university.
struct nodeList{
int data;
nodeList * next;
};
typedef nodeList * List;
void filter( List &l )
{
List * aux = &l;
while(*aux)
{
if( (*aux)->data > 3 )
{
List toDelete = *aux;
*aux = (*aux)->next;
delete toDelete;
}
else
{
aux = &((*aux)->next);
}
}
}
I don't know, what does List * aux = &l;
actually do. Because List
is the same as nodeList *
so, the code would be nodeList * * aux = &l;
and that is actually what I don't understand, is that a pointer to a pointer that holds the address of a pointer of a nodeList struct
?
The second thing I have trouble understanding is the last line. aux = &((*aux)->next);
Why is aux
without a *
on the left side? if It was declared as List *aux = &l;
is List
just a pointer to the first node?
Thank you in advance. I googled a lot, but I didn't find any answers. If you can answer my questions I'll appreciate a lot.
Upvotes: 6
Views: 288
Reputation: 1
- I don't know, what does
List * aux = &l;
actually do. BecauseList
is the same asnodeList *
so, the code would benodeList * * aux = &l;
and that is actually what I don't understand, is that a pointer to a pointer that holds the address of a pointer of anodeList struct
?
It takes the address of the pointer equivalent from the reference parameter (thus is the same as a nodeList**
actually).
- The second thing I have trouble understanding is the last line.
aux = &((*aux)->next);
Why isaux
without a*
on the left side? if It was declared asList *aux = &l;
isList
just a pointer to the first node?
aux
is a reference, so the original pointer passed as parameter l
will be changed.
Upvotes: 1
Reputation: 41127
void filter( List &l )
This means "pass by reference" rather than "by value", i.e. pass a pointer to the object l rather than copy l to the stack. In terms of how it actually works on a computer, there is no difference between "void filter( List &l )" and "void filter( List *l )" as they both end up being pointers passed to a function. From a coder's perspective, however, "void filter( List &l )" has the advantage that the complier ensures you won't get a 'nullptr'.
List * aux = &l;
This means "give me a pointer to object l". The symbol "&" is used for many different things in C/C++, and in this context it means "give me the address of". aux
is a pointer to an object of type List, not an object of type List (of course List here is itself a pointer to nodeList).
aux = &((*aux)->next);
*aux
is the object pointed by aux, which is a "nodeList*". (*aux)->next
is the next pointer in the nodelist object pointed to by the List object pointed at by aux. aux = &
sets the aux pointer to point to this object.
This code segment isn't particularly clear or concise, so I'm assuming it's written this way as an educational tool to see if you understand pointers, references, and address of in C/C++. As such, perhaps you should review the definitions of these operators in a tutorial on pointers in C/C++.
Upvotes: 2
Reputation: 32923
Exactly.
You should always match the datatypes. aux
is a nodeList **
, therefore any assignment should be of the same datatype. Since ((*aux)->next)
is nodeList *
, you use the &
operator to get a nodeList **
.
Datatypes
Variables have specific datatypes. For example, aux
is a List*
but List
is an alias of nodeList*
, so aux
is a nodeList**
.
But also expressions have datatypes as a whole. For example,
((*aux)->next)
is of datatype nodeList *
and &((*aux)->next)
is of datatype nodeList **
. You use the operator &
to get the memory address of a variable, and the result data type of using &
is one more star.*aux
is of datatype nodeList *
, because aux is nodeList **
and the star operator gets the value of the pointed element by the pointer, effectively removing one star from the datatype.Upvotes: 5