C中的通用结构

时间:2017-10-22 00:27:11

标签: c linked-list

我使用IEnumerable返回值int / double时出现问题。

例如:

void*

但该功能不适用于#include "stdio.h" #include "stdlib.h" typedef struct list { void *info; struct list *prox; } List; typedef struct queue { List* begin; List* end; } Queue; Queue* create_queue (void) { Queue* f = (Queue*) malloc(sizeof(Queue)); f->begin = f->end = NULL; return f; } Queue* insert_queue_end (List* end, void* v) { List* p = (List*) malloc(sizeof(List)); p->info=v; p->prox=NULL; if(end!=NULL) { end->prox=p; } return p; } double queue_empty_double(Queue* f) { return (f->begin==NULL); } double queue_remove_double(Queue* f) { List* t; double v; if(queue_empty_double(f)) { exit(1); } t=f->begin; v=*((double*)(t->info)); f->begin=t->prox; if (f->begin==NULL) { f->end = NULL; } free(t); printf("%.3lf\n",v); } void insert_queue(Queue* f, void* v) { f->end = insert_queue_end(f->end,v); if(f->begin==NULL) { f->begin=f->end; } } void print_queue_double(Queue* f) { List* i; for(i=f->begin;i!=NULL;i=i->prox) printf("%.3lf\n",*((double*)i->info)); } int main () { Queue* f; f = create_queue(); char ent1[100]; double n1; scanf("%s",ent1); while(ent1[0]!='X') { if(ent1[0]=='E') { scanf("%lf",&n1); insert_queue(f,&n1); scanf("%s",ent1); } else if (ent1[0]=='D') { queue_remove_double(f); scanf("%s",ent1); } } } 值,只有double

另一个新代码,现在代码可以打印double但是在函数queue_remove_double中存在问题,她应该从队列中删除第一个元素并打印第一个元素。我相信这个问题来自泛型结构,因为该函数删除了第一个并将其打印在普通结构中。

int

3 个答案:

答案 0 :(得分:1)

它适用于codeblocks ide。指定* info的类型以了解如何转换指针。

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

typedef enum DataTypes {
  INTEGER,
  FLOAT,
  DOUBLE,
  CHAR
} DataType;

typedef struct list {
   void *info;
   struct list *next;
   DataType type;
} List;


List* create_list(void *firstInfo, DataType firstType)
{
   List *f=(List*)malloc(sizeof(List));
   f->info=firstInfo;
   f->type=firstType;
   f->next=NULL;
   return f;
}

List* insertion(List *end, void *data, DataType type)
{
    List *p=(List*)malloc(sizeof(List));
    p->info=data;
    p->next=NULL;
    p->type=type;
    if(end != NULL)
    {
        end->next=p;
    }
    return p;
}

void showTheList(List **theBase)
{
    List *run=*theBase;

    while(run != NULL)
    {
        switch(run->type)
        {
            case INTEGER:
                printf("Showing the value: %d \n",*((int*)run->info));
                break;
            case FLOAT:
                printf("Showing the value: %f \n",*((float*)run->info));
                break;
            case DOUBLE:
                printf("Showing the value: %lf \n",*((double*)run->info));
                break;
            default:
                printf("Showing the value: %c \n",*((char*)run->info));
        }
        run=run->next;
    }
}

List* getEnd(List **theBase)
{
    List *run=*theBase;
    while(run->next != NULL)
        run=run->next;
    return run;
}

void clearList(List **theBase)
{
    List *run=(*theBase)->next;
    free(*theBase);
    while(run != NULL)
    {
        *theBase=run;
        run=run->next;
        free(*theBase);
    }
    *theBase=NULL;
}

int main(void)
{
   List *theList=NULL;
   int valA=10;
   float valB=1.25;
   double valC=23.45;
   char valD='C';

   theList=create_list(&valA,INTEGER);

   insertion(getEnd(&theList),&valB,FLOAT);
   insertion(getEnd(&theList),&valC,DOUBLE);
   insertion(getEnd(&theList),&valD,CHAR);

   showTheList(&theList);

   clearList(&theList);
   if(theList == NULL)
     printf("Ok, all operations realized !");

   return 0;
}

答案 1 :(得分:0)

尝试使用带指针的强制转换。你需要知道指针的类型。

void print_queue_double(Queue* f) 
{
    List* i;
    for(i=f->begin;i!=NULL;i=i->prox)
    printf("%.3lf\n",*((double*)i->info));
}

答案 2 :(得分:0)

你的问题是指针。如果使用n1,则void *始终包含最后一个n1值,因为它指向n1。然后当你释放列表(queue_remove_double)时,总是显示n1的值(最新的)......

一些解决方案:
(1)阵列 - 如下所示 - 是有限的....
(2)带有变量副本的新双值(malloc double) - “ilimited”(你的记忆限制......)

在新的双重案例中:

List* insert_queue_end (List* end, void* v) {

  List* p = (List*) malloc(sizeof(List));
  double *data=(double*)malloc(sizeof(double)); /*New double new address*/

  *data=*((double*)v); /*Copy the VALUE and not the address to new double in new and fixed address*/
  /*void* points to a new double with a new address in memory */
  p->info=data;

  p->prox=NULL;
  if(end!=NULL) {
    end->prox=p;
  }
  return p;
 }

不要忘记在删除功能中从新的双重释放内存!

一些解决方案:
解决方案1 ​​ - 双打数组:

#include "stdio.h"
#include "stdlib.h"

typedef struct list {

  void *info;
  struct list *prox;

} List;

typedef struct queue {

  List* begin;
  List* end;

} Queue;


Queue* create_queue (void) {

 Queue* f = (Queue*) malloc(sizeof(Queue));
 f->begin = f->end = NULL;
 return f;

}

/*Yes the type of return is List* and not Queue* - check your code */    
 List* insert_queue_end (List* end, void* v) {

  List* p = (List*) malloc(sizeof(List));

  ///If you want create a new double this is the local - don't use the same address in v !
  p->info=v;

  p->prox=NULL;
  if(end!=NULL) {
    end->prox=p;
  }
  return p;
 }

double queue_empty_double(Queue* f) {
   return (f->begin==NULL);
}


double queue_remove_double(Queue* f) {

   List* t;
   double v;
   double isRemoved=0;

  if(queue_empty_double(f)) {
    exit(1);
  }

   t=f->begin;
   v=*((double*)(t->info));
   f->begin=t->prox;
   if (f->begin==NULL) {
     f->end = NULL;
   }
    free(t);
    printf("%.3lf\n",v);

}


  void insert_queue(Queue* f, void* v) {

    f->end = insert_queue_end(f->end,v);
    if( f->begin==NULL) {
    f->begin=f->end;
  }

 }

void print_queue_double(Queue* f) {

  List* i;
  for(i=f->begin;i!=NULL;i=i->prox)
  printf("%.3lf\n",*((double*)i->info));

  }


 int main () {
   Queue* f;
   f = create_queue();
   char ent1[100];
   ///One Double Allocated - only one address in memory !!!
   ///double n1;

   double listOfDoubles[20]; ///All doubles allocated and one per one have a address in memory !!!
   int countDoubles=0;


   scanf("%s",ent1);
   while(ent1[0]!='X' && countDoubles < 20)
   {
     if(ent1[0]=='E') {

        ///IN YOUR CODE:
        ///Fill the same one double...
        ///scanf("%lf",&n1);

        ///Testing new code
        scanf("%lf",&listOfDoubles[countDoubles]); ///a new double with your address

        ///IN YOUR CODE:
        ///The same address of one variable. The same result.
        ///Remember void * is a pointer and use the address of n1, and then, print the most recent &n1 content...
        ///insert_queue(f,&n1);

        ///A new double in a new address, the content is not equal
        insert_queue(f,&listOfDoubles[countDoubles]);

        countDoubles++;
    }
    else if (ent1[0]=='D') {
        ///free the address and decrement the index of array to reuse a double
        queue_remove_double(f);
        countDoubles--;
    }
    else
    {
        ///Print the list - and see the result "debug"
        print_queue_double(f);
    }
    scanf("%s",ent1);

  }
  free(f);

}

一些解决方案:
解决方案2 - 带有值副本的新双精度

#include "stdio.h"
#include "stdlib.h"

typedef struct list {

  void *info;
  struct list *prox;

} List;

typedef struct queue {

  List* begin;
  List* end;

} Queue;


Queue* create_queue (void) {

 Queue* f = (Queue*) malloc(sizeof(Queue));
 f->begin = f->end = NULL;
 return f;

}

 /*Yes the type of return is List* and not Queue* check your code */    
 List* insert_queue_end (List* end, void* v) {

  List* p = (List*) malloc(sizeof(List));
  double *data=(double*)malloc(sizeof(double)); /*New double new address*/

  *data=*((double*)v); /*Copy the VALUE and not the address to new double in new and fixed address*/
  /*void* points to a new double with a new address in memory */
  p->info=data;

  p->prox=NULL;
  if(end!=NULL) {
    end->prox=p;
  }
  return p;
 }

double queue_empty_double(Queue* f) {
   return (f->begin==NULL);
}


double queue_remove_double(Queue* f) {

   List* t;
   double v;
   double isRemoved=0;

  if(queue_empty_double(f)) {
    exit(1);
  }

   t=f->begin;
   v=*((double*)(t->info));
   f->begin=t->prox;
   if (f->begin==NULL) {
     f->end = NULL;
   }
    free(t->info); ///free the double
    free(t);
    printf("%.3lf\n",v);

}


  void insert_queue(Queue* f, void* v) {

    f->end = insert_queue_end(f->end,v);
    if( f->begin==NULL) {
    f->begin=f->end;
  }

 }

void print_queue_double(Queue* f) {

  List* i;
  for(i=f->begin;i!=NULL;i=i->prox)
  printf("%.3lf\n",*((double*)i->info));

  }


 int main () {
   Queue* f;
   f = create_queue();
   char ent1[100];

   double n1;


   int countDoubles=0;


   scanf("%s",ent1);
   while(ent1[0]!='X' && countDoubles < 20)
   {
     if(ent1[0]=='E') {

        scanf("%lf",&n1);
        insert_queue(f,&n1);
    }
    else if (ent1[0]=='D') {
        queue_remove_double(f);
    }
    else
    {
        ///Print the list - and see the result "debug"
        print_queue_double(f);
    }
    scanf("%s",ent1);

  }
  free(f);

}