Fork me on GitHub

Microcontrolandos

O Blog está passando por uma fase de mudanças. Todos os posts estão sendo atualizados, códigos, links e imagens estão sendo arrumados. Conteúdos novos ainda estão por vir.

TUTORIAL: Ponteiros

Share:

TUTORIAL: Ponteiros



Um ponteiro é uma variável que contém um endereço de memória e não o valor.

A memória pode ser vista como uma sequência de bytes cada um com seu próprio endereço.

Ponteiros são importantes por exemplo quando se deseja que uma função retorne mais de um valor.

Por exemplo, uma função pode receber não os valores dos parâmetros, mas sim ponteiros que apontem para seus endereços. Assim esta função pode modificar diretamente os conteúdos destas variáveis.

Declaração dos ponteiros:
tipo *nome;

onde tipo é o tipo da variável e nome é o nome da variável ponteiro. Exemplo:
char *coelhos;
int *elefantes;

Operadores de ponteiros:
Existem dois operadores especiais para ponteiros: * e &

O operador & devolve o endereço de memória do seu operando. Por exemplo:

p = &coelhos; // o endereço de coelhos é carregado em p

O operador * devolve o valor da variável localizada no endereço que o segue. Por Exemplo:

p = *elefantes; //o valor de elefantes é carregado em p

Incrementando e Decrementando ponteiros:
Exemplo:
char valores = {0, 10, 20, 30, 40};
char *p;

void main()
{
p = &valores; // p aponta para o endereço inicial de valores. vamos supor que é 0x0000;
lcd_out(1, 1, *p); // escreve do display lcd o valor apontado por p, que é 0;
p++; //incrementa o ponteiro. O endereço apontado por p é 0x0001;
lcd_out(1, 1, *p); // escreve do display lcd o valor apontado por p, que é 10;
}




Não é possível multiplicar ou dividir ponteiros, e não se pode adicionar ou subtrair o tipo float ou o tipo double a ponteiros.

Ponteiros e Vetores
Ponteiros e Vetores estão fortemente relacionados. O nome de um vetor é um ponteiro que aponta para a primeira posição do vetor e todas as operações já mencionadas para ponteiros podem ser executadas com um nome de vetor. Por exemplo, a declaração:
 
int v[100];

declara um vetor de inteiros de 100 posições e a partir dela temos que v é um ponteiro equivalente ao da declaração abaixo:

int *v;
 
Por esta razão as seguintes declarações são idênticas e podem ser intercambiadas independemente do modo como v foi declarado:

v[i] = *(v+1);
&v[i] = v+i;

Existe uma diferença fundamental entre declarar um conjunto de dados como um vetor ou através de um ponteiro. Na declaração de vetor o compilador automaticamente reserva um bloco de memória para que o vetor seja armazenado. Quando apenas um ponteiro é declarado a única coisa que o compilador faz é alocar um ponteiro para apontar para a memória, sem que o espaço seja reservado.

O nome de um vetor não pode ter o seu valor alterado. Assim, os comandos abaixo não são válidos:

int coelhos[5], vacas;

coelhos = &vacas; // coelhos não pode ser modificado
coelhos++; //coelhos não pode ser incrementado

Outro exemplo:

int numeros[] = {1, 2, 3, 4, 5};
char *p;
char i;

void main()
{
  for(i=0; i< 5; i++) uart1_write( numeros[i] + '0' );
  for(i=0; i< 5; i++) uart1_write( *(numeros + i) + '0' );
  p = v;
  for(i=0; i< 5; i++) uart1_write( *(p++) + '0' );
}

Ponteiros e String

char *string = "Microcontrolandos";

void main()
{
 lcd_out(1, 1, string);
}

Mais Exemplos
Exemplo 01:

void pulse(char *port, char pin, int time)
{
   *port &= ~(1<<pin);
   VDelay_ms(time);
   *port |= (1<<pin);
   VDelay_ms(time);
}

void main()

{
TRISB = 0;
   while(1)
   {
    pulse(&PORTB, 0, 100);
   }
}

Exemplo 02:

void formatarFloat( float num, char *Out, char nCasas )
{
unsigned short i;
char string[15];

FloatToStr(num, string);
while(*string != 0)
{
     *Out++ = *string++;
     if(*string == '.')
     {
       for(i=0; i<=nCasas; i++)
       {
          *(Out+i) = *(string+i);
       }
       break;
     }
}
} 

3 comentários: