C 编写函数以返回节点的位置

C 编写函数以返回节点的位置,c,function,struct,linked-list,singly-linked-list,C,Function,Struct,Linked List,Singly Linked List,我试图添加一个函数,在用户输入值(字符)时查找节点位置,并返回节点的位置 我试着按照delete函数中的步骤操作,因为它看起来很相似,但我无法理解 #include <stdio.h> #include <stdlib.h> // self-referential structure struct listNode { char data; /

我试图添加一个函数,在用户输入值(字符)时查找节点位置,并返回节点的位置

我试着按照delete函数中的步骤操作,因为它看起来很相似,但我无法理解

#include <stdio.h>
#include <stdlib.h>

// self-referential structure                       
struct listNode {                                      
   char data; // each listNode contains a character 
   struct listNode *nextPtr; // pointer to next node
}; 

typedef struct listNode ListNode; // synonym for struct listNode


// prototypes
void insert(ListNode* *sPtr, char value);
char delete(ListNode* *sPtr, char value);
int find(ListNode* *sPtr, char value);
void printList(ListNode* currentPtr);
void menu(void);

int main(void)
{ 
   ListNode* Head = NULL; // initially there are no nodes
   char item; // char entered by user

   menu(); // display the menu
   printf("%s", "? ");
   unsigned int choice; // user's choice
   scanf("%u", &choice);

   // loop while user does not choose 3
   while (choice != 4) { 

      switch (choice) { 
         case 1:
            printf("%s", "Enter a character: ");
            scanf("\n%c", &item);
            insert(&Head, item); // insert item in list
            printList(Head);
            break;
         case 2: // delete an element
            // if list is not empty
            if (Head != NULL) { 
               printf("%s", "Enter character to be deleted: ");
               scanf("\n%c", &item);

               // if character is found, remove it
               if (delete(&Head, item)) { // remove item
                  printf("%c deleted.\n", item);
                  printList(Head);
               } 
               else {
                  printf("%c not found.\n\n", item);
               } 
            } 
            else {
               puts("List is empty.\n");
            } 
            break;
         case 3: // find node position
            // if list is not empty
            if (Head != NULL) { 
               printf("%s", "Enter character to find position: ");
               scanf("\n%c", &item);

               printf("Element %c is at index %d", item, find(&Head,item));
            } 
            else {
               puts("List is empty.\n");
            } 
            break;
         default:
            puts("Invalid choice.\n");
            menu();
            break;
      } // end switch

      printf("%s", "? ");
      scanf("%u", &choice);
   } 

   puts("End of run.");
} 

// display program instructions to user
void menu(void)
{ 
   puts("Enter your choice:\n"
      "   1 to insert an element into the list.\n"
      "   2 to delete an element from the list.\n"
      "   3 to find node position\n."
      "   4 to end.");
} 

