Domanda

Come faccio a scrivere il mio codice per esempio uno specifico indice di una matrice che sembra essere un membro di una struttura? Il codice seguente mi sta dando problemi.

// 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

ottengo un errore del compilatore "membro struct / union previsto" sulla riga seguente:

p_data = &p_struct->DATA;

Come dovrei scrivere un puntatore se ero per accedere, ad esempio, il valore specifico dei dati Gli struttura [3]? Sono confuso, ho pensato che come p_data = & p_struct-> DATI; è definito, dovrei essere in grado di farlo utilizzando * (pData + 3), ma credo che mi manca qualcosa.

È stato utile?

Soluzione

Sei sicuro si compila lo stesso codice che hai postato qui?

Se il compilatore si lamenta in questa linea

p_data = &p_struct->DATA;

con un "membro struct / union previsto" messaggio, il compilatore è probabilmente rotto.

Si noti che &p_struct->DATA è un'espressione perfettamente valido in C. Non c'è assolutamente nessun problema con questa espressione di per sé.

Il problema qui è solo che questo non è quello che ti serve nel vostro caso. &p_struct->DATA restituisce un puntatore l'intero array 'DATA', cioè un puntatore di tipo unsigned char (*)[20]. Si sta tentando di assegnare questo valore a un puntatore di tipo unsigned char *. Questo è illegale in C, poiché i tipi sono completamente diversi, ma tradizionalmente compilatori C risposto con un semplice avvertimento "tipo non corrispondente" e eseguita una conversione implicita (che, inoltre, significa che il codice originale, seppur "sporco", dovrebbe continuerà a funzionare come previsto).

Anche se alcuni compilatore decide di segnalare questo squilibrio come un errore (che va bene), ma ancora non dovrebbe lamentarsi dei problemi di "membro struct / union attesi" tipo. Non c'è nessun tipo di problemi qui.

P.S. Come altri già detto, che cosa si ha realmente bisogno è p_data = &p_struct->DATA[0], ma che ancora non spiega lo strano comportamento del compilatore. Potrebbe essere che 'DATA' è una macro definita da qualche parte prima della definizione delle 'clean_buffers'?

Aggiunto 2009/10/19: Nate, nel codice si accede l'array utilizzando un theCount indice. Dal momento che si sta utilizzando l'indice in ogni caso, non c'è davvero alcun motivo per creare anche il puntatore che si sta tentando di creare. Il codice funziona perfettamente bene senza alcun ulteriore puntatore, basta acess direttamente sul campo DATA

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

(probabilmente sarei utilizzare un ciclo for qui).

Se proprio insistete sulla creazione di questo puntatore e ancora utilizzando l'indice, il codice dovrebbe essere simile a quanto segue (le altre già suggerito che più di una volta)

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

Inoltre, si può optare per una variante più "esotici":)

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;

Comunque, tornando a una versione unsigned char *p_data, dal momento che a fare una puntatore, potrebbe avere più senso utilizzare una tecnica di "puntatore scorrimento" invece di usare l'accesso index

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

Come sempre, è tutta una questione di preferenze personali. Naturalmente, nulla di tutto questo funzionerà fino a sbarazzarsi di che l'interferenza dalla macro.

Altri suggerimenti

Perdere il & a   p_data = &p_struct->DATA;

p_struct è già un puntatore. In seguito, l'uso p_data [] per accedere l'array.

Che cosa si dovrebbe scrivere è una delle due cose:

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

o

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

È sufficiente rimuovere il & all'inizio, in questo modo:

p_data = p_struct->DATA;

Questo è sintassi speciale per array (ricordate che sono passati sempre come riferimento) ed è pari a:

p_data = &p_struct->DATA[0];

E sì, ora è possibile utilizzare * (pData + 3)

Speranza che aiuta.

Oops! Grazie AndreyT

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

p_struct è un puntatore ad struct DEV_STATUS.
&p_struct è l'indirizzo di un puntatore a struct DEV_STATUS (o un puntatore a un puntatore ad un struct DEV_STATUS).

Probabilmente si vuole cambiare quella linea a

    p_data = p_struct->DATA;

Oh ... la funzione clean_buffers() non "pulito" l'elemento g_cmdQueue[59].

E, perché è un oggetto globale, il g_cmdQueue array viene inizializzato a tutti zeri anche prima della prima dichiarazione di exceutes main().

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top