• Nenhum resultado encontrado

• Um ponteiro é uma variável que contém (armazena) um endereço de memória

N/A
N/A
Protected

Academic year: 2022

Share "• Um ponteiro é uma variável que contém (armazena) um endereço de memória"

Copied!
10
0
0

Texto

(1)

Ponteiros

Linguagem de Programação Estruturada Prof. Leandro Carlos Fernandes

2º semestre 2015

Ponteiros

• Um ponteiro é uma variável que contém (armazena) um endereço de memória

• Declaração:

tipo_dado *nome_ponteiro;

onde "*" indica que a variável é um ponteiro

• Ex: int x;

int *px; /* compilador sabe que px é ponteiro */

/* px é um ponteiro para inteiro */

Ponteiros

• O operador “&” quando aplicado sobre um identificador (nome de variável, por exemplo) retorna o seu endereço

• Ex: int x = 10, *pi;

pi = &x;

printf("&x: %p pi: %p", &x, pi);

• Saída em tela:

&x: 0x03062fd8 pi: 0x03062fd8

• O operador “*” quando aplicado sobre um ponteiro retorna o dado apontado

• Ex:

int main () { int *tmp_ptr;

int x, y;

x = 10;

tmp_ptr = &x;

y = *tmp_ptr;

return 0;

}

Ponteiros

0xABA0 0xABA0

10 10 10 10

0xABA2 0xABA0

:

x

y tmp_ptr 0xA000

(2)

Ponteiros

• ponteiros são variáveis tipadas:

(int *) ≠ (float *) ≠ (char *)

• Ex:

intmain() { int*ip, x;

float*fp, z;

ip = &x; /* OK */

fp = &z; /* OK */

ip = &z; /* erro */

fp = &x; /* erro */

return0;

}

(int *)

(float *)

1 byte (char *)

Utilizando Ponteiros

#include <stdio.h>

intmain() { intx = 10;

int*pi;

pi = &x; /* *pi é igual a 10 */

(*pi)++; /* *pi é igual a 11 */

printf("%d"x);

return0;

}

ao alterar *pi estamos alterando o conteúdo de x

Utilizando Ponteiros

#include <stdio.h>

intmain() { intx = 10;

int*pi, *pj;

pi = &x; /* *pi == 10 */

pj = pi; /* *pj == 10 */

(*pi)++; /* (*pi, *pj, x) == 11 */

(*pj)++; /* (*pi, *pj, x) == 12 */

printf("%d", x); /* Escreverá 12 */

return0;

}

PONTEIROS & PARÂMETROS DE

FUNÇÕES

(3)

Passagem de Informações

• Argumentos passados por referência

– Quando chamada, a função passa a referenciar (apontar) a variável informada

– Portanto o processo consiste em informar o endereço da variável para o que o parâmetro formal possa referenciá-lo.

– Os argumentos deixam de existir após a execução do método, porém as variáveis informadas e que foram referenciadas permanecem (pois não são dadas por este bloco de comandos).

9

Exemplo

#include <stdio.h>

/* Protótipos */

void funcPorVarlor(inta);

void funcPorRefer(int *b);

intmain () { intx = 0, y = 0;

funcPorValor(y);

printf("%d %d\n", x, y);

funcPorRefer(&y);

printf("%d %d\n", x, y);

return0;

}

/* Definição das subrotinas */

void funcPorVarlor(inta){

a = 1;

}

void funcPorRefer(int *b){

*b = 2; /* ... o conteúdo apontado por b recebe 2 */

}

• Note que as variáveis xe ysão locais a função main, enquanto os parâmetros ae bsão locais a funcPorValore funcPorRefer, respectivamente.

PONTEIROS & ARRAYS

Referenciando Arrays

• Pode-se referenciar os elementos de um array através de ponteiros

• Ex: float m[] = { 1.0, 3.0, 5.75, 2.345 };

float *pf;

pf = &m[2];

printf("%f", *pf); /* Escreve 5.75 */

(4)

Referenciando Elementos

• Pode-se utilizar ponteiros e colchetes:

float m[] = { 1.0, 3.0, 5.75, 2.345 };

float *pf;

pf = &m[2];

printf("%f", pf[0]); /* ==> 5.75 */

• Note que o valor entre colchetes é o

deslocamento a ser considerado a partir do endereço de referência

• pf[n] => indica n-ésimo elemento a partir de pf

Aritmética de Ponteiros

• É possível fazer operações aritméticas e relacionais entre ponteiros e inteiros

• Soma: ao somar-se um inteiro n a um ponteiro, endereçamos n elementos a mais (n positivo) ou a menos (n negativo)

• Assim, temos:

pf[2] equivale a *(pf+2)

*(pf + n) endereça n elementos a frente

