Is it possible to have a linked list of different data types?

后端 未结 11 2114
独厮守ぢ
独厮守ぢ 2020-12-13 22:22

This is just another interview question.

Can we have a linked list of different data types, i.e. each element in a linked list can have different structure or union

11条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-13 23:11

    Yes, I do this by defining the list's element's value as a void pointer void*. In order to know the type stored in each element of the list I also have a .type field in there, so I know how to dereference what the pointer is pointing to for each element.

    struct node {
        struct node* next;
        int type;
        void* value;
    };
    

    Here's a full example of this:

    //                                                                                                                                                                                          
    // An exercise to play with a struct that stores anything using a void* field.                                                                                                              
    //                                                                                                                                                                                          
    
    #include 
    
    #define TRUE 1
    
    int TYPE_INT = 0;
    int TYPE_STRING = 1;
    int TYPE_BOOLEAN = 2;
    int TYPE_PERSON = 3;
    
    struct node {
      struct node* next;
      int type;
      void* value;
    };
    
    struct person {
      char* name;
      int age;
    };
    
    int main(int args, char **argv) {
    
      struct person aPerson;
      aPerson.name = "Angel";
      aPerson.age = 35;
    
      // Define a linked list of objects.                                                                                                                                                       
      // We use that .type field to know what we're dealing                                                                                                                                     
      // with on every iteration. On .value we store our values.                                                                                                                                
      struct node nodes[] = {
        { .next = &nodes[1], .type = TYPE_INT    , .value=1                   },
        { .next = &nodes[2], .type = TYPE_STRING , .value="anyfing, anyfing!" },
        { .next = &nodes[3], .type = TYPE_PERSON , .value=&aPerson            },
        { .next = NULL     , .type = TYPE_BOOLEAN, .value=TRUE                }
      };
    
      // We iterate through the list                                                                                                                                                            
      for ( struct node *currentNode = &nodes[0]; currentNode;  currentNode = currentNode->next) {
        int currentType = (*currentNode).type;
        if (currentType == TYPE_INT) {
          printf("%s: %d\n", "- INTEGER", (*currentNode).value); // just playing with syntax, same as currentNode->value                                                                        
        } else if (currentType == TYPE_STRING) {
          printf("%s: %s\n", "- STRING", currentNode->value);
        } else if (currentType == TYPE_BOOLEAN) {
          printf("%s: %d\n", "- BOOLEAN (true:1, false:0)", currentNode->value);
        } else if (currentType == TYPE_PERSON) {
            // since we're using void*, we end up with a pointer to struct person, which we *dereference                                                                                        
            // into a struct in the stack.                                                                                                                                                      
            struct person currentPerson = *(struct person*) currentNode->value;
            printf("%s: %s (%d)\n","- TYPE_PERSON", currentPerson.name, currentPerson.age);
          }
      }
    
        return 0;
    }
    

    Expected output:

    - INTEGER: 1
    - STRING: anyfing, anyfing!
    - TYPE_PERSON: Angel (35)
    - BOOLEAN (true:1, false:0): 1
    

提交回复
热议问题