是否可以使用值大小不同的元素(结构)数组?
我面临的问题是我不知道如何访问元素,因为它需要强制转换。 “数组”只包含指向结构的指针。因此我决定选择无效**。由于并非每个元素都属于同一类型,因此类型也需要存储在数组中,以便在不进行粗略猜测的情况下知道要转换的内容。但这听起来效率不高。有没有更有效的方法?
答案 0 :(得分:10)
不,在C中,数组的每个元素必须是相同的类型(因此也是相同的大小)。
您可能需要添加另一个抽象层,在这种情况下,您需要使用它具有的类型来注释元素,例如你可以创建一个看起来像:
的结构数组enum ElemType {
TypeNull,
TypeFoo,
TypeBar
];
struct Elem {
enum ElemType type;
void *realElem;
};
您必须使用插入的实际类型更新'type',并在读取数组时对其进行决策,并将指针存储到'realElem'成员中的实际元素。
struct Elem arr[42];
...
switch(arr[k].type) {
case TypeFoo:
handleFoo(arr[k].realElem);
break;
...
}
答案 1 :(得分:6)
如果您不喜欢演员表,您可以随时使用联合(以及一个标志来指示联合应该被解释为哪种类型)
#include <stdio.h>
typedef struct {
int a;
} A;
typedef struct B {
double b;
} B;
typedef struct C {
char c[20];
} C;
typedef enum {
TypeA,
TypeB,
TypeC,
} type;
typedef struct {
type type;
union { A*a; B*b; C*c; } p;
} TypedPointer ;
void foreach (TypedPointer* list, void (*fn)(TypedPointer))
{
while (list->p.a) {
fn(*list);
++list;
}
}
void print_member (TypedPointer ptr)
{
switch (ptr.type) {
case TypeA: printf("A (%d)\n", ptr.p.a->a); break;
case TypeB: printf("B (%f)\n", ptr.p.b->b); break;
case TypeC: printf("C (%s)\n", ptr.p.c->c); break;
}
}
int main ()
{
A a = { .a = 42 };
B b = { .b = 1.01 };
C c = { .c = "Hello World!" };
TypedPointer ptrs[] = {
{ .type = TypeA, .p.a = &a },
{ .type = TypeB, .p.b = &b },
{ .type = TypeC, .p.c = &c },
{ .type = 0, .p.a = 0} };
foreach(ptrs, print_member);
return 0;
}
答案 2 :(得分:2)
不,C数组具有必须在编译时知道的常量大小。但是你可以通过使用指针和动态分配来解决这个问题。
这里的问题不是效率,而是类型安全。转换没有运行时性能成本,它只是与编译器通信的机制,要求它“信任你”并假设在一系列位后面有某种类型。我们谈的是安全问题,因为如果你错了,那么任何事都可以在运行时发生。
在C(静态语言)中构造不同类型的数组是不可能的。你可以做的是构造一个某个结构的数组,但是该结构保存指向不同大小的对象的指针。例如,让struct保存一个char*
指针,在这种情况下,每个对象都包含一个长度或另一个长度的字符串,因此具有可变大小(就运行时使用的总内存而言,不是就连续空间而言)使用)。
如果您希望每个对象的行为与其他对象不同,那么您可以通过使用函数指针数组来模拟多态,然后添加一个指向任何函数的结构的函数指针必要时。
答案 3 :(得分:0)
为此,我们使用指向实际对象的指针数组。
指针的大小都相同。
他们指向的对象可以是不同的大小。
“歧视联盟”对此很有效。
typedef struct { ... } this_type;
typedef struct { ... } that_type;
typedef struct {
int subtype;
union {
this_type this;
that_type that
}
} discriminated_union;
指向discriminated_union
的数组指针运行良好。
答案 4 :(得分:0)
Casts效率不高,因为它们只是告诉计算机如何解释内存区域。当它们被编译为汇编时,编译器将创建根据需要解释内存区域的程序集。