int find(ListNode* *sPtr, char value)
{
    int count = 0;
    while (sPtr != NULL || value != (*sPtr)->data)
    {
        count++;
        *sPtr = (*sPtr)->nextPtr;
    }
    return count;
}
#包括
#包括
//自指结构
结构listNode{
char data;//每个listNode包含一个字符
struct listNode*nextPtr;//指向下一个节点的指针
}; 
类型定义结构listNode listNode;//结构listNode的同义词
//原型
无效插入(列表节点**sPtr,字符值);
字符删除(列表节点**sPtr,字符值);
int find(列表节点**sPtr,字符值);
作废打印列表(ListNode*currentPtr);
作废菜单(作废);
内部主(空)
{ 
ListNode*Head=NULL;//最初没有节点
char item;//用户输入的字符
menu();//显示菜单
printf(“%s”和“?”);
unsigned int choice;//用户的选择
scanf(“%u”,选择(&C);
//在用户未选择3时循环
而(选择!=4){
开关(选择){
案例1:
printf(“%s”,“输入字符:”);
scanf(“\n%c,&项);
插入(&Head,item);//在列表中插入项
印刷品清单(标题);
打破
案例2://删除一个元素
//如果列表不是空的
如果(Head!=NULL){
printf(“%s”,“输入要删除的字符:”);
scanf(“\n%c,&项);
//如果找到字符,请将其删除
if(删除(&Head,item)){//删除项
printf(“%c已删除。\n”,项);
印刷品清单(标题);
} 
否则{
printf(“%c未找到。\n\n”,项);
} 
} 
否则{
puts(“列表为空。\n”);
} 
打破
案例3://查找节点位置
//如果列表不是空的
如果(Head!=NULL){
printf(“%s”,“输入字符以查找位置:”);
scanf(“\n%c,&项);
printf(“元素%c位于索引%d”,项,查找(&Head,项));
} 
否则{
puts(“列表为空。\n”);
} 
打破
违约:
puts(“无效选择。\n”);
菜单();
打破
}//结束开关
printf(“%s”和“?”);
scanf(“%u”,选择(&C);
} 
出售(“结束运行”);
} 
//向用户显示程序指令
作废菜单(作废)
{ 
放置(“输入您的选择:\n”
“1将元素插入列表。\n”
“2从列表中删除元素。\n”
“3以查找节点位置\n。”
“4结束。”);
} 
int find(列表节点**sPtr,字符值)
{
整数计数=0;
while(sPtr!=NULL | | value!=(*sPtr)->数据)
{
计数++;
*sPtr=(*sPtr)->NEXTPTTR;
}
返回计数;
}

我首先使用insert函数添加节点,例如:A->B->C。当用户输入B作为值时,我希望它返回索引1。每当我运行下面的代码时,就会转储分段错误核心。

循环不正确。对于初学者,而不是这个while循环

while (sPtr != NULL || value != (*sPtr)->data)
应该有以下循环

while ( *sPtr != NULL && value != (*sPtr)->data)
此声明

    *sPtr = (*sPtr)->nextPtr;
更改您的列表

该函数可以按以下方式显示

int find( ListNode **sPtr, char value )
{
    int count = 0;

    while ( *sPtr != NULL && value != (*sPtr)->data )
    {
        count++;
        sPtr = &(*sPtr)->nextPtr;
    }

    return *sPtr == NULL ? - 1 : count;
}
即节点位置从0开始。如果未找到具有给定值的节点,则函数返回-1

事实上,由于函数中的列表没有更改,第一个参数可以声明为单个指针。在这种情况下,函数可以如下所示

int find( ListNode *sPtr, char value )
{
    int count = 0;

    while ( sPtr != NULL && value != sPtr->data )
    {
        count++;
        sPtr = sPtr->nextPtr;
    }

    return sPtr == NULL ? - 1 : count;
}

循环不正确。对于初学者,而不是这个while循环

while (sPtr != NULL || value != (*sPtr)->data)
应该有以下循环

while ( *sPtr != NULL && value != (*sPtr)->data)
此声明

    *sPtr = (*sPtr)->nextPtr;
更改您的列表

该函数可以按以下方式显示

int find( ListNode **sPtr, char value )
{
    int count = 0;

    while ( *sPtr != NULL && value != (*sPtr)->data )
    {
        count++;
        sPtr = &(*sPtr)->nextPtr;
    }

    return *sPtr == NULL ? - 1 : count;
}
即节点位置从0开始。如果未找到具有给定值的节点,则函数返回-1

事实上,由于函数中的列表没有更改,第一个参数可以声明为单个指针。在这种情况下,函数可以如下所示

int find( ListNode *sPtr, char value )
{
    int count = 0;

    while ( sPtr != NULL && value != sPtr->data )
    {
        count++;
        sPtr = sPtr->nextPtr;
    }

    return sPtr == NULL ? - 1 : count;
}

while(sPtr!=NULL | | value!=(*sPtr)->数据)
-->
while(*sPtr!=NULL&&value!=(*sPtr)->数据)
如果只需遍历列表,为什么要传递双指针?
while(sPtr!=NULL | value!=(*sPtr)->数据)
while(*sPtr!=NULL&&value!=(*sPtr)->数据)
如果只需遍历列表,为什么要传递双指针?谢谢你的回答,我显然不明白单指针和双指针的区别,但我现在似乎掌握了窍门。我试着改变一下代码,我能这样写吗int find(ListNode sPtr,char value){ListNode current=sPtr;int count=0;而(current!=NULL&&value!=current->data){current=current->nextPtr;count++;}如果(current->data==value){return count;}否则{return 1;}```@justforfun对于启动器,第一个参数应为指针ListNode*sPtr,之后回路电流可等于NULL。因此,您可能不使用表达式current->data==valueit现在工作得非常好,我现在感觉更好了,非常感谢:))谢谢您的回答,我显然不理解单指针和双指针的区别,但我现在似乎明白了。我试着改变一下代码,我能这样写吗int find(ListNode sPtr,char value){ListNode current=sPtr;int count=0;而(current!=NULL&&value!=current->data){current=current->nextPtr;count++;}如果(current->data==value){return count;}否则{return 1;}```@justforfun对于启动器,第一个参数应为指针ListNode*sPtr,之后回路电流可等于NULL。因此,您不能使用表达式current->data