2009-07-29 99 views
3

在我的嵌入式C程序我有一個結構:的C指針問題

struct var{ 
    unsigned long value; 
    unsigned long length; 

    + More 
} 

這些結構的數組是用來裝變量。大部分存儲的變量都存儲在'value'中,因此長度設置爲1.
但是,其中一些變量是數組,我試圖將起始地址存儲在'value'中。

unsigned long lookup[10]; 
variables[x].length = 10; 

那我不太清楚如何來保存地址...

variables[x].value = lookup; 
// lookup is a pointer so I cant put it into value 

OR

variables[x].value = (unsigned long)lookup; 
// value reads back through sprintf+uart as '536874692' 
// which couldnt be a valid memory address! 

我可能乾脆放棄,並在結構中添加一個指針變量

編輯:
我想避免將指針添加到結構中,因爲我必須返回並重寫flash讀/寫函數以保存指針。這些都很複雜,目前正在工作,所以我寧願不要碰它們!

+0

爲什麼536874692無法成爲有效的地址? – jalf 2009-07-29 13:59:25

+0

剛剛意識到這一點。 536874692是20000EC4,它可能是有效的... – Tim 2009-07-29 14:02:35

+0

請注意,如果您的「閃存讀取/寫入功能」不知道查找是一個指針,他們將不知道保存它指向的數據。 – caf 2009-07-29 14:21:17

回答

5

可能將地址存儲在value中,將其轉換爲unsigned long,如您演示的那樣。 (我認爲你得到一個有效的地址...十六進制,它出來作爲0x20000EC4 ......看起來像你的嵌入式系統的數據段開始於0x20000000,是吧?)

然而,在澆鑄整數(或長整數)指針永遠不會「乾淨」。爲什麼不添加一個

unsigned long *starting_address; 

到你的結構?那麼你可以避免類型轉換。如果您擔心這會需要更多內存,則可以使用存儲unsigned long *starting_address或「無符號長整型值」的聯合體,該值比轉換更清晰。

0

我沒有看到在你的結構中放置一個指針的缺點。你想讓記憶處於連續的區塊嗎?你可以這樣做

struct var 
{ 
    unsigned long *value; 
    unsigned long length; 

    unsigned long othervalue1; 
    unsigned long othervalue2; 
}; 

但是不要忘了分別使用malloc來分配值的內存。或者,如果它是一個固定的空間量你想使用

unsigned long value[50]; 
0

,如果你的sprintf + UART查找會發生什麼。這給你什麼價值?

除非涉及到投射或符號擴展,否則實際數據是相同的。 sprintf對它的解釋是不同的。

你只是使用指針的解決方案是好的。如果你真的想使用int,你應該使用intptr_t,它保證足夠大以適應指針。

6

清潔選項將使用工會

struct var{ 
    union { 
     unsigned long numeric; 
     void *ptr; 
    } value; 
    unsigned long length; 

    + More 
} 

你可以選擇性地包含一個枚舉類型,就像通常使用聯合使用片段一樣。

1

假設系統指針大小與unsigned long(沒有gaurantee,請檢查它與sizeof)的系統指針大小相同,您將使用該演員。但這是混亂和容易出錯的。考慮使用聯合來代替。

struct var{ 
    unsigned short type; 
    union { 
     unsigned long i; 
     void *p; 
    } value; 
    unsigned long length; 

    + More 
} 

您在哪裏存儲類型type

0

當長度爲1時,爲什麼不將值設置爲一個長度爲1的數組?反正你不會使用更多的空間。

0

我不確定你爲什麼沒有將值定義爲unsigned long *。

相反,這樣做:

struct var{ 
    union{ 
    unsigned long solo_value; 
    unsigned long* multi_values; 
    } 

    unsigned long length; 
    + More 
}; 

而且,排列規則不那麼強烈*,因爲它們是在堆中執行堆棧。不過,如果你使用的是最新的編譯器,他們應該是無論如何......你可能用sprintf粉碎了一些東西。使用調試器或更可靠的東西拉出值。

*技術上malloc()等。人。強制執行8字節對齊規則,而不是語言。

0

您最好的選擇是使用枚舉,如前所述:

typedef struct var{ 
    union { 
     unsigned long numeric; 
     void *ptr; 
    } value; 
    unsigned long length; 

    // + More 
} composition_t; 

然後使用lenght成員來區分數據的類型:

composition_t array[2]; 
unsigned long lookup[10]; 

// Just a plain unsigned long value 
array[0].value.numeric = 100; 
array[0].length= 1; 

// An array of 10 long values 
array[0].value.ptr= lookup; 
array[x].length = 10; 
0

熊請注意,無符號長整數不能保證指針,儘管它可能在嵌入式系統中。按照其他答案的建議,做標準的事情並使用工會。在任何符合標準的實現中,工會都會做正確的事情,而不僅僅是你現在正在使用的東西。此外,它具有說出你的意思的優點,當有人不立即詆譭代碼(也許你,一年以後)必須處理它時,這是非常有價值的。

0

您是否知道膠印? http://en.wikipedia.org/wiki/Offsetof

我不確定你真的想做什麼,但是將一個結構成員的地址存儲在同一個結構中似乎沒有必要。

還有一個container_of宏(谷歌它),它是使用offsetof構建的,也可能是有用的。