PCI-Ponteiros

Propaganda
Programação de Computadores I –
Ponteiros
Profa. Mercedes Gonzales
Márquez
Ponteiros - Manipulação



Declaração: <tipo> *<identificador>
int *p;
float *q;
O operador unário & captura o endereço de um
objeto. p = &x;
O operador unário * é um operador de indireção:
quando aplicado a um apontador, acessa o
conteúdo do objeto apontado. x = *p;
Ponteiros - Manipulação
int vet[4];
vet aponta para vet[0] (vet[0]==*vet) e
- vet+1 aponta para vet[1] e *(vet+1) refere-se ao
conteúdo de vet[1]
– vet+i aponta para vet[i] e *(vet+i) refere-se ao
conteúdo de vet[i]

Ponteiros - Manipulação
int vet[4];
int *pa;
pa = &vet[0];
pa
vet
Se pa aponta para vet[0], então:
- pa+1 aponta para vet[1] e pa+i aponta para vet[i].

Aritmética de ponteiros


Todas as operações sobre ponteiros levam em
conta o tamanho do tipo apontado .
Operações válidas de ponteiros:
–
–
–
–
–
Atribuição entre ponteiros do mesmo tipo
Adição/Subtração entre um ponteiro e um inteiro.
Comparação entre dois ponteiros que apontam a
elemntos do mesmo array.
Subtração entre dois ponteiros que apontam a
elementos do mesmo array.
Atribuição ou comparação com zero (NULL)
Aritmética de Ponteiros

Incremento/decremento: Se p é um ponteiro a
tipo T, p++ incrementa o valor de p em sizeof(T)
(onde sizeof(T) é a quantidade de armazenagem
necessária para um dado de tipo T).
Similarmente, p-- decrementa p em sizeof(T);
T tab[N];
T * p;
int i;
p=&tab[i];
p++; // p contem o endereço de tab[i+1];
Aritmética de Ponteiros

Adição/subtração com um inteiro: Se p é um
ponteiro a tipo T e n é um inteiro, p+n
incrementa o valor de p em n*sizeof(T).
Similarmente, p-n decrementa p em n*sizeof(T);
T tab[N];
T * p;
p=tab;
p=p+n; // p contem o endereço de tab[n];
Aritmética de Ponteiros



Comparação de dois ponteiros.
– Se p e q aponta a membros do mesmo
array, então são válidas as relações como
==, !=, <, >=, etc. Por exemplo, p<q é
verdade se p aponta a um elemento anterior
do array que q aponta.
Subtração de ponteiros:
– Se p e q apontam a elementos do mesmo
array, e p<q, então q-p+1 é o número de
elementos de p até q inclusive.
O comportamento é indefinido para aritmética
ou comparação com ponteiros que não
apontam a membros do mesmo array.
Examplo de subtração de ponteiros
/* strlen: returna o comprimento da string s */
int strlen(char *s){
char *p = s;
while (*p != '\0')
p++;
return p - s;
}
Ponteiros e strings
char
a[] = “aprendendo ponteiros"; /* um array */
char *p = “aprendendo ponteiros"; /* um ponteiro */


a
aprendendo ponteiros\0
p
aprendendo ponteiros\0
a é um array, apenas do tamanho suficiente para
armazenar a sequência de caracteres e '\0.
p é um ponteiro inicializado para apontar uma string
constante;
Ponteiros - Exercícios
int x=3, y=5, *p=&x, *q=&y, *r;
double z;
Expressão
p==&x
**&p
r=&z
7**p/*q+7
*(&y)*=*p
Valor
1
3
erro
11
15
Ponteiros

Exemplo O que será impresso pelo programa
abaixo considerando que os valores lidos nas
variáveis x e y sejam 2 e 5,respectivamente?
Ponteiros

Exemplo O que será impresso pelo programa
abaixo considerando que os valores lidos nas
variáveis x e y sejam 2 e 5,respectivamente?
Ponteiros

Exemplo O que faz o trecho de programa abaixo?
Ponteiros para registros


Ao criarmos uma variável de um tipo struct, esta e
armazenada na memoria como qualquer outra
variável, e portanto possui um endereço.
Exemplo
#include <stdio.h>
typedef struct {
double x;
double y;
} Coordenada;
int main(){
Coordenada c1, c2, *c3;
c3 = &c1;
Ponteiros para registros
Para acessarmos os campos de uma variavel struct via um
ponteiro, podemos utilizar o operador * juntamente com o
operador . como de costume:
Coordenada c1, *c3;
c3 = &c1;
(*c3).x = 1.5;
(*c3).y = 1.5;
 Em C também podemos usar o operador -> para acessar
campos de uma estrutura via um ponteiro. Podemos obter o
mesmo resultado do exemplo anterior:
Coordenada c1, *c3;
c3 = &c1;
c3->x = 1.5; c3->y = 1.5;

Ponteiros para registros
Resumindo: Para acessar campos de estruturas via
ponteiros use um dos dois:
 ponteiroEstrutura->campo
 (*ponteiroEstrutura).campo
Exercício 1:
 Vamos criar as seguinte funcões:
 void leCoordenada3D(Coordenada3d *f);: lê dados de uma
ponto no espaço tridimensional com coordenadas (x,y,z)
passada como ponteiro. (Por quê como ponteiro?)
 void imprimeCoordenada3D(Coordenada3d f); Imprime
coordenadas de um ponto.
 O programa principal que requeira a leitura de 5 pontos no
espaço tridimensional.

Ponteiros para registros

Coordenada3d ProdutoEscalar(Coordenada3d
v1,Coordenada3d v2)
onde produto_escalar=<v1,v2>=v1.x*v2.x+v1.y*v2.y
Alocação dinámica



função malloc
– Parâmetro: tamanho desejado, em bytes
– Resultado: apontador para espaço na memória
Programa
int *p;
p = (int*)malloc(4);
*p = 5;
printf("%d", *p);
Alocação dinámica
função free:
– Parâmetro: endereço já alocado
– Resultado: libera a área alocada
Programa
int *p;
p = (int*)malloc(4);
*p = 5;
free(p);

Alocação dinámica
função sizeof:
 sizeof(variavel)
– Retorna quantidade de memória ocupada pela variável
 sizeof(tipo)
– Retorna quantidade de memória ocupada por uma variável
com este tipo.
VETOR DINÂMICO
• Calcular tamanho do vetor com sizeof
• Reservar memória com malloc
• Acessar elementos com [ ] ou ponteiros
• Liberar memória do vetor com free
Alocação dinámica

Exemplo: Alocação dinámica de um vetor
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
int * vet;
int i;
printf("Input number of elements: \n");
scanf("%d", &n);
if ((vet=(int *)malloc(n * sizeof(int)))==NULL) {
printf(“Erro de alocação de memoria !\n");
exit(1);
}
for (i=0; i<n; i++)
scanf("%d", &vet[i]);
for (i=0; i<n; i++)
printf("%d ", vet[i]);
free(vet);
}
Alocação dinámica de strings
void main(void) {
char sir1[40];
char *sir2;
printf(“Informe uma string: \n");
scanf("%40s", sir1);
if ((sir2=(char *)malloc(strlen(sir1)+1))==NULL) {
printf(“Erro na alocação de memória !\n");
exit(1);
}
strcpy(sir2, sir1);
printf(“A cópia e: %s \n", sir2);
..........
}
Alocação dinámica
Exercício 2. O exercício 1 pedia para ingressar 5 pontos do
espaço tridimensional, agora considere um vetor de pontos
de tamanho dinâmico.
Exercícios
Exercício 3. O que será impresso pelo programa abaixo:
#include <stdio.h>
typedef struct{
int x;
int y;
} T;
void f1(T *a){
f2(&(a->x));
f2(&(a->y));
}
void f2(int *b){
*b = 2*(*b);
Exercícios
int main(){
T a, b, *c, *d;
c = &a;
a.x = 2;
a.y = 4;
b.x = 2;
b.y = 2;
d = c;
f1(d);
b = *d;
printf("x: %d --- y: %d\n",b.x,b.y);
}
Função que retorna um ponteiro
int * soma_vetor4(int *a, int *b, int n) {
int * r;
r=(int *) malloc(sizeof (int) * n);
if (r==NULL) exit(1);
int i;
for (i=0; i<n; i++, a++, b++)
r[i]=*a+*b;
return r;
}
…
int a[3]={1,2,3};
int b[3]={4,5,6};
int * rr;
rr=soma_vetor4(a,b,3);
imprime_vetor(rr,3);
Download