【问题标题】:Popping & Getting Value From Multi-Type Stack从多类型堆栈中弹出和获取价值
【发布时间】:2014-03-04 17:08:53
【问题描述】:
  • 我有一个 Stack(使用链表结构实现),它包含两种类型:char *(保存字符串的值)和 double(保存数字的值)。 我有一个 Pop 函数,它是 void 将顶部值从堆栈中弹出。但我也想获得这个价值。

  • 但我不知道该怎么做,因为我无法在 C 中进行函数重载,这将允许我拥有两个 Pop 函数(一个是 char * 类型,另一个是 double 类型) 返回各自的类型。有人知道另一种解决方法吗?

这是我迄今为止的代码:

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


typedef struct stack
{
    char *valC;
    double valNum;
    struct stack *next;
}node;

node *head = NULL;

    int isnumber(char *str)
    {
        int i;
        for (i = 0; str[i] != '\0'; i++)
            {
                if (!isdigit(str[i]))
                return (0);
        }
        return (1);
        }


    node *get_node(void *item)
{
    node *temp;
    temp = (node*)malloc(sizeof(node));
    if (temp == NULL) printf("Memory Cannot Be Allocated");
    temp->valC = item;
    temp->next = NULL;
    return (temp);
}

void Push (char *Item, double num, node **head)
{
    node *New = (node*)malloc(sizeof(node));
    if (New == NULL) printf("Memory Cannot Be Allocated");
    New->valNum = num;
    New->valC = Item;
    //node *get_node(void*);
    //New = get_node(Item);
    New->next = *head;
    *head = New;
}


int Sempty (node *temp)
{
    if(temp == NULL)
        return 1;
    else
        return 0;
}

void Pop (node **head)
{
    char *item;
    double itemN;
    node *temp;
    node *prev = (node*)malloc(sizeof(node));
    //item = (*head)->valC;
    //itemN = (*head)->valNum;
    temp = *head;
    prev->next = temp;

    *head = (*head)->next;
    free(temp);
    if (prev->valC != NULL)
    {
      return (prev->valC);
    }
    else if (prev->valNum > 0)
    {
      return (prev->valNum);
    }

}

double PopN (node **head)
{
    double itemN;
    node *temp;
    itemN = (*head)->valNum;
    temp = *head;
    *head = (*head)->next;
    free(temp);
    return(itemN);
}

void Display (node **head)
{

    node *temp;
    temp = *head;
    char *error;
    if(Sempty(temp)) {
        printf("Empty Stack!\n");
        error = "::error::\n";
        Push(error, 0, &temp);
    }
    else
    {
        while (temp != NULL)
        {
            if (temp->valC != NULL) printf("%s\n", temp->valC);
            if (temp->valNum > 0) printf("%f\n", temp->valNum);
            temp = temp->next;
        }
    }
}


void main()
{

    node *inp = (node*)malloc(sizeof(node));;

    while(1)
        {
        printf("repl> ");
        char *storage [30];
        char *tok;
        double my_double;

        char buffer[50];
        int pos = 0;
        fgets(buffer,sizeof(buffer),stdin);

        tok = strtok(buffer," ");



        while (tok != NULL)
    {
        if (strcmp(tok, "add") == 0) printf("YES!!");
        else if (strcmp(tok, "add\n") == 0) printf("YELZZ!!!");

        if (strcmp(tok, "quit") == 0) exit(1);
        else if (strcmp(tok, "quit\n") == 0) exit(1);

        if (strcmp(tok, "pop") == 0)
            {
                Pop(&head);
                break;
            }
        else if (strcmp(tok, "pop\n") == 0)
        {
            Pop(&head);
            break;
        }


         if (sscanf(tok, "%lf", &my_double) > 0)
         {
             Push(NULL, my_double, &head);
         }
         else
            Push(strdup(tok), 0, &head);

        //if(Sempty(head)) Push("::error::", 0, &head);

        tok = strtok(NULL," ");
    }
    Display(&head);
}

}

【问题讨论】:

  • 您的 Pop 函数是无效的,但您仍然从中返回一个值。 Thios 无法编译。
  • 是的,我正在测试它,它可以编译,但当然不能正常工作@MichaelWalz
  • @MannyO 您想从 pop 返回 2 个值,您可以更改 pop() 函数的签名吗?
  • 开启所有警告。至于问题 - 您可能必须实现一些序列化。
  • @Rohith 是的,你可以调整信号

标签: c linked-list stack


【解决方案1】:

你不能在 C 中重载函数。你已经有一个 Pop 函数可以从堆栈中弹出最顶层的节点。节点可以包含数字或字符串。您的 Display 函数显示节点的内容并正确测试节点中的数据类型。

你应该写一个函数,它接受一个节点作为参数,如果它是一个数字则返回假,如果它是一个字符串则返回真:

bool IsString(node *inp)
{
   return temp->valC != NULL ;
}

但是即使您可以在 C 中重载函数,您也不知道堆栈顶部的节点类型(数字或字符串)。如果你调用 Pop 函数返回一个字符串并且最上面的节点包含一个数字会发生什么?

只需弹出,然后找出节点是字符串还是数字并采取相应的行动。

【讨论】:

    【解决方案2】:

    您可以做的一件事是编写一个 void * 类型的指针,然后您可以稍后将它类型转换为您需要的类型。

    我举个例子,你可以从中得到一些想法来实现pop()

    void *check(int x)
    {
     static void *p;
     int a=5;
     char *c="abcd";
     if(x==1)
       return p=&a;
     else
       return p=c;
    }
    int main()
    {
      int * a;
      char * b;
      a=(int *)check(1);
      b=(char *)check(2);
      printf("%d %s",*a,b);
    }
    

    对于您的 pop(),您甚至可以添加标志作为参数,以了解返回的指针的类型,以在调用函数中进行类型转换。作为

     void * pop(node **head, int &flag)
    

    设置标志以指示返回指针的类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-06
      • 1970-01-01
      • 2014-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-30
      • 2014-12-30
      相关资源
      最近更新 更多