引用在C方括号和索引而不是结构域。 - 和 - >?(referencing struc

2019-07-29 18:19发布

假设我有诸如的结构:

typedef struct
{
    char * string1;
    char * string2;
} TWO_WORDS;

这样,所有的领域都是同一类型的,而我的主要有

TWO_WORDS tw;

我可以引用字符串1与TW [0]和字符串2具有两个[1]? 如果是这样:

  • 是C标准的这一部分?
  • 我一定要在结构转换为数组第一?
  • 哪些是在内存中不同大小的领域是什么
  • 怎么样这是不同的类型,但同样大小字段?
  • 你可以做一个结构内的指针运算?
  • -

Answer 1:

我非常接近这个结构:

((char**)&tw)[0];

举个例子:

int main()
{
    typedef struct
    {
        char * string1;
        char * string2;
    } TWO_WORDS;

    TWO_WORDS tw = {"Hello", "World"};

    printf("String1: %s\n", ((char**)&tw)[0]);
    printf("String2: %s\n", ((char**)&tw)[1]);

    return 0;
}

它不能保证工作,因为编译器可以域之间添加填充物。 (许多编译器有一个#pragma将避免结构的填充)

为了回答您的每一个问题:

  • 是C标准的这一部分? 没有

  • 我一定要在结构转换为数组第一?

  • 哪些是在内存中不同大小的领域是什么
    这可以用更“邪恶”的铸造和指针运算来完成

  • 怎么样这是不同的类型,但同样大小字段?
    这可以用更“邪恶”的铸造和指针运算来完成

  • 你可以做一个结构内的指针运算?
    是的 (不能保证总是工作正如您所料,但结构只是一块内存,你可以用指针和指针的数学访问)



Answer 2:

作为@ouah所指出的,没有你不能做到这一点相当的方式。 但是,你可以:

typedef union
{ char *a[2];
  struct
  { char *string1;
    char *string2;
  } s;
} TWO_WORDS;

TWO_WORDS t;

t.a[0] = ...;
t.a[1] = ...;
t.s.string1 = ...;
t.s.string2 = ...;


Answer 3:

不,你不能使用索引访问结构数据成员,除非你采取具体步骤来效仿。

称为“指针到数据成员”特定的指针类型 - 在C ++中,这功能可通过使用C ++来仿真。 C语言没有这样的类型,但它可以反过来通过使用标准的被仿真offsetof宏和指针运算。

在您例如,它可能如下所示。 首先,我们准备一个特殊的偏移数组

const size_t TW_OFFSETS[] = 
  { offsetof(TWO_WORDS, string1), offsetof(TWO_WORDS, string2) };

此偏移阵列随后用于对组织结构成员索引访问

*(char **)((char *) &tw + TW_OFFSETS[i]); 
/* Provides lvalue access to either `tw.string1` or `tw.string2` depending on 
   the value of `i` */

它看起来并不漂亮(虽然它可以做成看起来使用宏更好),但是这是在C的方式

例如,我们可以定义

 #define TW_MEMBER(T, t, i) *(T *)((char *) &(t) + TW_OFFSETS[i])

并且在代码中使用它

 TW_MEMBER(char *, tw, 0) = "Hello";
 TW_MEMBER(char *, tw, 1) = "World";

 for (int i = 0; i < 2; ++i)
   printf("%s\n", TW_MEMBER(char *, tw, i));

注意,这种方法是从溶液中存在的基础上重新解释结构的严重问题,免费char*[2]数组(它是否是通过工会或通过铸造完成regradless)。 后者是一个黑客,从一般无效正式点是非法的。 该offsetof为基础的解决方案是完全有效的,合法。



Answer 4:

我可以引用字符串1与TW [0]和字符串2具有两个[1]?

不,你不能在C, tw是一个结构不是一个指针。

所述的限制[]操作者所需要的操作数是指针类型中的一个。

要访问string1 ,你可以用这个表达式: tw.string1



Answer 5:

不,你不能这样做,在C,您可以通过它们的名字只访问结构成员的温度。

你可以做的是建立一个有指向相同的字符串作为那些在你的结构数组,然后使用索引的数组。

但是,你为什么要这么做? 什么是你实际上是想用这个来解决这个问题?



Answer 6:

您可以使用((char **)&tw)[0]做到这一点,如果你真的想要,但不是tw[0]



Answer 7:

如果一个人有一个struct ,其与该都是相同类型的字段开始,一个可宣布union ,其包括该类型的结构以及相应的字段类型的阵列。 如果一个这样做,读取或写入的阵列的元素将读或写相应的结构构件。 这种行为将工作在我所知道的一切的实现,我相信这是便携式,如果所有字段的大小相同。

struct quad_int {int n0; int n1; int n2; int n3;}
union quad_int_union {struct pair p; int n[4];}

union quad_int_union my_thing;

my_thing.n[0] is synonymous with my_thing.p.n0
my_thing.n[1] is synonymous with my_thing.p.n1
etc.



文章来源: referencing struct fields in c with square brackets and an index instead of . and ->?
标签: c struct