什么';在我使用calloc之后,检查列表数组中单个列表是否为空的最佳方法是什么?

什么';在我使用calloc之后,检查列表数组中单个列表是否为空的最佳方法是什么?,c,pointers,struct,linked-list,stack,C,Pointers,Struct,Linked List,Stack,通常,当我使用链表时,我会写: struct node *startPtr = NULL; 所以我稍后检查它是否为空,如果为空,则表示列表为空 但在这部法典中: struct card{ char face[3]; char suit[4]; }; typedef struct card Card; struct stack{ Card cardd; struct stack *nextPtr; }; typedef struct stack Stack;

通常,当我使用链表时,我会写:

struct node *startPtr = NULL;
所以我稍后检查它是否为空,如果为空,则表示列表为空

但在这部法典中:

struct card{
    char face[3];
    char suit[4];
};
typedef struct card Card;

struct stack{
    Card cardd;
    struct stack *nextPtr;
};
typedef struct stack Stack;

int main(){
    /*
    creation of *stacks also with calloc
    */
    Stack *topstacks = calloc(4,sizeof(Stack));    // array of lists initialized by calloc
    /*
    scanf pos1, pos2 to switch
    */
    move_card(stacks, topstacks, pos1, pos2);
}

int move_card(Stack *stacks, Stack *topstacks, unsigned int pos1, unsigned int pos2){
    Stack *prevfromPtr;
    Stack *fromPtr = &(stacks[pos1]);
    Stack *toPtr = &(topstacks[pos2]); 
    while(fromPtr->nextPtr!=NULL){
        prevfromPtr = fromPtr;
        fromPtr = fromPtr->nextPtr;
    }
    Stack *newmovingcard = calloc(1,sizeof(Stack));
    newmovingcard->cardd = fromPtr->cardd;
    newmovingcard->nextPtr = NULL; 
    if (toPtr!=NULL){                       // here I'd like to check if the list is empty and has not any item. This way it does not work because toPtr can't be NULL, it's a pointer
        while(toPtr->nextPtr!=NULL){
            toPtr = toPtr->nextPtr;
        } 
        toPtr->nextPtr = newmovingcard; 
        free(fromPtr);
        prevfromPtr->nextPtr = NULL;
        return 0;
    } else {
        toPtr->cardd = newmovingcard->cardd;
        toPtr->nextPtr = NULL;
        free(fromPtr);
        prevfromPtr->nextPtr = NULL;
        return 0;
    }
}
我有一个列表数组(topstack),用calloc初始化。在
move_card
内的注释行中,我需要检查列表数组的单个列表是否为空。但我不知道怎么做


这是完整的代码,但是一些带有printf的部分是意大利语的,很抱歉:

您可以尝试将
nextPtr
分配给同一个元素,或者您可以引入一个特殊的全局项,这将意味着一个空列表。

同时处理两个链接列表有点繁琐和烦人,但这是可行的:

int移动卡(堆栈**源、堆栈**目标、int源位置、int目标位置){
//浏览链接列表,但在每种情况下,都要在
//插入点
//遍历源链并确定需要哪个指针
//被操纵。
对于(int i=0;inextPtr);
}
//遍历目标链并确定插入点。
对于(int i=0;inextPtr);
}
//捕捉我们实际移动的指针
堆栈*移动=*源;
//通过重新指定源跳过链中的此链接
*source=移动->下一个TPTR;
//捕获被碰撞的记录
堆栈*bumped=*目标;
//重新分配目标
*目标=移动;
//将碰撞的条目重新链接回链中
移动->nextPtr=碰撞;
返回0;
}
在这里,我冒昧地对一些东西进行了重命名,以使其更易于理解。注意它如何使用双指针,以便在必要时可以操纵原始指针。从链表中删除第一张卡片时,指向“头”项的指针必须更改

下面是针对该代码的更完整的“演示”工具:

#包括
#包括
结构堆栈{
字符卡[2];
结构堆栈*nextPtr;
};
typedef结构堆栈;
堆叠*make_堆叠(字符面、字符套装、堆叠*nextPtr){
Stack*Stack=calloc(1,sizeof(Stack));
堆栈->卡片[0]=面;
堆栈->卡片[1]=套装;
stack->nextPtr=nextPtr;
返回栈;
}
无效打印堆栈(堆栈*堆栈){
while(堆栈){
printf(“%c%c”,堆栈->卡[0],堆栈->卡[1]);
stack=stack->nextPtr;
}
printf(“\n”);
}
int main(int argc,字符**argv){
Stack*source=make_Stack('A','S',make_Stack('2','S',make_Stack('3','S',NULL));
Stack*target=NULL;
打印堆栈(源);
移动卡(源和目标,2,0);
打印堆栈(源);
打印堆栈(目标);
返回0;
}

其中使用了简化的卡模型。

如果您将
malloc
memset
一起使用,而不是
calloc
,则可以将您的值设置为您自己的“无效”值

我是说这种事情:

int* example;

example=malloc(100*sizeof(int));    // allocate memory to store 100 int

if(example){
    memset(example,1,100*sizeof(int));  // initialize it with value 1
}

有两种方法可以创建链接列表。一个是有一个函数,它接受指向指针的指针,并在“根”为空时进行分配;另一个是有一个存根“头”节点,该节点始终存在,但会被忽略。