2015-11-06 78 views
0

我在庫中有兩個結構體,我無法更改。 p.e:使struct數組指向另一個struct Array

struct{ 
    uint8_t test; 
    uint8_t data[8]; 
}typedef aStruct; 

struct{ 
    uint8_t value; 
    uint8_t unimportant_stuff; 
    char data[8]; 
}typedef bStruct; 

aStruct a; 
bStruct b; 

在我的應用程序中有一個過程,permantently刷新我的aStruct的。 現在我有一個bStruct的緩衝區,我想保持更新。 數據[]數組是重要的領域。我並不關心結構的其他價值。

我已經確定,在代碼運行的特定系統上,「char」也是8Bits。

現在我想讓「b.data」數組指向與我的「a.data」數組完全相同的值。所以如果進程刷新我的aStruct,我的bStruct中的值也是最新的。

因此,在C數組只有一個指向第一個元素,我覺得這樣的事情一定是可能的:

b.data = a.data 

但不幸的是這給我的編譯器錯誤:

error: assignment to expression with array type

有沒有辦法做我打算做的事情?

在此先感謝

+0

那不是這是如何工作的。分配'a.data [0] =(char)b.data [0]'等等。如果你喜歡,可以使用for循環。 – Magisch

+0

在'bStruct'中,您需要將'char data [8]'更改爲'char * data',所以答案是否定的。 – user3386109

+0

數組不指向數據。並且不可分配。查看如何複製數組,應該有許多重複項。 – juanchopanza

回答

0

如果你想b.data[]陣列指向完全相同的值,那麼你可以做的b一個char*data並使其指向adata

喜歡的東西

struct{ 
uint8_t value; 
uint8_t unimportant_stuff; 
char* data; 
}typedef bStruct; 

b.data = a.data; 

但是,請記住,這意味着b.data是在相同的存儲單元a.data指向,因此,改變b.data值會發生變化值的a.data也。


有這樣的另一種方式。它通過將a.data的所有值複製到b.data中。然後,b.data只會包含與a.data相同的值,但它會指向不同的內存位置。

這可以通過逐個複製來完成。在所有8元素的for循環中。

或者,要使用memcpy()


注意

數組不能進行指向另一個存儲位置。因爲它們是不可修改的l值。如果您不能修改struct,那麼您必須使用第二種方法。

+0

這正是我想要做的......問題是,我無法更改結構(都定義在庫中) –

+1

@TomMekken,那麼你將不得不採用第二種方法。因爲不能使數組指向其他內存位置。他們是**不可修改的l值** – Haris

+0

是的,但我沒有通知有關更新。所以我不知道什麼時候複製這些值...因此我想要指針。好的,所以沒有「真正的」指針似乎沒有辦法做到這一點。 –

1

好的,根據我從你們那裏得到的意見,我認爲這可能是重新設計我的應用程序的最佳方式。

因此,而不是緩衝區的bStruct的我可能會使用aStruct *的緩衝區。這可以確保我的緩衝區始終處於最新狀態。然後,如果我需要使用緩衝區的某個元素進行操作,我會寫一個簡短的getter函數,它將aStruct *中的數據複製到臨時bStruct中並返回。

感謝您的回覆和評論。

+0

謝謝你寫下! – fuz

0

當你無法修改現有的結構定義時,你所要求的是不可能的。但是,您仍然可以通過一些OO風格的編程來自動執行功能。以下所有內容假定結構中的數據字段長度相同,並且包含相同大小的元素,如示例中所示。

基本上,你用自己的容器包裝現有的結構。你可以把這個頭文件:

/* Forward declaration of the wrapper type */ 
typedef struct s_wrapperStruct wrapperStruct; 
/* Function pointer type for an updater function */ 
typedef void (*STRUCT_UPDATE_FPTR)(wrapperStruct* w, aStruct* src); 
/* Definition of the wrapper type */ 
struct s_wrapperStruct 
{ 
    STRUCT_UPDATE_FPTR update; 
    aStruct* ap; 
    bStruct* bp; 
}; 

然後你就可以可以創建你用它來創建您的同步結構對避免同步邏輯暴露給感興趣各方工廠式的模塊。實現一些簡單的功能。

/* The updater function */ 
static void updateStructs(wrapperStruct* w, aStruct* src) 
{ 
    if ((w != NULL) && (src != NULL)) 
    { 
     /* Copy the source data to your aStruct (or just the data field) */ 
     memcpy(w->ap, src, sizeof(aStruct)); 
     /* Sync a's data field to b */ 
     sync(w); /* Keep this as a separate function so you can make it optional */ 
    } 
} 

/* Sync the data fields of the two separate structs */ 
static void sync(wrapperStruct* w) 
{ 
    if (w != NULL) 
    { 
     memcpy(w->bp->data, w->ap->data, sizeof(w->bp->data)); 
    } 
} 

然後在你的工廠函數可以創建包裹對。

/* Create a wrapper */ 
wrapperStruct syncedPair = { &updateStructs, &someA, &someB }; 

然後,您可以在需要的地方通過,例如,正在更新您的aStruct,並使用它像這樣的過程:

/* Pass new data to the synced pair */ 
syncedPair.update(&syncedPair, &newDataSource); 

因爲C不是被設計成一個面向對象的語言,它不具有this指針,你需要通過明確的包裝圍繞指針。從本質上講,這就是C++幕後的情況,編譯器爲您節省了額外的麻煩。

如果您需要將單個aStruct同步到多個bStruct s,將指針更改爲數組指針並相應地修改其餘部分應該非常簡單。

這可能看起來像一個過於複雜的解決方案,但是當您實現邏輯一次時,它可能會幫助您節省維護中的一些體力勞動。