2013-03-27 45 views
1

我使用位域的結構來訪問像素中的每個顏色通道,問題是我經常有代碼以相同的方式應用到每個通道,但是因爲我不能只是迭代對於CI中結構的成員最終會爲每個成員擁有3份相同的代碼,或者更不方便地使用switch-case語句。宏來遍歷結構成員

我想如果我可以使用一個宏,以便我可以通過提供一個數字訪問一個成員,理想情況下會使.CHAN(i)成爲.r,.g或.b取決於整數變量i是否包含0,1或2.除了我不知道如何製作這樣一個宏,或者即使這是可能的。

一個細節,但每個成員是像12位,而不是8所期望的,所以我不能把它變成一個數組或與指針聯合。此外,X-Macros不會這樣做,因爲在對另一個頻道執行相同操作之前,我經常需要爲每個頻道執行許多操作,換句話說,通過每個成員的for循環可以包含比僅僅一行更多的內容。

編輯:下面是一些代碼,首先將結構:

typedef struct 
{ 
    uint32_t b:12; 
    uint32_t g:12; 
    uint32_t r:12; 
    uint32_t a:12; 
} lrgb_t; 

現在的例子就是我的問題看起來像代碼:

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 
} 
+5

爲什麼不給我們展示一些代碼,使討論更具體? – NPE 2013-03-27 12:35:46

回答

2

在評論中指出,這並未真的沒有解決OP的問題,因爲他的結構中的成員是位域,不會與數組對齊。儘管我會保留答案,希望對某人仍然有用。

我認爲union是你想要的。 你可以寫你的結構如

union 
{ 
    struct 
    { 
     float r; 
     float g; 
     float b; 
    }rgb; 
    float channel[3]; 
} color; 

這樣的結構會在內存中的同一個地方浮動[3],可以有效地訪問相同的成員或是結構成員或作爲數組中的元素。

您可能需要查看確切的語法,但您明白了。

+0

-1 Union爲所有成員使用相同的內存。根本不是退出。 – Alex 2013-03-27 12:37:30

+0

@Alex更新了我的意思 – filipe 2013-03-27 12:40:07

+0

的更好的解釋好吧,現在它使得sence。刪除downvote。 – Alex 2013-03-27 12:48:42

1

一種可能性是在重複的代碼封裝成函數,然後調用它爲每個信道的:

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; 
} 
0

閱讀提示宏,添加我做了一些改變,以我的代碼後

#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,那麼如果'ic'是2,那麼成員'.r'將被操縱,然後'.g'將被操縱,並且如果'ic'既不是1也不是2,那麼'.b'將被操縱,因爲這個假設你必須確保'ic'被正確設置,否則你可以使用panco [i] .b和pancol [i + 1] .b的值進行擰緊。你的代碼應該看起來像下面的代碼,但如果你有任何問題,你很可能需要稍微調整一下宏。

//#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 
} 

另外請注意,我的宏將做你的開關案件完全一樣的事情。唯一的區別是,它是在一個宏中定義的,我試圖做的一點是,開關盒與宏之間的區別純粹是可視的。