*(pf - n) endereça n elementos atrás pf++ endereça próximo elemento array pf-- endereça elemento anterior array

Exemplo

#include <stdio.h>

int main () {

int arint[] = { 1,2,3,4,5,6,7 };

int size = 7; /* tamanho do array */

int i, *pi;

for (pi=arint, i=0; i < size; i++, pi++) printf("%d ", *pi);

return 0;

} /* saída: 1 2 3 4 5 6 7 */

Exemplo - Variação #1

#include <stdio.h>

int main () {

int arint[] = { 1,2,3,4,5,6,7 };

int size = 7; /* tamanho do array */

int i, *pi;

for (pi=arint, i=0; i < size; i++) printf("%d ", *pi++);

return 0;

} /* saída: 1 2 3 4 5 6 7 */

(5)

Exemplo - Variação #2

#include <stdio.h>

int main () {

int arint[] = { 1,2,3,4,5,6,7 };

int size = 7; /* tamanho do array */

int i, *pi;

pi = arint;

printf("%d ", *pi); pi+=2;

printf("%d ", *pi); pi+=2;

printf("%d ", *pi); pi+=2;

printf("%d ", *pi);

return 0;

} /* saída: 1 3 5 7 */

Operações Válidas Sobre Ponteiros

É válido

somar ou subtrair um inteiro a um ponteiro

(pi ± int)

incrementar ou decrementar ponteiros

(pi++, pi--)

subtrair ponteiros (produz um inteiro)

(pf - pi)

comparar ponteiros

( >, >=, <, <=, == )

Não é válido

• somar ponteiros

(pi + pf)

• multiplicar ou dividir ponteiros

(pi*pf, pi/pf)

• operar ponteiros com double ou float

(pi ± 2.0)

Ponteiros e Strings

Strings são arrays de caracteres e podem ser acessados através de char *

int main() {

char str[] = "abcdef", *pc;

for (pc = str; *pc != '\0'; pc++) putchar(*pc);

return 0;

}

• O incremento de pc o posiciona sobre o próximo caractere (byte a byte)

Array de Strings

• Neste caso, cada elemento do array é um ponteiro para um caractere.

• Declaração:

char *arstr[] = {"Joao", "Maria", "Antonio",

"Zacarias", "Carlos"};

• Neste caso arstr é um array de ponteiros para

char, iniciado com os strings indicados

(6)

Array de Strings

• Comparando array de string com matriz de char

char

*as[] = {"Joao","Maria","Antonio","Zacarias","Carlos"};

char

mc[5][10] = {"Joao","Maria","Antonio","Zacarias","Carlos"};

Ponteiros (as)

J o a o M a r i a A n t o n i o Z a c a r i a s C a r l o s

\0

\0

\0

\0

\0

Matriz (mc)

J o a o M a r i a A n t o n i o Z a c a r i a s C a r l o s

\0

\0

\0

\0

\0

Cuidados com Strings

• É comum esquecer de alocar uma área para armazenamento de caracteres

int

main() {

char

*pc; char str[] = "Um string";

strcpy(pc, str); /* erro! pc indeterminado */

...

return

0;

}

Registros (Structs)

SCE283 – Ling. de Programação e Aplicações

Prof. Leandro Carlos Fernandes

2º semestre 2008

Estruturas

Structs são coleções de dados heterogêneos agrupados em um mesmo elemento de dados

• Ex: armazenar as coordenadas (x,y) de um ponto:

24

(x, y)

(7)

Estruturas

• Declaração:

• A estrutura contém dois inteiros, x e y

• Neste caso, a estrutura foi definida e com ela duas variáveis, p1 e p2, foram declaradas (cada um contendo duas coordenadas).

25

(x, y)

struct

{

int

x;

int

y;

} p1, p2;

Declaração

• Formato da declaração:

• A estrutura pode agrupar um número arbitrário de dados de tipos diferentes

• Pode-se nomear a estrutura para aumentar a facilidade em referenciá-la

26

structnome_da_estrutura

{ tipo_1 dado_1;

tipo_2 dado_2;

...

tipo_n

dado_n;

} lista_de_variaveis;

Nomeando uma Estrutura

27

structponto { intx;

inty;

};

structponto p1, p2;

Para evitar a repetição

struct pontodefine um novo tipo de dado Pode-se definir novas variáveis do tipo ponto struct

{

int

x;

int

y;

} p1;

struct

{

int

x;

int

y;

} p2;

Estruturas

• Assim como as demais variáveis compostas, temos de ter a capacidade de manipular seus elementos individualmente.

• Acessando os dados:

nome_variavel_struct.campo

• Ex: p1.x = 10; /*atribuição */

p2.y = 15;

if (p1.x >= p2.x) && (p1.y >= p2.y) ...

28

(8)

Atribuição de Estruturas

• Tal qual a demais variáveis, é possível inicializar uma estrutura no momento de sua declaração:

struct

ponto p1 = { 220, 110 };

• A operação de atribuição entre estruturas do mesmo tipo pode acontecer de maneira direta:

struct

ponto p1 = { 220, 110 };

struct

ponto p2;

p2 = p1;

/* p2.x = p1.x e p2.y = p1.y */

Note que os campos correspondentes das estruturas são automaticamente copiados do destino para a fonte

29

Espaço alocado para uma Estrutura

struct aluno {

char nome[20]; /* array 20 bytes */

int idade; /* 4 bytes */

char matricula[8]; /* array 8 bytes */

};

struct aluno al;

strcpy( al.nome, "Assis“);

al.idade = 21;

strcpy( al.matricula, "00/0001");

30 struct aluno al

"Assis"

21

"00/0001"

Composição de Estruturas

• De fato, as structs definem novos tipos de dados (tipos do usuário) e portanto podem conter campos de qualquer tipo, quer sejam tipos básicos ou outros tipos definidos pelo usuário.

• Inclusive, suportam a definição de estruturas compostas de outras estruturas!

– Um retângulo poderia ser definido por dois pontos: o superior esquerdo e o inferior direito.

Composição de Estruturas

Acesso aos dados:

32

struct

retangulo {

struct

ponto cantoSupEsq;

struct

ponto cantoInfDir;

};

struct

retangulo r = { { 10, 20 }, { 30 , 40 } };

r.cantoSupEsq.x += 10;

r.cantoSupEsq.y -= 10;

(9)

STRUCTS & SUBROTINAS

Estruturas como retorno de função

struct ponto cria_ponto (int x, int y) { struct ponto tmp;

tmp.x = x;

tmp.y = y;

return tmp;

}

int main () {

struct ponto p = cria_ponto(10, 20);

...

return 0;

}

34

Estruturas como parâmetros para funções

• As operações entre membros das estruturas devem ser feitas membro a membro:

/* retorna uma cópia de p1 = p1 + p2 */

struct ponto soma_pts (struct ponto p1, struct ponto p2) { p1.x += p2.x;

p1.y += p2.y;

return p1; /* retorna uma copia de p1 */

}

35

Ponteiros para Estruturas

• Estruturas grandes são passadas como

parâmetro de forma mais eficiente através de ponteiros

struct ponto *pp;

struct ponto p1 = { 10, 20 };

pp = &p1;

printf("Ponto P1: (%d %d)\n", (*pp).x, (*pp).y};

• acesso via operador "->":

printf("Ponto P1: (%d %d)\n", pp->x, pp->y};

36

(10)

Exemplo

#include <stdio.h>

#include <stdlib.h>

structponto { intx,y;

};

voidsomaPorValor(structponto p, inta){

p.x += a;

p.y += a;

}

voidsomaPorRef(structponto *p, inta){

p->x += a;

p->y += a;

}

voidmain() {

structponto r = {0,0}, q;

q.x = 1; q.y = 2;

printf("r(%d,%d) q(%d,%d)", r.x, r.y, q.x, q.y);

r = q;

printf("r(%d,%d) q(%d,%d)", r.x, r.y, q.x, q.y);

somaPorValor(q,2);

printf("q(%d,%d)\n", q.x, q.y);

somaPorRef(&q,2);

printf("q(%d,%d)\n", q.x, q.y);

system("pause");

}

37

Exemplo

38

Referências

Documentos relacionados

potencialmente porque não são entendidos como tal pela maioria da população e porque não estão classificados — e, em parte, a uma lacuna consistente relativa à formação de

tidos para o Coefi ciente de Efi cácia Protéica para o leite de búfala, vaca e caseína como padrão, verifi caram que a caseína e o leite de vaca, não apresentaram diferença

Verificada a efetividade da proposta, a Comissão de Licitações declarou vencedor o licitante Francisco Souza Lima Helm, sendo o total do item 14 licitado o valor de

Com efeito, à semelhança da estratégia adoptada na investigação e publicação sistemática do espólio exumado no povoado pré ‑histórico de Leceia pelo escultor Álvaro de

BARHAM, 1982 (2), define as diferenças conceituais e campos de ação, tanto para en­ sino como investigação, entre Biomecânica e Cinesiologia Mecânica. Não trataremos

A meta prevista para este indicador era garantir a realização de exames complementares em dia a 100% de hipertensos e diabéticos do programa, por tanto não foi atingida,

No panorama internauta são vários os softwares à disposição do utilizador que servem para converter ficheiros PDF em flipbooks, que nada mais são que livros ou publicações

ABSTRACT: The toxicological effects of crude ethanolic extracts (CEE) of the seed and bark of Persea americana have been analyzed on larvae and pupae of