2013-06-25 39 views
0

我有typedef結構框,以便盒BOX1,箱BOX2等 結構體的成員是長度,寬度,高度等關於Çtypedef結構

typedef struct 
{ 
    int width; 
    int height; 
} box; 

box box1; 
box box2; 

如何創建一個功能的多個實例對每個 框實例的所有寬度成員進行操作?我的困惑是如何將指針傳遞給在所有框的實例上工作的typedef結構成員 。我知道如何將一個指針傳遞給特定的 實例成員一樣box1.width但如何通過.WIDTH然後做

box1.width=value; 
box2.width=value; 
box3.width=value; 

函數內?

+0

你不能陣列。沒有全局。但不要打擾。 –

+0

'typedef'只給結構賦予一個新的名字。你可以用它做任何事情都沒有。 – Elazar

+0

爲什麼不使用數組? 'SetWidth(size_t arraySize,box array [],int desiredWith)'? – Dai

回答

3

您可能想考慮使用數組而不是大量單獨的實例,例如,或者,如果你真的想由於某種原因迭代大量不同的盒子變量,那麼你可以初始化一個指針數組,例如,如果你真的想迭代大量不同的盒子變量,那麼你可以初始化一個指針數組,例如,

Box box1; // 3 separate Box variables 
Box box2; 
Box box3; 

Box *boxes[3] = { &box1, &box2, &box3 }; 
           // array of pointers to box1, box2, box3 

for (b = 0; b < 3; b++)   // set `width` field of all boxes to `value` 
    boxes[b]->width = value; 
+1

我會建議創建一個指針數組的選項,以防有現有的盒子要迭代。 – Elazar

+0

@Elazar:好點 - 問題不是很清楚,所以我會將其添加爲選項。 –

+0

我實際上正在做的是將實例struct成員值存儲到eeprom。我只是試圖編寫一個函數,可以將來自每個實例的所有相同成員一起存儲。感謝所有的建議。我會給他們一個旋轉。 –

0

看來你所要求的成員指針,但這些都是C++的功能(他們可以offsetof雖然你可能碰上嚴格走樣問題進行仿真)。除非您要求.width影響所有box的實例,而沒有指定具體的實例。在那種情況下,沒有答案。這將是這個樣子:

// C++ ahead 

struct box 
{ 
    int width; 
    int height; 
}; 

box boxes[3]; 

void setGlobalBoxesValue(int value, int box::*member) 
{ 
    for(unsigned int i = 0; i < sizeof(boxes)/sizeof(boxes[0]); ++i) 
     boxes[i].*member = value; 
} 

int main(int, char**) 
{ 
    setGlobalBoxesValue(4, &box::width); 
    setGlobalBoxesValue(3, &box::height); 
    return 0; 
} 

邪惡çoffsetof變種:

// C emulation (not typesafe) 

#include <stddef.h> 
#include <string.h> 

typedef struct 
{ 
    int width; 
    int height; 
} box; 

box boxes[3]; 

void setGlobalBoxesValue(int value, size_t memberOffset) 
{ 
    for(unsigned int i = 0; i < sizeof(boxes)/sizeof(boxes[0]); ++i) 
     memcpy((char*)(boxes+i) + memberOffset, &value, sizeof(value)); 
} 

int main(int, char**) 
{ 
    setGlobalBoxesValue(4, offsetof(box, width)); 
    setGlobalBoxesValue(3, offsetof(box, height)); 
    return 0; 
} 

如果你只是想同樣的操作適用於箱的多個實例,把它們放在一個數組和循環遍歷該數組(指針數組,如果它們分佈在內存中)。

1

在可以附加指針的typedef(或結構體)中,不存在字段width。該字段僅在物理上存在於該類型的具體對象中。所以,你不能有一個指向結構體的width的指針。您只能有指向box1.widthbox2.width等的指針。

不可能以某種方式編寫一個函數,它將在所有現有對象中改變width。更確切地說,不可能編寫一個函數,以某種方式神奇地枚舉該類型的所有現有對象,並在其中更改字段width。你有責任告訴你的函數你想改變哪些對象。

無論如何,你想要做什麼?


如果你想寫將運行時間與特定區域來設定,如果可以在C通過補償來實現參數化一個「二傳手」的作用。例如

void set_value(box *box, size_t offset, int value) { 
    *(int *) ((char *) box + offset) = value; 
} 

box box1; 
box box2; 
box box3; 

void set_values(size_t offset, int value) 
{ 
    set_value(&box1, offset, value); 
    set_value(&box2, offset, value); 
    set_value(&box3, offset, value); 
} 

現在呼籲

set_values(offset_of(box, width), 42); 

將在box1box2box3設置寬度以42,同時呼籲

set_values(offset_of(box, height), -5); 

將這些對象設置的高度,以-5

但是,您有責任確保函數知道哪些對象必須更改。在上面的例子中,我只是將它們聲明爲文件範圍變量。在現實生活中,通常情況下不可能。

+0

由於存在違反嚴格別名規則的風險,我不建議像'*(int *)((char *)box + offset)那樣進行類型竄改 – Joe

+0

@Joe:這裏沒有類型雙關。將int對象作爲int對象訪問不構成類型雙關。通過相當複雜的指針算術進行訪問的事實不會改變它。 – AnT

+0

直到有人有使用該函數設置浮動成員的好主意(不是任何人都應該......) – Joe

0

您不能將width字段本身傳遞給函數。但是,您可以在結構中傳遞它的偏移量。這是一個「髒」的伎倆,有時用於低級編程,但我不建議您在沒有很好理由的情況下使用它。

另一種選擇是使用宏。這可能是一個壞主意太多,但這裏的如何:

#define assign(field, value) \ 
    do { \ 
     box1.field = value; \ 
     box2.field = value; \ 
     box3.field = value; \ 
    } while (0) 

,並使用它像這樣:

assign(width, 5); 

如果你不知道什麼是框提前,你可以結合起來陣列解決方案在這裏建議。

0

我不知道我理解你的問題,但

我怎樣才能創建一個對 每箱實例的全部寬度構件進行動作的功能?我的困惑是如何將指針傳遞給一個 typedef結構成員,它可以在所有框的實例中工作。我知道 如何將一個指針傳遞給特定的實例成員一樣box1.width 但如何通過.WIDTH,然後通過創建一個函數,它的類型定義爲參數做

您可以訪問的寬度結構

void foo(box* p) 
{ 
    p->width .. do something 
... 
} 

,或者如果你的意思是傳遞箱

void foo(box* p, int count) 
{ 
    for (int i = 0; i < count; ++i) 
    { 
    p[i]->width .. do something 
    ... 
    } 
}