我可以'扩展'C中的结构吗?

cha*_*m15 15 c struct

typedef struct foo_s {
    int a;
} foo;

typedef struct bar_s {
    foo;
    int b;
} bar;
Run Code Online (Sandbox Code Playgroud)

基本上我想做:

bar b;
b.a;
Run Code Online (Sandbox Code Playgroud)

我知道如果我在bar中命名了foo结构,我可以做b.foo_name.a,但我不想这样做.

有什么办法吗?

这个问题得到了各种不同的答案,所以让我解释一下这个问题.我想这样做的原因是因为我有一个我需要适应我的情况的库,这意味着我无法修改原始的struct decleration.此外,我需要做的就是在结构的开头添加1项(为什么开始?因为我有一个'object'结构,它可以处理项目中的所有结构).我可以像你提到的那样简单地嵌入结构但它真的很烦人,因为所有的引用都需要输入'variable-> image.location'那个'image'.键入十亿种类型真的很烦人.

wco*_*ran 28

显然这个功能已被添加到C11中,但是我无法访问最近年份的C编译器(> = GCC 4.6.2).

typedef struct foo {
  int a;
} foo;

typedef struct bar {
  struct foo;
  int b;
} bar;

int main() {
  bar b;
  b.a = 42;
  b.b = 99;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 正如链接文档中所解释的那样,这是一个 Microsoft 扩展,如果没有 `-fms-extensions` 标志,就不能在 GCC 和 clang 上编译。 (3认同)
  • 注意,这是有效的,因为在`bar`中,`struct foo`是匿名使用的(即没有变量名)。 (2认同)

Jou*_*nen 10

您可以使用指针,因为保证指向结构对象的指针指向其第一个成员.参见例如本文.

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

typedef struct foo_s {
    int a;
} foo;

typedef struct bar_s {
    foo super;
    int b;
} bar;

int fooGetA(foo *x) {
  return x->a;
}

void fooSetA(foo *x, int a) {
  x->a = a;
}

int main() {
  bar* derived = (bar*) calloc(1, sizeof(bar));
  fooSetA((foo*) derived, 5);
  derived->b = 3;
  printf("result: %d\n", fooGetA((foo*) derived));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,这对于呼叫者来说肯定更方便。我想证明 foo 函数的作者不必知道“真正的”结构是 foo 以外的东西。 (2认同)

Mah*_*esh 7

C你的方式不可能.但是你可以模仿具有foo成员变量的继承bar.

typedef struct bar_s {
    foo obj;
    int b;
} bar;

bar b;
b.obj.a = 10;
Run Code Online (Sandbox Code Playgroud)

  • 如果我没弄错的话,那就叫做[作文](http://en.wikipedia.org/wiki/Composition_over_inheritance). (7认同)
  • 我认为这就是OP*不*想要的;这是“明显的解决方案”。 (2认同)