Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的硬链表_C_Pointers_Linked List - Fatal编程技术网

C语言中的硬链表

C语言中的硬链表,c,pointers,linked-list,C,Pointers,Linked List,我无法理解AddToList是如何工作的,如果gHeadPtr总是指向我理解的第一个(最小)评级结构,但gHeadPtr没有指向它,或者我错了?或者有人能告诉我AddToList是怎么工作的?我不知道最后一个字符串是什么意思,为什么我们需要双指针,在什么结构上指向gHeadPtr,何时gHeadPtr指向第一个(最小)评级结构,何时指向我们刚刚添加的结构(具有最大评级) struct DVDInfo { 煤焦等级; 字符标题[kMaxTitleLength]; 字符注释[kMaxCommentL

我无法理解AddToList是如何工作的,如果gHeadPtr总是指向我理解的第一个(最小)评级结构,但gHeadPtr没有指向它,或者我错了?或者有人能告诉我AddToList是怎么工作的?我不知道最后一个字符串是什么意思,为什么我们需要双指针,在什么结构上指向gHeadPtr,何时gHeadPtr指向第一个(最小)评级结构,何时指向我们刚刚添加的结构(具有最大评级)

struct DVDInfo
{
煤焦等级;
字符标题[kMaxTitleLength];
字符注释[kMaxCommentLength];
结构DVDInfo*prev;
结构DVDInfo*下一步;
};
char GetCommand(void);
结构DVDInfo*ReadStruct(无效);
void AddToList(结构DVDInfo*curPtr);
作废列表DVD(bool-forward);
char*TrimLine(char*line);
结构DVDInfo*gHeadPtr,*gTailPtr;
int main(int argc,const char*argv[]
{
char命令;
而((command=GetCommand())!='q')
{
开关(命令)
{
案例“n”:
AddToList(ReadStruct());
打破
案例“l”:
案例“r”:
ListDVD(命令=='l');
打破
}
printf(“\n------\n”);
}  
printf(“再见…\n”);
返回0;
}
char GetCommand(void)
{
字符缓冲区[100+1];
printf(“输入命令(q=quit,n=new,l=list,r=reverse list):”;
fgets(缓冲区、sizeof(缓冲区)、stdin);
返回*TrimLine(缓冲区);
}
结构DVDInfo*ReadStruct(无效)
{
结构DVDInfo*infoPtr;
infoPtr=malloc(sizeof(struct DVDInfo));
如果(infoPtr==NULL)
{
printf(“内存不足!!!再见!\n”);
出口(1);
}
字符缓冲区[500+1];
printf(“输入DVD标题:”);
fgets(缓冲区、sizeof(缓冲区)、stdin);
strlcpy(infoPtr->title、TrimLine(buffer)、sizeof(infoPtr->title));
printf(“输入DVD注释:”);
fgets(缓冲区、sizeof(缓冲区)、stdin);
strlcpy(infoPtr->comment,TrimLine(buffer),sizeof(infoPtr->comment));
int-num;
做
{
printf(“输入DVD评级(1-10):”;
fgets(缓冲区、sizeof(缓冲区)、stdin);
num=atoi(TrimLine(buffer));
}
而((num<1)|(num>10));
infoPtr->rating=num;
返回(infoPtr);
}
void AddToList(结构DVDInfo*curPtr)
{
结构DVDInfo**nextPtrPtr=&gheadtr;
结构DVDInfo*prevPtr=NULL;
而(*nextptr!=NULL&&curPtr->rating>(*nextptr)->rating)
{
prevPtr=*nextptr;
nextPtrPtr=&(prevPtr->next);
}
curPtr->prev=prevPtr;//链接到上一个结构
curPtr->next=*nextptr;//链接到下一个结构
如果(curPtr->next!=NULL)
curPtr->next->prev=curPtr;//将下一个结构的prev链接到curPtr
其他的
gTailPtr=curPtr;//没有下一个结构:curPtr现在是尾部
*NEXTPTTRPTR=curPtr;//将下一个或上一个结构(或头)链接到curPtr
} //когда функция передах структкру, а потом получает новую, указатели сохраняются?
作废列表DVD(bool-forward)
{
结构DVDInfo*curPtr=(正向?gheadtr:gTailPtr);
布尔分隔符=假;
如果(curPtr==NULL)
{
printf(“尚未输入任何DVD…\n”);
} 
其他的
{
while(curPtr!=NULL)
{
if(分离器)
printf(“----------\n”);
printf(“标题:%s\n”,curPtr->Title);
printf(“注释:%s\n”,curPtr->Comment);
printf(“评级:%d\n”,curPtr->Rating);
curPtr=(向前?curPtr->next:curPtr->prev);
分隔符=真;
}
}
}
char*TrimLine(char*line)
{
尺寸/长度=标准长度(直线);
while(长度>0&&isspace(行[length-1]))
{
行[length-1]='\0';
长度--;
}
返回线+strspn(行“\t”);
}
双指针的值是另一个指针的地址。对于AddToList(),您需要双指针,因为这样,nextPtrPtr所指向的值将自动从列表头(gheadtr)的地址开始,并在需要时进行更新。如果不需要更新gHeadPtr,您可以轻松使用“struct DVDInfo*nextptr”

对于AddToList(),有两种情况,第一种情况下肯定需要双指针。第一种情况是,如果gheadtr为NULL,则表示列表中没有元素。在这种情况下,“**nextPtrPtr=&gheadtr”意味着nextPtrPtr的值为空。这就是我们正在用“*nextPtrPtr!=NULL”检查的内容。由于它为NULL,它将跳过while循环,*nextPtrPtr将指向curPtr”。因此,gheadtr将开始指向curPtr。secodn的情况是,如果head(gheadtr)不为NULL,则我们将进入while循环,并且nextptr将根据评级标准指向最后一个元素。因此,curPtr将添加为nextptr节点之后的节点

为了进一步说明这一点,让我们假设AddToList()使用了一个指针和gheadtr was NULL(我提供以下代码,使NEXTPTR成为 在这种情况下,nextptr将指向gheadtr,这意味着 以gHeadPtr的地址(比如0x1010)为例,因为nextptr为NULL(您可能 如果用NULL初始化gheadtr,顺便说一句),它现在将跳过while循环和最后一个循环 语句将被执行“nextptr=curPtr;有了这个,nextPtrPtr现在指向curPtr(让 美国称其地址为0x20
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;
...
...
*nextPtrPtr = curPtr;  
/* Note: Incorrect version for the sake of explanation */
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
}
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;