[英]c struct grabbing data by offset
可以說我有這個結構:
typedef struct nKey {
int num;
widget* widget;
} NUMBER_KEY;
和一個功能:
void dialKey(widget* widget) {
// Need to print 'num' of the struct that this widget resides in
}
我該如何完成這項工作? 我嘗試了類似的東西:
printf("%d", * (int *) widget - sizeof(int)); // Failure.org
編輯:可以安全地假設所傳遞的小部件實際上是NUMBER_KEY結構的成員
編輯:尋找問題的解決方案而不是另一種方法。
正如Michael在回答中解釋的那樣,您不能在給定的約束下完成此操作,因為無法“返回”指針圖。 為了使事情更明顯,讓我畫一個涉及的對象圖(用C術語表示,而不是OOP含義):
+- NUMBER_KEY --+
| ... | points to
| widget field -+-----------+
| ... | |
+---------------+ | + widget +
+-->| ... |
| ... |
+-->| ... |
| +--------+
points to |
[widget argument]-----------+
注意箭頭。 它們是單向的-您可以從指針“移動”到指向的值,但是不能“移動”回去。 因此,您可以引用函數的widget
參數來獲取widget
對象,但是一旦到達該對象,就無法告訴其他人指向它了-包括NUMBER_KEY
結構的任何實例。 想一想:如果您有十二個指向同一widget
其他指針,其中有一些來自不同的NUMBER_KEY
對象,該怎么辦? 如果不在widget
對象中保留所有指針的列表,如何跟蹤呢? 如果您確實需要它,這就是您需要做的-使widget
指向它自己的NUMBER_KEY
。
只給一個widgit *而不是一個widgit **傳遞給DialKey,就沒有辦法做你想要的事情(一個widgit *值與NUMBER_KEY結構沒有關系)。 假設您的意思確實是這樣的:
void dialKey(widget** ppWidget)
{
// Need to print 'num' of the struct that this widget resides in
}
微軟有一個漂亮的宏可以做這種事情(它有助於使例程能夠以C語言通用地操作鏈表):
#define CONTAINING_RECORD(address, type, field) ((type *)( \
(PCHAR)(address) - \
(ULONG_PTR)(&((type *)0)->field)))
您可以這樣使用:
NUMBER_KEY* pNumberKey = CONTAINING_RECORD( *ppWidgit, NUMBER_KEY, widgit);
printf( "%d", pNumberKey->num);
結構的內存布局是由編譯器定義的,只有在結構成員之間填充0字節填充時,代碼才能工作。 通常不建議這樣做,因為b / c 0字節填充會使結構覆蓋大多數處理器的標准讀取大小。
一些對您的問題有用的宏:
#define GET_FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
#define GET_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
例:
NUMBER_KEY key;
key.num = 55;
int nOffSetWidget = GET_FIELD_OFFSET( NUMBER_KEY, widget);
int *pKeyNumAddress = (int *) &(key.widget) - nOffSetWidget );
printf("%d", * pKeyNumAddress ); // Should print '55'
C標准定義了offsetof()
宏(在stddef.h
標頭中定義),在您的情況下很方便。
#include <stddef.h>
void DialKey(widget** foo) {
printf("%d", *((char *)foo - offsetof(struct nKey, widget)));
}
請注意,您必須傳遞一個struct字段的地址 ,而不是一個值!
最安全的解決方案是在小部件中保留指向相關nKey結構的指針
printf("%d", widget->myKey->num);
所有其他方法都不安全
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.