*Pointer,Variaveis locais...ou ok?

Programação C em geral

Moderadores: 51, guest2003

*Pointer,Variaveis locais...ou ok?

Mensagempor vtrx » 28 Jun 2018 21:38

Não sou bom na linguagem C,então quase sempre caio em 'armadilhas' que me faz perder tempo.
Comprei um módulo DHT11,e achei que não ia ser difícil sua implementação,mas foi...
Fique horas sem saber se era o Hardware,temporização ou rotina mal interpretada,desmembrei todas as partes da rotina principal e não achava alguma 'lógica errada' em nenhuma delas,mas era a forma de utilizar estas rotinas que eu estava fazendo 'errado'.
A rotina principal de leitura do módulo é:
Código: Selecionar todos
u8 DHT11_Read_Data(void)   
{    
  u8 buf[5];
  u8 i;

  DHT11_Rst();
 if(DHT11_Check()==0)
    {
  for(i=0;i<5;i++)
       {
        buf[i]=DHT11_Read_Byte();
       }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
         {
               HM=buf[0];
               TP=buf[2];
               HM1=buf[1];
               TP1=buf[3];
         }
    }
    else
        return 1;
    return 0;       
}


Acontece que usando HM,TP,HM1 e TP1 como variáveis globais,a rotina retorna os valores corretamente,mas se eu usá-las no corpo da rotina,não consigo retornar os valores.
Exemplo:
Código: Selecionar todos
u8 DHT11_Read_Data(u8 var,u8 var1,u8 var2,u8 var3)   
{    
  u8 buf[5];
  u8 i;

  DHT11_Rst();
 if(DHT11_Check()==0)
    {
  for(i=0;i<5;i++)
       {
        buf[i]=DHT11_Read_Byte();
       }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
         {
               var=buf[0];
               var1=buf[2];
               var2=buf[1];
               var3=buf[3];
         }
    }
    else
        return 1;
    return 0;       
}


Deste modo não consigo carregar as variáveis globais chamando a rotina como if(DHT11_Read_Data(HM,HM1,TP,TP1) ==0 ){...,não carrega os valores nas variáveis.
Como é o procedimento correto?
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor tcpipchip » 28 Jun 2018 22:12

vc deu o #include < >

TCPIPCHIP
------------------------------------------
http://www.youtube.com/tcpipchip
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor Rodrigo_P_A » 28 Jun 2018 22:19

Existem várias formas, seguem 2 exemplos:


Código: Selecionar todos
u8 DHT11_Read_Data(u8 *var,u8 *var1,u8 *var2,u8 *var3)   
{   
  u8 buf[5];
  u8 i;

  DHT11_Rst();
 if(DHT11_Check()==0)
    {
  for(i=0;i<5;i++)
       {
        buf[i]=DHT11_Read_Byte();
       }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
         {
               *var=buf[0];
               *var1=buf[2];
               *var2=buf[1];
               *var3=buf[3];
         }
    }
    else
        return 1;
    return 0;       
}


chamando:
void blablabla()
{
  u8 var,var1,var2,var3;
 DHT11_Read_Data(&var,&var1,&var2,&var3) ;
}



--- OU ASSIM:

Código: Selecionar todos
u8 DHT11_Read_Data(u8 *buf)   
{   
  u8 i;

  DHT11_Rst();
 if(DHT11_Check()==0)
    {
      for(i=0;i<5;i++)
       {
        buf[i]=DHT11_Read_Byte();
       }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
         {
         return 0;
         }
       return 1;
    }
    else
   {
        return 2;
   }
    return 3;       
}


chamando:
void blablabla()
{
  u8 buf[5];
  u8 ret;
  ret=DHT11_Read_Data(buf) ;
  if ( ret==0 )
  {
   // ok..... faça algo seus dados estão aqui
  }
}
---
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2236
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor andre_luis » 28 Jun 2018 22:27

Nao ficou claro se voce também está usando essas variaveis dentro de alguma rotina de interrupção ou não, mas na dúvida sempre as declaro como volatile.
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor xultz » 29 Jun 2018 09:02

Uma terceira opção é você declarar uma estrutura com os quatro parâmetros que a função retorna (HM, TP, etc) e pode também colocar na estrutura o valor de retorna da função (0 se leu ok, 1 se deu zica), e fazer a função retornar esta estrutura. Fica bonitinho.
Ou então cria a estrutura somente com os 4 parâmetros e passa a estrutura sob forma de ponteiro, e retorna o valor de status da leitura do sensor. Depois que se acostuma a usar o operador ->, fica bem legalzinho também.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor Rodrigo_P_A » 29 Jun 2018 10:01

Exemplo 3:

Código: Selecionar todos
typedef struct {
   u8 HM;
   u8 TP
   u8 HM1;
   u8 TP1;
} tpdadosxultz;

u8 DHT11_Read_Data(tpdados *tpdadosxultz)   
{   
  u8 i;
  u8 *buf=(u8*)tpdadosxultz;
  DHT11_Rst();
 if(DHT11_Check()==0)
    {
      for(i=0;i<5;i++)
       {
        buf[i]=DHT11_Read_Byte();
       }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
         {
         return 0;
         }
       return 1;
    }
    else
   {
        return 2;
   }
    return 3;       
}


chamando:
void blablabla()
{
  tpdadosxultz xultz;
  u8 ret;
  ret=DHT11_Read_Data(&xultz) ;
  if ( ret==0 )
  {
   // ok..... faça algo seus dados estão aqui
   // aggora vc tem os dados em: xultz.HM  xultz.TP xultz.HM1 xultz.TP1
  }
}
---
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2236
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor eletroinf » 29 Jun 2018 13:17

O Xultz gosta de estruturas
"De cada um segundo sua capacidade a cada um segundo sua necessidade."
Avatar do usuário
eletroinf
Word
 
Mensagens: 948
Registrado em: 12 Out 2006 14:59
Localização: Santa Maria - RS

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor xultz » 30 Jun 2018 16:13

Eu não gostei dessa parte:
Código: Selecionar todos
u8 *buf=(u8*)tpdadosxultz;


Não é mais humanamente compreensível fazer
Código: Selecionar todos
tpdadosxultz->HM = DHT11_Read_Byte();
tpdadosxultz->TP = DHT11_Read_Byte();
tpdadosxultz->HM1 = DHT11_Read_Byte();
tpdadosxultz->TP1 = DHT11_Read_Byte();


do que
Código: Selecionar todos
for(i=0;i<5;i++)
 {
 buf[i]=DHT11_Read_Byte();
 }

?
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor Rodrigo_P_A » 30 Jun 2018 16:36

xultz escreveu:Eu não gostei dessa parte:
Código: Selecionar todos
u8 *buf=(u8*)tpdadosxultz;


Não é mais humanamente compreensível fazer
Código: Selecionar todos
tpdadosxultz->HM = DHT11_Read_Byte();
tpdadosxultz->TP = DHT11_Read_Byte();
tpdadosxultz->HM1 = DHT11_Read_Byte();
tpdadosxultz->TP1 = DHT11_Read_Byte();


do que
Código: Selecionar todos
for(i=0;i<5;i++)
 {
 buf[i]=DHT11_Read_Byte();
 }

?



pode ser, mas eu pensei que fosse mais fácil para ele entender... existem várias formas de fazer.
---
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2236
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor vtrx » 01 Jul 2018 19:35

Usei como o Rodrigo_P_A sugeriu,pois é oque se encontra na Net,usando Keil:

Código: Selecionar todos
void TIM2_IRQHandler(void)  //
{
   u8   TP,TP1,HM,HM1;
     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
     {
   //   GPIOA->ODR ^=  ( 1 << 2 );
   //   GPIOA->ODR ^=  ( 1 << 3 );
   //   GPIOB->ODR ^=  ( 1 << 2 );
       GPIOA->ODR ^= GPIO_Pin_2;
       GPIOA->ODR ^= GPIO_Pin_3;
       GPIOB->ODR ^= GPIO_Pin_2;
      if(DHT11_Read_Data(&HM,&TP,&HM1,&TP1)==0)
         {
            sprintf((char *)Texto,"HUMIDADE:%d%%, TEMPERATURA:%d C",HM,TP);
          GLCD_Print(4,16,Texto,White,Black);               
         }
         else
         {
            GLCD_Print(4,16,(u8 *)"DH11 erro",White,Black);
         }
      TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );   
     }

}


Código: Selecionar todos
u8 DHT11_Read_Data(u8 *var,u8 *var1,u8 *var2,u8 *var3)   
{    
  u8 buf[5];
  u8 i;

  DHT11_Rst();
 if(DHT11_Check()==0)
    {
  for(i=0;i<5;i++)
       {
        buf[i]=DHT11_Read_Byte();
       }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
         {
           *var=buf[0];
           *var1=buf[2];
           *var2=buf[1];
           *var3=buf[3];
         }
    }
    else
        return 1;
    return 0;       
}


