如何使void指针在描述中按照下面的要求工作?

时间:2014-08-18 13:52:34

标签: c void-pointers

我正在尝试在C程序中实现堆栈。 这是我的程序的标头文件Stack.h

#ifndef STACK_H
#define STACK_H


typedef struct node {

    void *data;
    struct node *next;
}Stack;


void push(Stack **, void *);
void *pop(Stack **);
void *peek(Stack **);

#endif

这是我在Stack.c文件中的函数实现。

#include <stdlib.h>
#include "Stack.h" 

void push(Stack **TOP, void *data) {

    Stack *PTR;

    PTR = (Stack *)malloc(sizeof(Stack));
    if(!PTR) return;

    PTR->data = data;
    PTR->next = *TOP;
    *TOP = PTR;
}

void *pop(Stack **TOP) {

    Stack *PTR;
    void *data;
    PTR = *TOP;

    *TOP = PTR->next;
    data = PTR->data;
    free(PTR);

    return data;
}

void *peek(Stack **TOP) {

    Stack *PTR;
    PTR = *TOP;

    return PTR->data;
}

这是我的main.c文件。

#include <stdio.h>
#include "Stack.h"

int main() {

    int count;
    Stack *TOP = NULL;


    for(count = 0; count < 100; count += 10)
        push(&TOP, &count);

    while(TOP != NULL)
        printf("%d\n", *(int *)pop(&TOP));
}

这样打印100 11次:

100
100
100
100
100
100
100
100
100
100
100 

虽然应该打印出来:

100
90
80
70
60
50
40
30
20
10
0

嗯,我知道为什么会这样。这是因为我们传递了count变量存储的地址,而不管它包含的值。因此,我们得到堆栈中推送的最后一个值10次。

但是当我像这样修改我的main.c时:

#include <stdio.h>
#include "Stack.h"

int main() {

    Stack *TOP = NULL;
    int a = 5;
    char b = 'A';
    float c = 15.98;
    long d = 225678460;


    push(&TOP, &a);
    push(&TOP, &b);
    push(&TOP, &c);
    push(&TOP, &d);

    printf("%ld\n", *(long *)pop(&TOP));
    printf("%f\n", *(float *)pop(&TOP));
    printf("%c\n", *(char *)pop(&TOP));
    printf("%d\n", *(int *)pop(&TOP));
}

然后我得到了所需的输出:

225678460
15.980000
A
5

如何修改我的第一个main.c以获得第二个main.c所需的输出?

提前感谢我对编程生活的最大帮助。这是我的大学项目。

2 个答案:

答案 0 :(得分:3)

因为您的堆栈将指针保存到值而不是文字值,所以您必须将这些值保存在不同的地址。如果在循环中只使用一个变量,则将所有这些值连续存储到相同的地址中。所以堆栈上的所有节点都指向那个地址。

要解决此问题,您可以在堆上为每个值分配内存。像这样:

for(count = 0; count < 100; count += 10) {
    int *ptr = malloc(sizeof(int));
    *ptr = count;
    push(&TOP, (void*)ptr);
}

在您的情况下,您在打印堆栈上的值后立即退出,因此您可以在没有free分配的内存的情况下离开。当程序退出时,它将被释放。但是如果在实际程序中实际执行类似的操作,请确保{} 1}在您不再需要时为每个值分配的内存。或者,更现实地说,如果你想要的是一个整数堆栈,只需让每个节点保持一个free而不是一个空指针。

答案 1 :(得分:0)

你的问题是,持有什么堆栈是计数的地址。您正在使用地址而不是值初始化堆栈。 *(PTR->数据)= *数据;我认为现在应该工作它应该更新数据字段中的值而不是地址。你现在也需要为数据字段分配内存......