簡體   English   中英

在C中:如何設置指向作為數組的結構成員的指針?

[英]In C: How to set a pointer to a structure member that is an array?

我應該如何編寫代碼來示例恰好是結構成員的數組的特定數組索引? 以下代碼給了我一些問題。

// main.c

void clean_buffers(void); // prototype

struct DEV_STATUS {
    unsigned char ADDR;
    unsigned char DEV_HAS_DATA;
    unsigned char ETH_HAS_DATA;
    unsigned char DATA[20];
};

struct DEV_STATUS g_cmdQueue[60] = {0};

void main(void) {

    clean_buffers();

    while (1) {
        ;// MCU tasks        
    }
}

void clean_buffers(void) {
    unsigned char theCount = 0;
    byte queIdx;
    for (queIdx = 0; queIdx < 59; queIdx++) {
        struct DEV_STATUS *p_struct;
        unsigned char *p_data;
        p_struct = &g_cmdQueue[queIdx];
        p_data = &p_struct->DATA;
        p_struct->ADDR = 0;
        p_struct->DEV_HAS_DATA = 0;
        p_struct->ETH_HAS_DATA = 0;
        theCount = 0;
        while(*(p_data+theCount) != 0) {
            *(p_data+(theCount++)) = 0;
        }
    }    
} // EOF main.c

我在以下行中收到編譯器錯誤“struct / union member expected”

p_data = &p_struct->DATA;

如果我要訪問,例如,結構成員DATA [3]的具體值,我應該如何編寫指針? 我很困惑,我認為這是p_data =&p_struct-> DATA; 定義,我應該能夠通過使用*(pdata + 3)得到它,但我想我錯過了一些東西。

您確定要編譯您在此處發布的相同代碼嗎?

如果你的編譯器在這一行抱怨

p_data = &p_struct->DATA;

使用“struct / union member expected”消息,您的編譯器可能已損壞。

注意, &p_struct->DATA是C中完全有效的表達式。這個表達式本身絕對沒有問題。

這里的問題只是在你的情況下這不是你需要的。 &p_struct->DATA返回指向整個數組'DATA'的指針,即unsigned char (*)[20]類型的指針。 您正在嘗試將此值分配給unsigned char *類型的指針。 這在C中是非法的,因為類型完全不同,但傳統上C編譯器只用“類型不匹配”警告響應它並執行隱式轉換(BTW,意味着你的原始代碼,雖然“臟”,應該仍然按預期工作)。

即使某些編譯器決定將此不匹配標記為錯誤(這很好),它仍然不應該抱怨“struct / union member expected”類型的任何問題。 這里沒有這樣的問題。

PS正如其他人已經說過的,你真正需要的是p_data = &p_struct->DATA[0] ,但這仍然無法解釋編譯器的奇怪行為。 可能是'DATA'是在'clean_buffers'定義之前某處定義的宏嗎?

已添加10/19/2009: Nate,在您的代碼中使用索引theCount訪問您的數組。 由於您仍在使用索引訪問,因此實際上沒有理由創建您嘗試創建的指針。 代碼將完美地工作,沒有任何額外的指針,只是直接訪問DATA字段

theCount = 0;
while (p_struct->DATA[theCount] != 0) {
  p_struct->DATA[theCount++] = 0;

(我可能在這里使用for循環)。

如果你真的堅持創建這個指針並且仍然使用索引訪問,那么代碼應該類似於以下內容(其他人已經建議多次)

p_data = p_struct->DATA; /* or &p_struct->DATA[0] */
...
theCount = 0;
while (p_data[theCount] != 0) {
  p_data[theCount++] = 0;

此外,你可以選擇更“異國情調”的變種:)

unsigned char (*p_data)[20]; /* <- note: declared differently */
...
p_data = &p_struct->DATA; /* <- note: your original version */
...
theCount = 0;
while ((*p_data)[theCount] != 0) {
  (*p_data)[theCount++] = 0;

但是,返回到unsigned char *p_data版本,因為您創建了該指針,使用“滑動指針”技術而不是使用索引訪問可能更有意義

unsigned char *p_data;
...
p_data = p_struct->DATA; /* or &p_struct->DATA[0] */
...
while (*p_data != 0) {
  *p_data++ = 0;

一如既往,這完全取決於個人喜好。 當然,除非你擺脫宏的干擾,否則這一切都無濟於事。

丟失p_data = &p_struct->DATA;

p_struct已經是一個指針。 然后,使用p_data []訪問您的陣列。

你應該寫的是兩件事之一:

p_data = p_struct->DATA; // DATA is the address of the first element.

要么

p_data = &p_struct->DATA[0]; // taking the address of the first element.

只需刪除開頭的&,如下所示:

p_data = p_struct->DATA;

這是數組的特殊sintax(記住它們總是作為引用傳遞),它相當於:

p_data = &p_struct->DATA[0];

是的,現在你可以使用*(pdata + 3)

希望能幫助到你。

哎呀! 謝謝AndreyT

struct DEV_STATUS * p_struct; unsigned char * p_data; p_struct =&g_cmdQueue [queIdx]; p_data =&p_struct-> DATA;

p_struct是指向struct DEV_STATUS的指針。
&p_struct是指向struct DEV_STATUS的指針的地址(或指向struct DEV_STATUS的指針)。

您可能想要將該行更改為

  p_data = p_struct->DATA; 

哦...你的clean_buffers()函數不會“清理”元素g_cmdQueue[59]

並且,因為它是一個全局對象,所以即使在main()的第一個語句之外,數組g_cmdQueue被初始化為全零。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM