c - ty如何像数组一样定义可通过下标访问的结构体 union ?就像在 GLSL 中一样

标签 c arrays struct types unions

很久以前,我一定在某个地方见过 GLSL vector ,现在我们有一个涉及 OpenGL 的大学项目(他们实际上说的是 2.4,而不是 3.x 或 4.x)。然而,它们似乎与 glsl 密切相关,我希望在原始 C 中拥有相同的东西: structs 与 x/ry/gb 也可能是 z。我尝试为每个 vec2vec3vec4 进行一个定义,内部使用 int (因为 OpenGL 确实有使用 int 的函数,而不是 long int ,我是说我自己的定点可能更快或更简单),与他们的 unsigned 对应(因为老师说最好使用正值来提高可读性,可读性和更好的直觉)发生了什么,同时使用翻译进行居中,而我更喜欢以算术方式更改坐标,以便可以在编译时进行调整)。这会占用很多空间,因此我使用宏来定义它,所以最后我还将包含一个无宏示例版本,这样您就可以知道这对您来说是否难以理解。

主要问题是我无法将这些结构传递给以数组/指针作为参数的函数(因此我确实将 union 成员定义为 .ptr 以进行更简单的转换),也不能我显然在它们上使用了数组下标。我想我记得在某处看到过一种用数组定义 struct 或 union 的方法,其中 structunion 可以是直接下标来访问该数组,但我找不到它了……也许它是一些 GNU 扩展,但我不确定。

尽管如果没有办法,并且我仍然想要可读性,我仍然可以选择仅使用基本数组定义我的类型,然后 union dim { x, y, z } 并访问例如 my_vec[x] 。但我想知道是否也可以使用相同类型的 my_vec.x。代码如下:

typedef unsigned int uint;
#define VEC_TYPEDEF(type, type_name, n)                        \
  typedef union type_name ## vec ## n ## _t                    \
  {                                                            \
    struct                                                     \
    {                                                          \
      type x;                                                  \
      type y;                                                  \
      VEC_THIRD(type, z)                                       \
      VEC_FORTH(type, w)                                       \
    };                                                         \
    struct                                                     \
    {                                                          \
      type s;                                                  \
      type t;                                                  \
      VEC_THIRD(type, p)                                       \
      VEC_FORTH(type, q)                                       \
    };                                                         \
    struct                                                     \
    {                                                          \
      type r;                                                  \
      type g;                                                  \
      VEC_THIRD(type, b)                                       \
      VEC_FORTH(type, a)                                       \
    };                                                         \
    type ptr[n];                                               \
  } type_name ## vec ## n
#define VEC_THIRD(type, var) type var;
#define VEC_FORTH(type, var) type var;
VEC_TYPEDEF(int,, 4);
VEC_TYPEDEF(uint, u, 4);

#undef VEC_FORTH
#define VEC_FORTH(type, var)
VEC_TYPEDEF(int,, 3);
VEC_TYPEDEF(uint, u, 3);

#undef VEC_THIRD
#define VEC_THIRD(type, var)
VEC_TYPEDEF(int,, 2);
VEC_TYPEDEF(uint, u, 2);

它给出的一个例子:

typedef union uvec3_t
{
  struct
  {
    unsigned int x;
    unsigned int y;
    unsigned int z;
  };
  struct
  {
    unsigned int s;
    unsigned int t;
    unsigned int p;
  };
  struct
  {
    unsigned int r;
    unsigned int g;
    unsigned int b;
  };
  unsigned int ptr[3];
} uvec3;

目前,如果尝试使用类似 my_vect.x = my_other_vect[0]; (使用 uvec3 my_vect, my_other_vect;),gcc 只会发出“错误:下标值既不是数组也不是指针也不是 vector ”:/

最佳答案

为此,您首先需要对结构进行打包,以便没有填充 然后你可以像这样使用它

* (<TYPE> *) ((void *)my_other_vect + sizeof(<TYPE>)*offset);

例如 对于 int 类型并获取 x 你可以这样做

my_vect.x = * (int *) ((void *)my_other_vect + sizeof(int)*0);
my_vect.y = * (int *) ((void *)my_other_vect + sizeof(int)*1);

关于c - ty如何像数组一样定义可通过下标访问的结构体 union ?就像在 GLSL 中一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49574384/

相关文章:

arrays - 如何使用 Monk 在 MongoDB 中插入带有子文档数组元素的文档

go - 一段任意结构的接口(interface)用作函数参数(golang)

c++ - 如何在 C++ 中的结构中设置一个 int 数组

c - 使用 C 从文件中读取数据以创建数组

c - 在内核中高效分配内存

c - 将静态变量作为参数传递给函数

c - 无变量字符串反转

arrays - 软件测试--正交表测试算法

arrays - 给定两个数组 A 和 B ,找到两个数组中的第一个数字,使得替换它们使得数组 A 的总和等于数组 B 的总和

arrays - 如何在 Matlab 中将结构体的叶子作为向量返回?