我无法理解 AddToList 的工作原理,如果 gHeadPtr 始终指向第一个(最小)评级结构我理解它,但 gHeadPtr 没有指向它,或者我错了?或者有人可以告诉我 AddToList 是如何工作的?我不知道最后一个字符串是什么意思,为什么我们需要双指针以及 gHeadPtr 的结构点以及 gHeadPtr 何时指向第一个(最小)评级结构,何时添加到我们刚刚添加的结构(具有最大评级)
struct DVDInfo
{
char rating;
char title[ kMaxTitleLength ];
char comment[ kMaxCommentLength ];
struct DVDInfo *prev;
struct DVDInfo *next;
};
char GetCommand( void );
struct DVDInfo *ReadStruct( void );
void AddToList( struct DVDInfo *curPtr );
void ListDVDs( bool forward );
char *TrimLine( char *line );
struct DVDInfo *gHeadPtr, *gTailPtr;
int main (int argc, const char * argv[])
{
char command;
while ( (command = GetCommand() ) != 'q' )
{
switch( command )
{
case 'n':
AddToList( ReadStruct() );
break;
case 'l':
case 'r':
ListDVDs( command=='l' );
break;
}
printf( "\n----------\n" );
}
printf( "Goodbye...\n" );
return 0;
}
char GetCommand( void )
{
char buffer[ 100+1 ];
printf( "Enter command (q=quit, n=new, l=list, r=reverse list): " );
fgets( buffer, sizeof(buffer), stdin );
return *TrimLine( buffer );
}
struct DVDInfo *ReadStruct( void )
{
struct DVDInfo *infoPtr;
infoPtr = malloc( sizeof( struct DVDInfo ) );
if ( infoPtr == NULL )
{
printf( "Out of memory!!! Goodbye!\n" );
exit( 1 );
}
char buffer[ 500+1 ];
printf( "Enter DVD Title: " );
fgets( buffer, sizeof(buffer), stdin );
strlcpy( infoPtr->title, TrimLine( buffer ), sizeof(infoPtr->title) );
printf( "Enter DVD Comment: " );
fgets( buffer, sizeof(buffer), stdin );
strlcpy( infoPtr->comment, TrimLine( buffer ), sizeof(infoPtr->comment) );
int num;
do
{
printf( "Enter DVD Rating (1-10): " );
fgets( buffer, sizeof(buffer), stdin );
num = atoi( TrimLine( buffer ) );
}
while ( ( num < 1 ) || ( num > 10 ) );
infoPtr->rating = num;
return( infoPtr );
}
void AddToList( struct DVDInfo *curPtr )
{
struct DVDInfo **nextPtrPtr = &gHeadPtr;
struct DVDInfo *prevPtr = NULL;
while ( *nextPtrPtr != NULL && curPtr->rating > (*nextPtrPtr)->rating )
{
prevPtr = *nextPtrPtr;
nextPtrPtr = &(prevPtr->next);
}
curPtr->prev = prevPtr; // link to previous struct
curPtr->next = *nextPtrPtr; // link to next struct
if ( curPtr->next != NULL )
curPtr->next->prev = curPtr; // link prev of next struct to curPtr
else
gTailPtr = curPtr; // no next struct: curPtr is now the tail
*nextPtrPtr = curPtr; // link next or previous struct (or head) to curPtr
} //когда функция передах структкру, а потом получает новую, указатели сохраняются?
void ListDVDs( bool forward )
{
struct DVDInfo *curPtr = ( forward ? gHeadPtr : gTailPtr );
bool separator = false;
if ( curPtr == NULL )
{
printf( "No DVDs have been entered yet...\n" );
}
else
{
while ( curPtr != NULL )
{
if ( separator )
printf( "--------\n" );
printf( "Title: %s\n", curPtr->title );
printf( "Comment: %s\n", curPtr->comment );
printf( "Rating: %d\n", curPtr->rating );
curPtr = ( forward ? curPtr->next : curPtr->prev );
separator = true;
}
}
}
char *TrimLine( char *line )
{
size_t length = strlen( line );
while ( length > 0 && isspace( line[length-1] ))
{
line[length-1] = '\0';
length--;
}
return line + strspn( line, " \t" );
}
最佳答案
struct DVDInfo **nextPtrPtr = &gHeadPtr;
struct DVDInfo *prevPtr = NULL;
nextPtrPtr 是必需的,因为程序员不想弄乱全局头指针(gHeadPtr)。我们只是使用此指针来迭代列表,因为使用指针到指针比使用头指针本身进行迭代更好。
while ( *nextPtrPtr != NULL && curPtr->rating > (*nextPtrPtr)->rating )
{
prevPtr = *nextPtrPtr;
nextPtrPtr = &(prevPtr->next);
}
上面来自 AddToList 的代码处理查找新节点应在列表中进入的位置(即电影的降序评级)。
curPtr->prev = prevPtr; // link to previous struct
curPtr->next = *nextPtrPtr; // link to next struct
上面的行用于插入链接列表。
if ( curPtr->next != NULL )
curPtr->next->prev = curPtr; // link prev of next struct to curPtr
else
gTailPtr = curPtr;
如果新节点 (curPtr) 是链表中的第一个节点或最后一个节点,则使用上面的这些行。
关于c - C 中的硬链接(hard link)表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18776394/