Вы можете легко сделать это в глобальной области видимости:
// nil = &nilObj, which means nil->next == nil.
//
// This way, there's no checking for both 'nil' and 'NULL'!
//
// As a consequence of this last point, you can make passing 'NULL'
// to most list functions invalid: it just means the user didn't
// use mklist() on every list they needed to manually work with.
static struct node nilObj = { 0, "null", "null", &nilObj };
node nil = &nilObj;
void mklist(node *n)
{
*n = nil;
}
Как упоминал Стивен Доци, использование typedef T *Tname;
обычно является плохой идеей, поскольку скрывает тот факт, что вы используете указатель, которыйможет сбивать с толку, когда вы используете Tname *n
как (*n)->foo
(я бы честно предположил, что вы используете n->foo
).Некоторые API-интерфейсы делают это, но они делают это таким образом, чтобы выражать, что переменная является указателем на объект, а не на объект: вместо Node
используется что-то вроде NodeRef
или NodePtr
, означающее в именичто это указатель на узел, а не узел.Apple Core Foundation API использует такие имена (например, CFStringRef
).Я настоятельно рекомендую принять конвенцию, подобную этой, впредь.Приведенный выше код, который я разместил, может выглядеть примерно так:
static struct node nilObj = { 0, "null", "null", &nilObj };
nodeRef nil = &nilObj;
void mklist(nodeRef *n)
{
*n = nil;
}