That's a recursive definition. A list is defined either by a base case empty or by a recursive case. The recursive case tells you how to make a bigger list from an existing list. The base case tells you how to make the smallest list. It's rather like using the principle of mathematical induction to prove theorems: Establish the truth of the theorem for an initial case (typically 0, if working with integers), and then show how to deduce the truth of the theorem for a large case using the established truth of the theorem in previous cases.
Recursive definitions of data structures lead to very elegant implementations and encourage the use of correctness proving via induction. Thus they accord with some of the most sound software engineering principles. Here for example is how the recursive definition of a list leads to a simple implementation of lists of ints:
struct iNode { int myInt; /* the data */ struct iNode *next; /* the rest of the list (itself, of course, a list) */ }
Note that it would be illegal, in C, for a struct to contain an instance of itself. But iNode contains a pointer to an iNode, not the iNode itself.
The token iNode is a structure tag and serves as a shorthand for the detailed description of the structure. In order to declare an iNode you can use the structure tag in code like:
struct inode *temp;
In general we prefer to work with pointers to dynamic, recursively defined, structures. The reason will be apparent in the next chapter.