ELT048 - SOE
Ponteiros, Structs e Buffers Circulares
Rodrigo AlmeidaUniversidade Federal de Itajubá
Ponteiros
Ponteiros
● São variáveis que guardam o endereço (localização) de memória.
● Nestes endereços da memória é possível colocar valores e utilizá-los.
● Os tipos de valores colocados nos endereços de memória são definidos na declaração de um ponteiro.
● É esse tipo que indica ao compilador a quantidade de memória necessária para armazenar os valores.
● Uma variável do tipo ponteiro aponta para uma variável de um determinado tipo (char, int, float, double, . . .).
● É necessário na declaração de um ponteiro, especificar para qual tipo de variável ele irá apontar.
● Os ponteiros são declarados com um * antes do nome da variável.
Ponteiros● Sintaxe:tipo *nomeVariavel;
int *aux;
float *temp;
char *pont;
Ponteiros● aux, temp e pont são
variáveis que armazenam endereços de memória e não valores do tipo int, float ou char.
● * é usado quando deseja-se acessar o valor que está na posição de memória e não ao endereço da memória.
Ponteiros
Ponteiros● Operador &:
● Obtém sempre o endereço de uma variável
● Como os ponteiros também são variáveis eles também ocupam memória.– Pode-se obter o
endereço do ponteiro e ter ponteiros para ponteiros (múltiplos *).
● Operador *:● O operador * faz o
contrário do operador &.
● Dado um ponteiro, o operador * acessa o conteúdo apontado por ele.
Ponteiros● Simbolo &:
● “endereço de”● “salvo em”
● Simbolo *:● “derreferenciando”● “através de”● “apontado por”
Exemplo#include <stdio.h>
int main(int argc, char *argv[]){ int x=10; int *p1=&x; //ponteiro para um inteiro
printf("x = %d\n\n", x); *p1=20; //ou p1[0]=20; printf("p1 = %u\n", p1); printf("x = %d\n", x); printf("*p1 = %d\n", *p1); printf("p1[0] = %d\n\n", p1[0]); return 0;} //end main
Passagem de parâmetros● As funções em linguagem C podem receber
vários parâmetros e pode retornar um.● O método de envio dos parâmetros pode
ser feito na pilha ou nos registradores.● A pilha permite que diversos parâmetros sejam
passados de uma única vez● Os registros possuem menor overhead, sendo
portanto mais rápidos e com menor tamanho de código
Passagem de parâmetros● No envio, os parâmetros são copiados para uma
variável temporária, de modo que as alterações em seu valor são perdidas após o fim da função.
● A variável inicial não é alterada● Para evitar esta situação é comum realizar a
passagem de parâmetro por referência.
● Na passagem por referência é passado o endereço da variável de modo que a função consiga alterar o valor da variável original.
void incrementa(int a){ a += 1;}
int main(int argc, char *argv[]){ int x = 10;
incrementa(x);
return 0;}
void main(void){ int x = 10;
incrementa(x);
return 0;}
void incrementa(int a){ a+=1; return;}
Rotina Principal Função
void main(void){ int x = 10;
inc(x);
return 0;}
void inc(int a){ a += 1; return;}
Rotina Principal Função Variáveis
x=10
void main(void){ int x = 10;
inc(x);
return 0;}
void inc(int a){ a += 1; return;}
Rotina Principal Função Variáveis
x=10
a=10
void main(void){ int x = 10;
inc(x);
return 0;}
void inc(int a){ a += 1; return;}
Rotina Principal Função Variáveis
x=10
a=11
void main(void){ int x = 10;
inc(x);
return 0;}
void inc(int a){ a += 1; return;}
Rotina Principal Função Variáveis
x=10
descartado
void incrementaptr(int* a){ (*a) += 1;}
int main(int argc, char *argv[]){ int x = 10;
incrementaptr(&x);
return 0;} //end main
void main(void){ int x = 10;
incptr(&x);
return 0;}
void incptr (int* a){ (*a) += 1; return;}
Rotina Principal Função Variáveis
x=10
void main(void){ int x = 10;
incptr(&x);
return 0;}
void incptr (int* a){ (*a) += 1; return;}
Rotina Principal Função Variáveis
x=10
temp=&x
void main(void){ int x = 10;
incptr(&x);
return 0;}
void incptr (int* a){ (*a) += 1; return;}
Rotina Principal Função Variáveis
x=10
a=&x
void main(void){ int x = 10;
incptr(&x);
return 0;}
void incptr (int* a){ (*a) += 1; return;}
Rotina Principal Função Variáveis
x=11
a=&x
*
void main(void){ int x = 10;
incptr(&x);
return 0;}
void incptr (int* a){ (*a) += 1; return;}
Rotina Principal Função Variáveis
x=11
descartado
Passagem de parâmetros● A passagem de parâmetros por referência
permite que uma função “retorne” mais de um parâmetro por vez.
● Isto é feito passando-se uma variável via referência para que a função possa escrever nela.
Structs● As estruturas (structs) são a ferramenta
pela qual o programador pode agrupar diversas variáveis de tipos diferentes num mesmo conjunto.
● Utilizando-se a diretiva typedef é possível definir-se um novo tipo de variável.
typedef struct{ char titulo[30]; char producao[20]; char dataCompra[8]; int temporada; float preco;}t_serietv;
Structs
t_serietv s1 = {"Big Bang Theory", "Warner", "25/05/10", 3, 55.50};strcpy(s1.titulo,"The Big Bang Theory");strcpy(s1.producao, "Warner Bros");s1.temporada = 6;printf("A serie foi produzida pela %s,", s1.producao);printf(" e esta na temporada %d\n", s1.temporada);
● O acesso dos membros internos de estruturas apontadas por ponteiros pode ser feito através do operador ->
typedef struct{ char nome[20]; int idade;}t_aluno;
t_aluno *a1;
(*a1).nome = "Joao";(*a1).idade = 18;
a1->nome = "Joao";a1->idade = 18;
Structs
Buffers● Buffers são regiões de memória para
armazenamento temporário de informações.
● Podem ser implementados em SW ou HW.● Muito comuns em protocolos de
comunicação.
Buffers● Buffers circulares auxiliam na
implementação de filas do tipo FIFO (first in, first out)
● Em geral são implementados em cima de um vetor com funções para a manipulação deste.
● É necessário possuir ponteiros/variáveis que indiquem o começo e fim do buffer.
● Deve-se tomar cuidado na escolha
Exercício● Implementar um buffer circular● Utilizar um vetor de 10 posições● Cada elemento do vetor é uma estrutura
com duas variáveis● char NomeDoProcesso
● int Prioridade
● Criar uma função para adicionar novos elementos e uma para retirar os mais antigos.
Ponteiros para void● Aponta para uma região de memória sem
especificar o tipo.● Não pode ser utilizado sem casting● Abstração que permite ao programador
passar parâmetros de diferentes tipos para a mesma função.● A função que os receber deve saber como
tratar cada tipo.
char *name = "Paulo";
double weight = 87.5;
unsigned int children = 3;
void main (void){ //não confundir com printf print(0, name); print(1, &weight); print(2, &children);}
Ponteiros para void
Ponteiros para void
void print(int option; void *parameter){ switch(option){ case 0: printf("%s",(char*)parameter); break; case 1: printf("%f",*((double*)parameter)); break; case 2: printf("%d",*((unsigned int*)parameter)); break; }}
Exercício (cont)● Implementar um buffer circular
● Utilizar um vetor de 10 posições
● Cada elemento do vetor é uma estrutura com duas variáveis
● char tipo
● void* ptr
● Criar uma função para adicionar novos elementos e uma para retirar os mais antigos.● Add(char tipo, void* var);● Remove(void);