tags:

views:

111

answers:

6

For example:

void DeleteLastNode(NodeType **L)

If **L represents the address of the variable L, can it not be replaced by &L instead? Also, if I were to use *L or simply just L, would I not be able to change L's contents? If so, what's the difference of using *L and L, if L is a pointer to it anyways? Would I not be able to look at it's contents just by sending in L and using *L in the actual method?

I guess I'm still not too good with pointers.

A: 

No, not in C, asterisks in the function header could not be replaced with ampersands (&) in the function body instead. In C++ it is another matter though. People thought somewhat similar thoughts and added this functionality when they decided on features for C++.

Amigable Clark Kant
+5  A: 

As far as I know one asterisk represents a normal pointer in C. For instance you can allocate memory and make the pointer point the that new allocated area. You can also point to variables in the stack like:

int x = 10;
int *p = &x;

But there are some situations where you want to pass a pointer to a function and make the function able to change the pointer to point to another address. Now we are not talking about change the contents of a variable through a pointer nor a memory pointed by it but literary change the pointer information (which is a mem. address) to point to another places. In this case we use a pointer to a pointer which is represented by double asterisk.

int x, y;
int *p;
int **pp;

pp = &p;  //pp points to pointer p
*pp = &x; //pp changes pointer p to point to variable x
*p = 10;  //p (now points to x) assigns value 10 to x
*pp = &y; //pp changes pointer p again assigning the address of y
*p = 20;  //p assigns 20 to y;
**pp = 25;// that's tricky, the first * give access to the address pointed by p (&y) the second changes the content of that address to 25. so now y ends with 25

In the end x = 10 and y = 25

Now looking particularly in you case, that function call looks like a function that will remove a node from a linked list. And this makes sense because you have an external pointer pointing to the head of the list. When you remove the last element your function must be able to change the pointer from the current address to null. You can do it using a global pointer or, as it seems in your case, passing the address of the head pointer.

Andres
+1  A: 

Let's clear some things up. Technically, L is a pointer to a pointer to a NodeType instance. However, the name of the function suggests a different interpretation: probably L is the address of a pointer to an array or a linked list of NodeType instances (you have to consult the documentation of the function to verify this).

If that is the case, then the function would typically be used like this:

NodeType *list = malloc (5 * sizeof(NodeType));
/* do something with the list, e.g. put entries into it */
DeleteLastNode (&list);  /* delete last node in list */

The function probably modifies the variable pointing to the array/list, that's why you have to pass the address of list to the function.

But to say anything specific, we need more information about DeleteLastNode ().

Adrian Willenbücher
A: 

Something that may help understand

NodeType **L

means L is a pointer to pointer to NodeType object.

For example, if it is

NodeType *P

then P is a pointer to NodeType object, and if P is 0xE0101010, and each NodeType object is 80 bytes, then P + 1 will be 0xE0101060 (0xE0101010 plus 0x50 = 0xE0101060).

Then let's look at L, which a pointer to pointer to NodeType. If we consider a pointer being 4 bytes, then if L is 0xE0202020, and L + 1 will be just 0xE0202024.

So it is important to use the right type, whenever pointer arithmetics is involved. Note that L[3] is the same as *(L + 3), so L[3] involves pointer arithmetics, therefore the pointer types need to be very precise, or else when you look at the content of where a pointer is pointing to by *L, which is call dereferencing, then a segmentation fault (Unix/Linux) or GP fault (Windows) can occur.

動靜能量
A: 
NodeType nt;
NodeType *pnt = &nt;

--------         ------
| pnt  |-------->| nt |
--------         ------

Here, pnt (content of pnt) is &nt; *pnt is nt.

NodeType **L = &pnt;

------        --------         ------
| L  |------->| pnt  |-------->| nt |
------        --------         ------

Now L (content of L) is &pnt; *L is pnt; and thus **L is *pnt, which is nt. Note that *& cancels each other (*L -> *&pnt -> pnt).

Donotalo
A: 
John Bode