简体   繁体   English

在 c 中使用通用指针实现堆栈

[英]Implementing stack using generic pointer in c

This is my code for implementing stack using generic pointer, I am not getting the proper output, at the time of display, sometimes I am getting garbage value, there is also a problem while popping the value.这是我使用通用指针实现堆栈的代码,我没有得到正确的 output,在显示时,有时我得到垃圾值,弹出值时也有问题。

I took void *data as generic pointer and I have to pass int and float values to it, I have used memmove to move the address of local variables of int and float to pass the address to the generic pointer.我将void *data作为通用指针,我必须将intfloat值传递给它,我使用memmove移动intfloat的局部变量的地址以将地址传递给通用指针。

I am new with generic pointers and implemented it first time.我是通用指针的新手,并第一次实现了它。 I just cant find out whats the problem.我只是无法找出问题所在。

If anybody could solve my problem than it would be great help.如果有人可以解决我的问题,那将是很大的帮助。
Thank you.谢谢你。

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

static int position = 0;


typedef struct generic
{
    void *data;
    struct generic *next;
} generic;


generic *pop(generic *top);


generic *
push (generic *top, void *temp, int size)
{
    generic *nw;
    nw = (generic *) malloc (sizeof (generic));
    nw->data = malloc(size);
    memmove(nw->data, temp, size);
    nw->next = top;
    return nw;
}

generic *
pop (generic *top)
{
    generic *p;
    if (top == NULL)
        printf ("\n Stack is empty");
    else
    {
        p = top->next;
        free(top->data);
        free (top);
        top = p;
        position--;
        return top;
    }
}



void
display (generic *top, int temp[])
{
    int pos = 0;
    for (; top != NULL; top = top->next)
    {
        if (temp[pos] == 1)
            printf ("\n %d", *(int *) top->data);
        else
            printf ("\n %.2f", *(float *) top->data);
        pos++;
    }
}




int
main ()
{
    generic *top = NULL;
    int choice;


    bool exitt = false;
    int temp[5];
    while(1)
    {
        printf ("\n*******Stack using generic pointer*********\n");
        printf ("\n 1.PUSH");
        printf ("\n 2.POP");
        printf ("\n 3.DISPLAY");
        printf ("\n 4.EXIT");
        printf ("\n********************************************\n");

        printf ("\n enter the choice");
        scanf ("%d", &choice);
        switch (choice)
        {
        case 1:
            int choose;
            printf("Enter the choose option\n");
            scanf("%d", &choose);
            if (choose == 1)
            {
                int val;
                printf ("\nenter the value");
                scanf ("%d", &val);
                top = push (top, &val, sizeof(val));
                temp[position++] = 1;
            }
            else
            {
                float val;
                printf ("\nenter the value");
                scanf ("%f", &val);
                top = push (top, &val, sizeof(val));
                temp[position++] = 2;

            }
            break;

        case 2:
            top = pop (top);
            break;

        case 3:
            display (top, temp);
            break;
        default :
            exit(0);
        }
    }
    return 0;
}

This is not a complete answer.这不是一个完整的答案。

I suggest you use a union , for example:我建议您使用union ,例如:

typedef struct generic
{
    int datatype;
    union {
        int intval;
        float floatval;
    }u;
    struct generic *next;
} generic;

Now you can store the type of the data with the data and do not need to keep track of it outside your data structure.现在您可以将数据的类型与数据一起存储,而无需在数据结构之外跟踪它。

First of all the function pop has to return something if top == NULL , as kaylum pointed out in the comments.首先 function pop如果top == NULL必须返回一些东西,正如kaylum在评论中指出的那样。

if (top == NULL) {
    fprintf(stderr, "Error: stack is empty\n");
    return NULL;
}

Note that you also don't need to cast malloc , because it returns void * , which is automatically and safely promoted to any other pointer.请注意,您也不需要malloc ,因为它返回void * ,它会自动且安全地提升为任何其他指针。

nw = malloc(sizeof(generic)); /* no need to cast malloc */

Your approach你的方法

If you want to stick to your approach, I would store the return value of sizeof() in the site_t datatype.如果您想坚持您的方法,我会将sizeof()的返回值存储在site_t数据类型中。

push (generic *top, void *temp, size_t size) { }

And the thing that actually causes your problem is the fact that you iterate over the array temp from 0 to position - 1 while the elements on the stack are in reverse order.实际上导致您的问题的事情是您在数组temp0position - 1迭代,而堆栈上的元素是相反的顺序。 This code should work though:这段代码应该可以工作:

void display (generic *top, int temp[])
{
    for (; top != NULL; top = top->next) {
        position--; // <- the global variable
        if (temp[position] == 1)
            printf("%d\n", *(int *) top->data);
        else
            printf("%.2f\n", *(float *) top->data);
    }
}

Alternative solution替代解决方案

I would store the data in a union instead of a generic void pointer, as briefly described in Paul Ogilvie's answer , because with your approach you have to keep track of the datatype outside, which is generally not a good idea.正如Paul Ogilvie 的回答中简要描述的那样,我会将数据存储在union中而不是通用的void指针中,因为使用您的方法,您必须跟踪外部的数据类型,这通常不是一个好主意。

C11 and newer C11 及更新版本

As of C11 the union can be anonymous:C11开始, union可以是匿名的:

enum datatype {
    DATATYPE_INT,
    DATATYPE_FLOAT,
}

struct generic {
    enum datatype;
    union {
        int int_data;
        float float_data;
    };
    struct generic *next;
};

The data can then be accessed like this:然后可以像这样访问数据:

if (top->datatype == DATATYPE_INT)
    printf("%d\n", top->int_data);
else if (top->datatype == DATATYPE_FLOAT)
    printf("%f\n", top->float_data);

C99 and older C99 及以上

If you are using C99 or older you have to name the union .如果您使用的是C99或更早版本,则必须命名union

enum datatype {
    DATATYPE_INT,
    DATATYPE_FLOAT,
}

struct generic {
    enum datatype;
    union {
        int int_data;
        float float_data;
    } data;
    struct generic *next;
};

The data can then be accessed like this:然后可以像这样访问数据:

if (top->datatype == DATATYPE_INT)
    printf("%d\n", top->data.int_data);
else if (top->datatype == DATATYPE_FLOAT)
    printf("%f\n", top->data.float_data);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM