c - 单一函数可处理两种类型的链表

标签 c struct linked-list

我有两个链接列表:-

struct Struct_A_s {
int a;
struct  Struct_A_s *next;
}Struct_A;

struct Struct_B_s {
int a;
int b;
int c;
int d;
struct  Struct_B_s *next;
}Struct_B;

我已经有几个在 Struct_A 上运行的函数。 诸如此类的事情:

“Add_tail (Struct_A *)”、“Remove_tail(Struct_B *)”、“Add_node(Struct_A *,int pos)、Add_head 等已就位。

对我来说,我的要求是修改现有的函数,以便它们可以同时对 Struct_A 和 Struct_B 进行操作。

在 C 中,有没有一种方法可以传递 void 指针(或类似的东西)并编写一些通用代码来同时处理 Struct_A 和 Struct_B。 代码大小是这里的一个大问题。目前我看到的唯一选择是从头开始重写 Struct_B 的所有代码(链表操作)。

最佳答案

有几种方法可以解决这个问题。我确信其他人比我建议的更熟练。

  • 选项 A:传递一个 void 指针和某种数据类型指示,然后进行转换。
  • 选项 B:将两个指针组合成一个并集并传递。
  • 选项 C:将类型和 union 组合成一个结构并传递
  • 选项 D:使用更受尊重的 union 替代方案

一些示例代码...

enum DataType { TYPE_1, TYPE_2 };

struct Type1 { ... };
struct Type2 { ... };

union Data
{
    void*         addr;
    struct Type1* type1;
    struct Type2* type2;
}

struct Object
{
    DataType type;
    union Data data;
}

struct Thing
{
    DataType type;
    void* data;
}

void someFunc1( void* data, DataType type )
{
   switch( type )
   {
       case TYPE_1:
       {
           struct Type1* type1 = (struct Type1*)data;
           ...
           break;
       }
       case TYPE_2:
       {
           struct Type2* type2 = (struct Type2*)data;
           ...
           break;
       }
   }
}

void someFunc2( union Data* data, DataType type )
{
   switch( type )
   {
       case TYPE_1:
       {
           struct Type1* type1 = data->type1;
           ...
           break;
       }
       case TYPE_2:
       {
           struct Type2* type2 = data->type2;
           ...
           break;
       }
   }
}

void someFunc3( struct Object* object )
{
   switch( object->type )
   {
       case TYPE_1:
       {
           struct Type1* type1 = object->data.type1;
           ...
           break;
       }
       case TYPE_2:
       {
           struct Type2* type2 = object->data.type2;
           ...
           break;
       }
   }
}


void someFunc4( struct Thing* thing )
{
   switch( thing->type )
   {
       case TYPE_1:
       {
           struct Type1* type1 = (struct Type1*)thing->data;
           ...
           break;
       }
       case TYPE_2:
       {
           struct Type2* type2 = (struct Type2*)thing->data;
           ...
           break;
       }
   }
}

换个角度看...如果你有一个只需要 a 的方法,那么你可以做这样的事情...

void myFunc( int a ) { ... };

void someFunc3( struct Object* object )
{
    myFunc( object->type == TYPE_1 ? object->data.type1->a : object->data.type2->a );
}

更好的是...修改函数以接受对象并仅在底部进行区分...

void myFunc( struct Object* object )
{
   int* a;

   switch( object->type )
   {
       case TYPE_1:
       {
           a = &object->data.type1->a
           break;
       }
       case TYPE_2:
       {
           a = &object->data.type2->a;
           break;
       }
       default:
       {
           abort();
       }
   }

   // do work with a as though it were passed in as a pointer to int

   if( object->type == TYPE_2 )
   {
      // do additional work with the b, c, d elements, etc.
   }
}

关于c - 单一函数可处理两种类型的链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16426577/

相关文章:

c - typedef 可见性

c - 共享内存段中的链表

python - 链表 : How to remove odd numbers?

c++ - 在编译时不知道返回类型时如何避免向下转换?

局部变量地址可以保留在返回指针的函数中吗

在c中将文本文件转换为二进制文件

c# - 从 C# 使用 C 库的技巧

c - gcc 将自动调整结构大小

c - 使用 strtol() 的十六进制字符串转换给出错误的输出

c - Swift 使用 c 结构