-
Simple typedef question
Hi,
If i have the following:
Code:
struct stackNode {
int data;
struct stackNode *nextPtr;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
I know the 2nd last line is just to save some work when declaring variables with the type struct stackNode. But what's the last line for? Why has it got the asterisk there? Why make it a pointer. Note that i'm now learning linked lists, stacks and quese at the moment. ALso, can i reduce the last two lines with this:
Code:
typedef struct stackNode *StackNodePtr;
Is this the way to do it in one line what the 2 lines are doin?
many thnx
-
The second typedef is to just save further typing and perhaps makes the code easier to understand. You can refer to a pointer to a stackNode using StackNodePtr. You wouldn't need the asterisk.
StackNodePtr ptr; /*same as StackNode* ptr*/
-
but doesn't
Code:
typedef struct stackNode *StackNodePtr;
do the same thing?
-
Yes, but you wouldn't get the first one just doing this.
-
typedef struct stackNode *StackNodePtr;
This should be typed:
typedef struct stackNode* StackNodePtr;
In other words, if you want a stackNode*, instead of doing:
stackNode *myStack;
...you could simply type:
StackNodePtr myStack;
..which is of course a stackNode*!
Like:
typedef int* pInt;
..means that if you need an int pointer you could type:
pInt ptr;
Likewise, you could do:
typedef int[100] hundredIntArray;
Then if you need an array of 100 ints, you could do:
hundredIntArray array;
...get it?
-
but in my deitel book it's typed
typedef QueueNode *QueueNodePtr;
?
-
ok , the source file is attached. Hav a look. The function prototypes format is:
Code:
void enqueue( QueueNodePtr *, QueueNodePtr * );
QueueNodePtr is already typedefed as a declaration of a pointer, so why is there an extra * ?
-
That's because the two functions listed take pointers to pointers as arguments. If they didn't, you would see them without the extra asterick...
-
The attached source isn't readable. I'd guess they are passing a pointer to a pointer, so as to change the address that something points to rather than changing the contents pointed to.
-
so that means if i don't have the typedef things at the top, i would have the function prototype:
Code:
void enqueue( struct queueNode **, struct queueNode ** );
right?
-
-
see? Thats the deitel book problem again. It doesn't teach all of the stuff. It assumes you can pick up everything from the one piece of code. Pancho might ask this question when he gets up to chapter 12 too.
-
Often these programming books really just show off. Don't be discouraged.
-
This is the contemporary (and incorrect) way to declare structures and structure pointers. The compiler swallows it only because this is the old-time way that structures were declared.
Code:
struct stackNode {
int data;
struct stackNode *nextPtr;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
The above is a "pascalized" _forward_ declaration method. It gives 'stackNode' form without substance until it is typedef'd as a new (that is "non-homogenous", or "extrinsic") type.
The reason you have 'typedef struct stackNode StackNode; is so that you tell the compiler that the amorphous forward declaration of 'stackNode' is to be considered and referred to by the 'StackNode' type.
The reason you have 'typedef 'StackNode *StackNodePtr' is to create a type of pointer variable that refers to the new type.
Here is the modern, correct way to create both the declaration and the typedef--
Code:
typedef struct stackNode
{
int data;
struct stackNode *nextPtr;
}StackNode, *StackNodePtr;
The reason you give the forward declaration ('stackNode') in this structure at all, is because it references itself, so the compiler must be able to locate the forward declaration already on the symbol table in order to resolve the self-reference.
Also, please give thought that whenever you create linked lists, you always put the self-referencing pointer as the _first_ member in the structure. It's a good habit. That way, if you ever have to change the size or orientation of the structure (say, you update software), that pointer can _always_ be found because it's at the structure's starting address. It makes 'backwards compatibility' much easier.
For example:
Code:
typedef struct stackNode
{
struct stackNode *nextPtr;
int data;
}StackNode, *StackNodePtr;
Enjoy.
-
And to be really obvious, be aware that:
Code:
StackNode *theNode1P;
StackNodePtr theNode2P;
both are the same exact thing. If you have to do a lot of dereferencing, it can make things _much_ easier to understand by not having to have an asterisk next to the variable name.
I mean, consider having to deref through a variety of handles and pointers---
x = *(**(**(**(**moulin)rouge)))->nicole;
This kind and level of dereferencing is commonplace within some O/Ss.
Enjoy,