首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于迭代结构成员的宏

用于迭代结构成员的宏
EN

Stack Overflow用户
提问于 2013-03-27 20:34:44
回答 3查看 1.4K关注 0票数 1

我使用位域的结构来访问像素中的每个颜色通道,问题是我的代码经常以相同的方式应用于每个通道,但因为我不能在C中迭代结构的成员,所以最终每个成员都有3个相同代码的副本,或者更不方便的是必须使用switch-case语句。

我想,如果我可以使用一个宏,这样我就可以通过提供一个数字来访问一个成员,理想情况下,一个宏会使.CHAN(i)成为.r,.g或.b,这取决于整数变量i是否包含0,1或2。除了我不知道如何创建这样一个宏,或者即使这是可能的。

一个细节,但每个成员大约是12位,而不是人们期望的8位,所以我不能简单地将其转换为数组或具有指针的并集。此外,X-Macros不会这样做,因为我经常需要在对另一个通道执行相同的操作之前对每个通道执行许多操作,换句话说,用于遍历每个成员的for循环可以包含比一行多得多的内容。

编辑:下面是一些代码,首先是struct:

代码语言:javascript
复制
typedef struct
{
    uint32_t b:12;
    uint32_t g:12;
    uint32_t r:12;
    uint32_t a:12;
} lrgb_t;

下面是我的问题在代码中的示例:

代码语言:javascript
复制
for (ic=0; ic<3; ic++)
{
    for (i=0; i<curvecount; i++)
    {
        curve[i].p0.x = (double) i;
        curve[i].p3.x = (double) i+1.;

        switch (ic)     // this is what I'm trying to eliminate
        {
            case 0:
                curve[i].p0.y = pancol[i].r / 4095.;
                curve[i].p3.y = pancol[i+1].r / 4095.;
                break;
            case 1:
                curve[i].p0.y = pancol[i].g / 4095.;
                curve[i].p3.y = pancol[i+1].g / 4095.;
                break;
            case 2:
                curve[i].p0.y = pancol[i].b / 4095.;
                curve[i].p3.y = pancol[i+1].b / 4095.;
                break;
        }
        // Ideally this would be replaced by something like this, CHAN() being an hypothetical macro
        // curve[i].p0.y = pancol[i].CHAN(ic) / 4095.;
        // curve[i].p3.y = pancol[i+1].CHAN(ic) / 4095.;
    }

    ... // more stuff that ultimately results in a bunch of pixels being written, channel after channel
}
EN

回答 3

Stack Overflow用户

发布于 2013-03-27 20:36:41

正如评论中指出的,这并没有真正解决OP的问题,因为他的struct上的成员是不会与数组对齐的位域。不过,我会把答案留在这里,希望它对某些人仍然有用。

我想union就是你想要的。您可以编写结构,如下所示

代码语言:javascript
复制
union
{
   struct
   {
       float r;
       float g;
       float b;
   }rgb;
   float channel[3];
} color;

这样,结构将与float3位于内存中的相同位置,并且您可以有效地作为结构成员或数组中的元素访问相同的成员。

您可能需要查找确切的语法,但是您已经明白了。

票数 2
EN

Stack Overflow用户

发布于 2013-03-27 20:41:17

一种可能是将重复的代码包装到一个函数中,然后为每个通道调用它:

代码语言:javascript
复制
typedef struct {
  int r:12;
  int g:12;
  int b:12;
} Pixel;

int inc(int val) {
  return val + 1;
}

int main(void) {
  Pixel p = {0, 0, 0};
  p.r = inc(p.r);
  p.g = inc(p.g);
  p.b = inc(p.b);
  return 0;
}
票数 1
EN

Stack Overflow用户

发布于 2013-03-27 21:56:14

在阅读了您添加的代码后,我对建议的宏进行了一些更改

代码语言:javascript
复制
#define CHAN(ic) \
(ic == 1) ? curve[i].p0.y = pancol[i].r / 4095; curve[i].p3.y = pancol[i+1].r / 4095; : \
(ic == 2) ? curve[i].p0.y = pancol[i].g / 4095; curve[i].p3.y = pancol[i+1].g / 4095; : \
curve[i].p0.y = pancol[i].b / 4095; curve[i].p3.y = pancol[i+1].b / 4095;

宏CHAN(ic)将对'ic‘求值,以便决定操作哪个成员。如果'ic‘是1,那么成员'.r’将被操纵如果'ic‘是2,那么'.g’将被操纵,如果'ic‘既不是1也不是2,那么'.b’将被操纵,因为这个假设你必须确保'ic‘被正确设置,否则你可能会破坏pancoi.b和pancoli+1.b的值。你的代码应该看起来像下面这样,但你很可能需要调整一下宏,让我知道如果你有任何问题。

代码语言:javascript
复制
//#define CHAN(ic) here

for (ic=0; ic<3; ic++)
{
  for (i=0; i<curvecount; i++)
  {
     curve[i].p0.x = (double) i;
     curve[i].p3.x = (double) i+1.;
     CHAN(ic)
  }
  ... // more stuff that ultimately results in a bunch of pixels being written, channel after channel
}

还请注意,我的宏将做与您的切换情况完全相同的事情。唯一的区别是它是在宏中定义的,我试图说明的一点是,切换用例和宏之间的区别纯粹是可视的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15658916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档