Pergunta

Como devo escrever meu código para exemplo, um índice de matriz específico de uma matriz que é membro de uma estrutura? O código a seguir está me dando problemas.

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

Eu recebo um erro do compilador "Membro da estrutura/união esperada" Na linha seguinte:

p_data = &p_struct->DATA;

Como devo escrever um ponteiro para acessar, por exemplo, o valor específico dos dados do membro da estrutura [3]? Estou confuso, pensei que como p_data = & p_struct-> dados; é definido, eu deveria ser capaz de obtê -lo usando *(pdata+3), mas acho que estou perdendo alguma coisa.

Foi útil?

Solução

Tem certeza de que está compilando o mesmo código que você postou aqui?

Se o seu compilador reclamar desta linha

p_data = &p_struct->DATA;

Com uma mensagem "Struct/Union Member", seu compilador provavelmente está quebrado.

Observe que &p_struct->DATA é uma expressão perfeitamente válida em C. Não há absolutamente nenhum problema com essa expressão por si só.

O problema aqui é que não é isso que você precisa no seu caso. &p_struct->DATA Retorna um ponteiro para toda a matriz 'dados', ou seja, um ponteiro do tipo unsigned char (*)[20]. Você está tentando atribuir esse valor a um ponteiro do tipo unsigned char *. Isso é ilegal em C, já que os tipos são completamente diferentes, mas tradicionalmente os compiladores C respondem a ele com um mero aviso de "incompatibilidade" e realizou uma conversão implícita (que, btw, significa que seu código original, embora "sujo", deve ainda trabalha como pretendido).

Mesmo que algum compilador decida sinalizar essa incompatibilidade como um erro (o que é bom), ele ainda não deve reclamar de nenhum problema de "membro da estrutura/membro da união esperado". Não existem problemas aqui.

PS Como outros já disseram, o que você realmente precisa é p_data = &p_struct->DATA[0], mas isso ainda não explica o comportamento estranho do seu compilador. Será que 'Data' é uma macro definida em algum lugar antes da definição 'Clean_Buffers'?

Adicionado 19/10/2009: Nate, em seu código, você acessa sua matriz usando um índice theCount. Como você está usando o acesso do índice de qualquer maneira, não há realmente razão para criar o ponteiro que você está tentando criar. O código funcionará perfeitamente bem sem qualquer ponteiro adicional, apenas acessar o DATA campo diretamente

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

(Eu provavelmente usaria um for ciclo aqui).

Se você realmente insiste em criar este ponteiro e ainda usar o acesso do índice, o código deve se parecer com o seguinte (os outros já sugeriram que mais de uma vez)

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

Além disso, você pode optar por uma variante mais "exótica" :)

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;

No entanto, retornando a um unsigned char *p_data Versão, como você cria esse ponteiro, pode fazer mais sentido usar uma técnica "ponteiro deslizante" em vez de usar o acesso ao índice

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

Como sempre, é tudo uma questão de preferência pessoal. Obviamente, nada disso funcionará até você se livrar dessa interferência da macro.

Outras dicas

Perder o & in p_data = &p_struct->DATA;

p_struct já é um ponteiro. Depois, use p_data [] para acessar sua matriz.

O que você deve escrever é uma das duas coisas:

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

OU

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

Basta remover o & no começo, assim:

p_data = p_struct->DATA;

Isso é Sintax especial para matrizes (lembre -se de que são sempre passadas como referência) e é equivalente a:

p_data = &p_struct->DATA[0];

E sim, agora você pode usar *(pdata+3)

Espero que ajude.

Opa! Obrigado Andreyt

struct dev_status *p_struct; char não assinado *p_data; p_struct = & g_cmdQueue [queidx]; p_data = & p_struct-> data;

p_struct é um ponteiro para struct DEV_STATUS.
&p_struct é o endereço de um ponteiro para struct DEV_STATUS (ou um ponteiro para um ponteiro para um struct DEV_STATUS).

Você provavelmente quer mudar essa linha para

    p_data = p_struct->DATA;

Oh ... seu clean_buffers() A função não "limpa" o elemento g_cmdQueue[59].

E, porque é um objeto global, a matriz g_cmdQueue é inicializado para todos os zeros mesmo antes da primeira declaração de main() Exceuta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top