You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言链表实现栈:输出异常与指针警告问题求助

问题:链表实现栈的C代码指针警告与输出异常修复

我编写了一段基于链表实现栈的C语言代码,包含入栈、出栈等操作,但运行时出现指针类型不兼容的警告,且输出结果不符合预期。请协助修改push()、pop()和freeStack()函数。

原代码

// C program for linked list implementation of stack 
#include <stdio.h> 
#include <stdlib.h>

// Implement a stack as a linked list
typedef struct Node { 
    int data; 
    struct StackNode* next; 
}Node; 

typedef struct Stack {
    int size;
    Node *pTop;
}Stack;

// Initialize the stack
void init (Stack *s) {
    s = (Stack*)malloc(sizeof(Stack));
    s->size = 0;
    s->pTop = NULL;
}

// Check if a stack is empty
int isEmpty (Stack st) {
    return (st.size == 0);
}

// Push operation to add new element
int push (int newData, Stack *st) 
{
// put newData in a stack node -> this node becomes the top element
    Node *p = (Node*)malloc(sizeof(Node));
    if (p == NULL) // check if memory allocation for the new node is successful
        return 0; // return 0 to indicate failure
    p->data = newData;
    p->next = st->pTop;
    st->pTop = p;
    st->size++;
    return 1;
}

// Pop operation to delete the first top element
int pop (Stack *st) 
{
    Node *p;
    if (isEmpty(*st))
        return 0; // fail to pop
    p = st->pTop;
    st->pTop = st->pTop->next; // change the pointer of the top element to the second top element
    st->size--;
    free(p);
    return 1;
}

// Top operation to return the top element
int top(Stack st) {
    if (isEmpty(st))
        return 1;
    return st.pTop->data;
}

// Display elements of the stack
void display(Stack *s)
{
    Node *p = s->pTop;
    printf("Stack: ");
    for (; p != NULL; p = p->next) {
        printf("%d ", p->data);
    }
    printf("\n");
}

// Free all memory used by the stack
void freeStack(Stack* st) {
    Node* current = st->pTop;
    Node* next;

    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }

    st->pTop = NULL;
    st->size = 0;
}

int main() 
{ 
    // Memory allocation
    Stack st;
    init(&st);

    // Push elements
    push(10, &st); 
    push(20, &st); 
    push(30, &st); 
    display(&st);

    printf("30 is popped from stack\n", pop(&st)); 
    display(&st);

    printf("Top element is %d\n", top(st)); 

    freeStack(&st);

    return 0; 
} 

运行错误输出

linked_list_stack.c: 在函数‘push’中:
linked_list_stack.c:36:17: 警告:从不兼容的指针类型‘Node *’赋值给‘struct StackNode *’ [-Wincompatible-pointer-types]
   36 |         p->next = st->pTop;
      |                 ^
linked_list_stack.c: 在函数‘pop’中:
linked_list_stack.c:50:14: 警告:从不兼容的指针类型‘struct StackNode *’赋值给‘Node *’ [-Wincompatible-pointer-types]
   50 |     st->pTop = st->pTop->next; // 将栈顶指针改为指向次栈顶元素
      |              ^
linked_list_stack.c: 在函数‘display’中:
linked_list_stack.c:68:25: 警告:从不兼容的指针类型‘struct StackNode *’赋值给‘Node *’ [-Wincompatible-pointer-types]
   68 |     for (; p != NULL; p = p->next) {
      |                         ^
linked_list_stack.c: 在函数‘freeStack’中:
linked_list_stack.c:80:14: 警告:从不兼容的指针类型‘struct StackNode *’赋值给‘Node *’ [-Wincompatible-pointer-types]
   80 |         next = current->next;
      |              ^
栈内容: 30 20 10 -489483407
已从栈中弹出30
栈内容: 20 10 -489483407
栈顶元素为20

问题分析与修改方案

1. 指针类型不兼容问题

Node结构体中next指针被定义为struct StackNode*,但代码中根本不存在struct StackNode类型,正确的应该是指向自身结构体的指针struct Node*。

2. 栈初始化函数错误

init函数中直接给形参s赋值malloc的地址,这只会修改函数内部的形参,不会影响main中定义的栈变量,导致栈的size和pTop未被正确初始化,出现垃圾值。

3. top函数逻辑缺陷

栈为空时返回1,但1可能是合法的栈元素值,应该通过更清晰的方式区分空栈和正常返回值。

4. 冗余的printf参数

main中printf("30 is popped from stack\n", pop(&st));多了一个参数,printf没有对应的占位符,虽然不影响运行,但不符合规范。

修改后的完整代码

// C program for linked list implementation of stack 
#include <stdio.h> 
#include <stdlib.h>

// Implement a stack as a linked list
typedef struct Node { 
    int data; 
    struct Node* next;  // 修正指针类型为自身结构体指针
} Node; 

typedef struct Stack {
    int size;
    Node *pTop;
} Stack;

// Initialize the stack:直接初始化传入的栈变量,无需malloc
void init(Stack *s) {
    s->size = 0;
    s->pTop = NULL;
}

// Check if a stack is empty
int isEmpty(Stack st) {
    return (st.size == 0);
}

// Push operation to add new element
int push(int newData, Stack *st) 
{
    Node *p = (Node*)malloc(sizeof(Node));
    if (p == NULL) 
        return 0; 
    p->data = newData;
    p->next = st->pTop;
    st->pTop = p;
    st->size++;
    return 1;
}

// Pop operation to delete the first top element
int pop(Stack *st) 
{
    Node *p;
    if (isEmpty(*st))
        return 0; 
    p = st->pTop;
    st->pTop = st->pTop->next; 
    st->size--;
    free(p);
    return 1;
}

// Top operation:用指针参数返回结果,空栈返回0表示失败
int top(Stack st, int *result) {
    if (isEmpty(st))
        return 0;
    *result = st.pTop->data;
    return 1;
}

// Display elements of the stack
void display(Stack *s)
{
    Node *p = s->pTop;
    printf("Stack: ");
    for (; p != NULL; p = p->next) {
        printf("%d ", p->data);
    }
    printf("\n");
}

// Free all memory used by the stack
void freeStack(Stack* st) {
    Node* current = st->pTop;
    Node* next;

    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }

    st->pTop = NULL;
    st->size = 0;
}

int main() 
{ 
    Stack st;
    init(&st);

    push(10, &st); 
    push(20, &st); 
    push(30, &st); 
    display(&st);

    // 修正printf,先判断pop是否成功再输出
    if (pop(&st)) {
        printf("30 is popped from stack\n");
    }
    display(&st);

    int topVal;
    if (top(st, &topVal)) {
        printf("Top element is %d\n", topVal);
    } else {
        printf("Stack is empty\n");
    }

    freeStack(&st);

    return 0; 
} 

修改说明

  • 指针类型修正:将Node结构体的next指针改为struct Node*,解决类型不兼容警告。
  • 初始化函数修复:直接操作传入的栈指针,初始化size和pTop,避免无效的malloc操作。
  • top函数优化:通过指针参数返回栈顶元素,空栈时返回0,避免返回值歧义。
  • printf修正:移除冗余参数,先判断pop是否成功再输出提示信息。

内容的提问来源于stack exchange,提问作者ahnherin092

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 07:34:58