O documento descreve conceitos sobre ponteiros, structs e buffers circulares em C. Especificamente, apresenta: 1) como ponteiros armazenam endereços de memória e apontam para variáveis; 2) como structs agrupam variáveis de diferentes tipos; e 3) como buffers circulares implementam filas FIFO usando um vetor com ponteiros de início e fim.
3. 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, . . .).
4. Ponteiros
● É necessário na ● Sintaxe:
declaração de um tipo *nomeVariavel;
ponteiro, especificar
para qual tipo de
variável ele irá
apontar.
● Os ponteiros são
declarados com um
* antes do nome da
variável.
5. Ponteiros
int *aux; ● aux, temp e pont são
float *temp; variáveis que
armazenam endereços
char *pont; 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.
7. Ponteiros
● Operador &: ● Operador *:
● Obtém sempre o ● O operador * faz o
endereço de uma contrário do operador
variável &.
● Como os ponteiros ● Dado um ponteiro, o
também são variáveis operador * acessa o
eles também ocupam conteúdo apontado
memória. por ele.
– Pode-se obter o
endereço do ponteiro
e ter ponteiros para
ponteiros (múltiplos *).
9. Exemplo
#include <stdio.h>
int main(int argc, char *argv[]){
int x=10;
int *p1=&x; //ponteiro para um inteiro
printf("x = %dnn", x);
*p1=20; //ou p1[0]=20;
printf("p1 = %un", p1);
printf("x = %dn", x);
printf("*p1 = %dn", *p1);
printf("p1[0] = %dnn", p1[0]);
return 0;
} //end main
10. 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
11. 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.
12. void incrementa(int a){
a += 1;
}
int main(int argc, char *argv[]){
int x = 10;
incrementa(x);
return 0;
}
13. Rotina Principal Função
void main(void){
int x = 10;
incrementa(x); void incrementa(int a)
{
a+=1;
return;
}
return 0;
}
14. Rotina Principal Função Variáveis
void main(void)
{
int x = 10; x=10
inc(x); void inc(int a){
a += 1;
return;
}
return 0;
}
15. Rotina Principal Função Variáveis
void main(void)
{
int x = 10; x=10
a=10
inc(x); void inc(int a){
a += 1;
return;
}
return 0;
}
16. Rotina Principal Função Variáveis
void main(void)
{
int x = 10; x=10
a=11
inc(x); void inc(int a){
a += 1;
return;
}
return 0;
}
17. Rotina Principal Função Variáveis
void main(void)
{
int x = 10; x=10
descartado
inc(x); void inc(int a){
a += 1;
return;
}
return 0;
}
18. void incrementaptr(int* a){
(*a) += 1;
}
int main(int argc, char *argv[]){
int x = 10;
incrementaptr(&x);
return 0;
} //end main
19. Rotina Principal Função Variáveis
void main(void)
{
int x = 10; x=10
incptr(&x); void incptr
(int* a){
(*a) += 1;
return;
}
return 0;
}
20. Rotina Principal Função Variáveis
void main(void)
{
int x = 10; x=10
temp=&x
incptr(&x); void incptr
(int* a){
(*a) += 1;
return;
}
return 0;
}
21. Rotina Principal Função Variáveis
void main(void)
{
int x = 10; x=10
a=&x
incptr(&x); void incptr
(int* a){
(*a) += 1;
return;
}
return 0;
}
22. Rotina Principal Função Variáveis
void main(void)
{
int x = 10; x=11
incptr(&x); void incptr
a=&x *
(int* a){
(*a) += 1;
return;
}
return 0;
}
23. Rotina Principal Função Variáveis
void main(void)
{
int x = 10; x=11
descartado
incptr(&x); void incptr
(int* a){
(*a) += 1;
return;
}
return 0;
}
24. 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.
25. 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.
26. Structs
typedef struct{
char titulo[30];
char producao[20];
char dataCompra[8];
int temporada;
float preco;
}t_serietv;
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 %dn", s1.temporada);
27. Structs
● O acesso dos typedef struct{
char nome[20];
membros internos int idade;
de estruturas }t_aluno;
apontadas por
ponteiros pode ser t_aluno *a1;
feito através do (*a1).nome = "Joao";
operador -> (*a1).idade = 18;
a1->nome = "Joao";
a1->idade = 18;
28. 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.
29. 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
30. 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.
31. 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.
32. Ponteiros para void
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);
}
33. 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;
}
}
34. 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);