Pergunta que preciso fazer:
1-Porque só tenho o resultado usando 'pointers',se usar direto retorna zero?
2-Porque usar
Código: Selecionar todos
&
,não seria '*' ?
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor Rodrigo_P_A » 01 Jul 2018 21:27

vtrx escreveu:Usei como o Rodrigo_P_A sugeriu,pois é oque se encontra na Net,usando Keil:

Código: Selecionar todos
void TIM2_IRQHandler(void)  //
{
   u8   TP,TP1,HM,HM1;
     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
     {
   //   GPIOA->ODR ^=  ( 1 << 2 );
   //   GPIOA->ODR ^=  ( 1 << 3 );
   //   GPIOB->ODR ^=  ( 1 << 2 );
       GPIOA->ODR ^= GPIO_Pin_2;
       GPIOA->ODR ^= GPIO_Pin_3;
       GPIOB->ODR ^= GPIO_Pin_2;
      if(DHT11_Read_Data(&HM,&TP,&HM1,&TP1)==0)
         {
            sprintf((char *)Texto,"HUMIDADE:%d%%, TEMPERATURA:%d C",HM,TP);
          GLCD_Print(4,16,Texto,White,Black);               
         }
         else
         {
            GLCD_Print(4,16,(u8 *)"DH11 erro",White,Black);
         }
      TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );   
     }

}


Código: Selecionar todos
u8 DHT11_Read_Data(u8 *var,u8 *var1,u8 *var2,u8 *var3)   
{    
  u8 buf[5];
  u8 i;

  DHT11_Rst();
 if(DHT11_Check()==0)
    {
  for(i=0;i<5;i++)
       {
        buf[i]=DHT11_Read_Byte();
       }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
         {
           *var=buf[0];
           *var1=buf[2];
           *var2=buf[1];
           *var3=buf[3];
         }
    }
    else
        return 1;
    return 0;       
}


Pergunta que preciso fazer:
1-Porque só tenho o resultado usando 'pointers',se usar direto retorna zero?
2-Porque usar
Código: Selecionar todos
&
,não seria '*' ?


Essas suas dúvidas são conceituais, sugiro ler um pouco mais sobre ponteiros, veja um artigo:
https://www.ime.usp.br/~pf/algoritmos/aulas/pont.html

Se tiver mais dúvidas após ler, poste aí pra gente.
---
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2236
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor vtrx » 02 Jul 2018 09:15

Muito interessante...depois dizem que ASM é difícil...
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor Rodrigo_P_A » 02 Jul 2018 09:54

vtrx escreveu:Muito interessante...depois dizem que ASM é difícil...


depois que entender vai bem... vale a pena!
---
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2236
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor xultz » 02 Jul 2018 19:09

Pergunta que preciso fazer:
1-Porque só tenho o resultado usando 'pointers',se usar direto retorna zero?
2-Porque usar &,não seria '*' ?


Quando você passa uma variável para uma função (não seu ponteiro), o programa cria um clone dessa variável. Esse clone vai existir enquanto a função estiver em execução. Assim que a função encerrar, esse clone será sumariamente destruído de uma forma violenta e dolorida.
Quando você passa o ponteiro da variável, é como se você dissesse prá função "use a variável que mora na rua tal, número tal, cidade tal". A função vai lá naquele endereço e mexe na variável como quiser. Quando a função termina, a variável continua naquele endereço. Como quem criou a variável foi a função principal (e ela sabe o endereço, porque foi ela que criou a variável), quando ela for visitar o endereço vai encontrar o resultado do que a função que foi chamada fez na variável. Ficou confuso o que eu escrevi, mas não é (muito).

A segunda pergunta é um detalhe irritante do C. Você usa o * quando quer declarar um ponteiro. Você usa o & para pegar o endereço da variável. E usa * para pegar o valor apontado por um ponteiro. Mas como assim, usa o * para duas coisas? É, isso gera uma confusão dos diabos, e eu não sei da onde os inventores do C tiveram essa ideia de jerico. Depois de fazer um milhão de vezes, acaba se acostumando. Mas no começo, isso gera confusão mesmo, não se preocupe, você não é o único não.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Re: *Pointer,Variaveis locais...ou ok?

Mensagempor andre_luis » 03 Jul 2018 07:55

Porque usar &,não seria '*' ?


De um modo resumido, o & é usado como argumento da função, indicando o endereço da variavel á ser manipulada, enquanto que o * funciona mais como uma declaração de tipo, que no caso da declaracao da função, é o tipo ponteiro para armazenar o endereço da variavel 'endereço' instanciada posteriormente no argumento da função.
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ


Voltar para Visual C++/C/C++/C#

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x