• Nenhum resultado encontrado

Ponteiros e Vetores INF Prof. Lucas Mello Schnorr 1 / 16

N/A
N/A
Protected

Academic year: 2021

Share "Ponteiros e Vetores INF Prof. Lucas Mello Schnorr 1 / 16"

Copied!
22
0
0

Texto

(1)

Ponteiros e Vetores

INF01202

(2)

Sumário

Ponteiros

I

Aritmética de ponteiros (lembrete)

I

Exemplo #1: aritmética

Ponteiros e vetores

I

Semelhanças

I

Exemplo #2

I

Diferenças

I

Exemplo #3

I

Exemplo #4

Passagem de vetores como referência

I

Exemplo #5 (leitura de valores)

I

Exemplo #6 (manipulação de string)

I

Exemplo #7 (copia invertido)

(3)

Aritmética de ponteiros (lembrete)

9 INF 01202 - Prof. Marcelo Walter – Aula 19

Aritmética de Ponteiros

–  Supondo um ponteiro inteiro p1, apontando para o

endereço de memória 2000: • p1++; // valor de p1 fica 2004 * • p1--; // valor de p1 fica 1996

• p1= p1 + 5; // p1 passa a apontar para 2000 + (5 X 4) * Cada inteiro ocupa 4 bytes neste exemplo. Isto varia de

arquitetura para arquitetura

2000 2004

2000

p1 2000 2004

2004

p1

Após p1++

Memória Endereços

(4)

Exemplo #1 a28-aritmetica.c

#include <stdio.h> int main() {

int i, *pi1, *pi2;

double d, *pd1, *pd2; char c, *pc1, *pc2; c = 'A'; d = 5.423; i = -20; pi1 = &i;

pi2 = pi1 + 1; // incrementa o espaco ocupado por um inteiro (4 bytes)

pd1 = &d;

pd2 = pd1 + 2; // incrementa duas vezes o espaco ocupado por um double (2*8 bytes)

pc1 = &c;

pc2 = pc1 - 1; // decrementa o espaco ocupado por um char (1 byte)

printf("Resultados em hexadecimal\n"); printf("pi1: %p, pi2: %p\n", pi1, pi2); printf("pd1: %p, pd2: %p\n", pd1, pd2); printf("pc1: %p, pc2: %p\n\n", pc1, pc2); printf("Resultados em decimal\n"); printf("pi1: %d, pi2: %d\n", pi1, pi2); printf("pd1: %d, pd2: %d\n", pd1, pd2); printf("pc1: %d, pc2: %d\n", pc1, pc2);

(5)

Ponteiros e vetores:

semelhanças

11 INF 01202 - Prof. Marcelo Walter – Aula 19

Semelhanças entre Ponteiros e Vetores

•  O nome de um vetor corresponde a um ponteiro constante, isto

é,

ao ponteiro para o primeiro elemento

. •  Em geral, as operações válidas para ponteiros podem ser

executadas com vetores.

•  Assim, as notações abaixo são equivalentes:

com vetores equivale a com ponteiros int v[100]; int *v;

v[i] ou *(v+i) *(v+i) ou v[i] &v[i] v+i

declaração de

vetor v

de inteiros com 100 elementos indica quevé umponteiroque aponta para o 1º elemento do vetor(v[0]),alocando a área necessária

declaração do

ponteiro v

apontapara a posiçãoinicial, mas

não aloca áreapara isso.

(6)

Exemplo #2 a28-semelhancas.c

#include <stdio.h>

#define TAM 2

int main() {

int v[TAM]; //alocação de vetor de inteiros de tamanho TAM int i;

printf("Leitura com acesso tipo ponteiro\n");

for (i = 0; i < TAM; i++)

scanf("%d",v+i); // ja eh ponteiro (sem o "e" comercial)

printf("Impressao com acesso tipo ponteiro\n");

for (i = 0; i < TAM; i++)

printf("%d ",*(v+i)); //acessamos o valor apontado por v+i

printf("\n");

printf("Impressao com acesso tipo vetor\n");

for (i = 0; i < TAM; i++)

printf("%d ",v[i]); //acessamos a posição i de v

printf("\n");

return 0; }

(7)

Ponteiros e vetores:

diferenças

(na declaração unicamente)

13 INF 01202 - Prof. Marcelo Walter – Aula 19

Diferença entre Ponteiros e Vetores

Declaração de

vetor

:

o compilador automaticamente

reserva um bloco de

memória

para que o vetor seja armazenado,

do tamanho

especificado na declaração

(mas não controla se o uso é

limitado à área reservada).

Declaração de

ponteiro

:

o compilador

aloca um ponteiro

para apontar para a

memória,

sem reservar espaço de memória

(usado para

alocação dinâmica de memória).

Por exemplo, considere:

int v[3]={1,2,3}; int *p;

p = v; //operação válida. Atribui a p o end do 1º elem de v v = p; //operação inválida (pois v aponta para um endereço fixo de memória)

(8)

Exemplo #3 a28-diferencas.c

#include <stdio.h> #define TAM 3 int main() { int v[TAM] = {1,2,3}; int *p;

p = v; //operação válida. Atribui a p o endereço do primeiro elemento de v

v = p; //operação inválida (pois v aponta para um endereço fixo de memória) return 0;

}

Compilando para ver

error

gcc a28-diferencas.c 2> x; cat x a28-diferencas.c: In function `main':

a28-diferencas.c:9:5: error: assignment to expression with array type

v = p; //operação inválida (pois v aponta para um endereço fixo de memória) ^

(9)

Exemplo #3 a28-diferencas.c

#include <stdio.h> #define TAM 3 int main() { int v[TAM] = {1,2,3}; int *p;

p = v; //operação válida. Atribui a p o endereço do primeiro elemento de v

v = p; //operação inválida (pois v aponta para um endereço fixo de memória) return 0;

}

Compilando para ver

error

gcc a28-diferencas.c 2> x; cat x a28-diferencas.c: In function `main':

a28-diferencas.c:9:5: error: assignment to expression with array type

v = p; //operação inválida (pois v aponta para um endereço fixo de memória) ^

(10)

Exemplo #4 a28-strings.c

Strings são vetores de caracteres.

#include <stdio.h> int main() {

char str[80] = "Alpha Centauri";

char *p1;

//atribui à p1 o endereço do primeiro elemento de str

p1 = str;

//imprimir o mesmo elementos com dois atalhos

printf("[%c] = [%c]\n", str[0], *p1);

// str[4] ou *(p1+4) acessam o 5o caractere (elemento) de str

printf("[%c] = [%c]\n", str[4], *(p1+4));

return 0; }

(11)

Resumo: Vetores são como se fossem ponteiros!

Slide 7 INF 01202

Uma variável que representa um vetor

corresponde a um endereço de memória.

Assim:

Vetores

são SEMPRE

passados por referência

!

Alterações feitas no vetor dentro da subrotina

modificam o mesmo

após a saída da subrotina!

Apenas

o endereço do primeiro elemento do vetor

é passado (v, ou equivalentemente, &v[0])

Dessa forma, o tamanho (comprimento) do

vetor também deve ser passado explicitamente

como argumento para a subrotina.

Vetores e parâmetros de funções

(12)

Exemplo #5 a28-levetor.c (leitura de valores)

Faça uma função le_vetor de oats que receba como parâmetro o vetor

a ser preenchido e o número de elementos a serem lidos:

#include <stdio.h>

#define TAM 3

void le_vetor(float vetor[], int num_vet) { //leitura de um vetor de floats int i; // variável local, para auxiliar leitura

printf("Entre os %d valores do vetor, separados por espaços\n",num_vet);

for (i = 0; i < num_vet; i++) scanf("%f",&vetor[i]);

return; }

int main() {

int i; //contador float vec[TAM];

printf("leitura de %d elementos \n", TAM);

le_vetor(vec, TAM); //<-- veja a chamada da função for (i = 0; i < TAM; i++) // escrita do vetor

printf("%.2f ", vec[i]); printf("\n");

return 0; }

(13)

Exemplo #5 a28-levetor.c (leitura de valores)

Faça uma função le_vetor de oats que receba como parâmetro o vetor

a ser preenchido e o número de elementos a serem lidos:

#include <stdio.h>

#define TAM 3

void le_vetor(float vetor[], int num_vet) { //leitura de um vetor de floats int i; // variável local, para auxiliar leitura

printf("Entre os %d valores do vetor, separados por espaços\n",num_vet);

for (i = 0; i < num_vet; i++) scanf("%f",&vetor[i]);

return; }

int main() {

int i; //contador float vec[TAM];

printf("leitura de %d elementos \n", TAM);

le_vetor(vec, TAM); //<-- veja a chamada da função for (i = 0; i < TAM; i++) // escrita do vetor

printf("%.2f ", vec[i]); printf("\n");

return 0; }

(14)

Observação sobre o Exemplo #5

Slide 9 INF 01202

Exercício 1 : função void, para leitura de um vetor:

• Exemplo de execução

Observação:

• A declaração void le_vetor(float vetor[ ], int num_vet)

(15)

Exemplo #6 a28-upper.c (manipulação de string)

Faça uma função void que receba como parâmetro uma string e converta

todos seus caracteres para maiúsculas.

#include <stdio.h>

void nosso_upper (char str[]) {

int i = 0; //contador inicializado na primeira posicao da string while(str[i] != '\0') {

str[i] = toupper(str[i]); i++;

} }

Uma segunda versão:

void nosso_upper_v2 (char str[]) {

while(*str != '\0'){

*str = toupper(*str); str++;

} }

(16)

Exemplo #6 a28-upper.c (manipulação de string)

Faça uma função void que receba como parâmetro uma string e converta

todos seus caracteres para maiúsculas.

#include <stdio.h>

void nosso_upper (char str[]) {

int i = 0; //contador inicializado na primeira posicao da string while(str[i] != '\0') {

str[i] = toupper(str[i]); i++;

} }

Uma segunda versão:

void nosso_upper_v2 (char str[]) {

while(*str != '\0'){

*str = toupper(*str); str++;

} }

(17)

Exemplo #7 a28-inverte.c (copia invertido)

Faça uma função void inverte(char* str1, char* str2), que copie

o conteúdo de str1 invertido (caracteres de trás para frente) em str2.

#include <stdio.h>

#include <string.h>

#define TAM 20

void inverte(char* str1, char* str2);

int main() {

char c1[TAM], c2[TAM]; fgets(c1, TAM, stdin); c1[strlen(c1)-1] = '\0'; inverte_texto(c1, c2);

printf("[%s] -> [%s]\n", c1, c2);

return 0; }

void inverte(char* str1, char* str2) {

int i, n = strlen(str1);

for (i = 0; i < n; i++) str2[i] = str1[n - 1 - i]; str2[i] = '\0';

(18)

Exemplo #7 a28-inverte.c (copia invertido)

Faça uma função void inverte(char* str1, char* str2), que copie

o conteúdo de str1 invertido (caracteres de trás para frente) em str2.

#include <stdio.h>

#include <string.h>

#define TAM 20

void inverte(char* str1, char* str2);

int main() {

char c1[TAM], c2[TAM]; fgets(c1, TAM, stdin); c1[strlen(c1)-1] = '\0'; inverte_texto(c1, c2);

printf("[%s] -> [%s]\n", c1, c2);

return 0; }

void inverte(char* str1, char* str2) {

int i, n = strlen(str1);

for (i = 0; i < n; i++) str2[i] = str1[n - 1 - i]; str2[i] = '\0';

(19)

Exemplo #8 a28-maior.c (ponteiro para maior)

Uma função também pode retornar um ponteiro

Escreva uma função em C que receba como parâmetro um vetor de

inteiros, e retorne um ponteiro apontando para a posição do maior

elemento do vetor

#include <stdio.h>

// função tipo ponteiro inteiro int *maior(int vet[], int tamanho) {

int i, *p; // índice e ponteiro de elemento do vetor

p = vet; // aponta para 1o elemento do vetor for (i = 0; i < tamanho; i++)

if (vet[i] > *p)

p = vet + i; // passa a apontar para o maior valor return p; // retorna o ponteiro

}

int main() {

int vet[] = {3, 1, 8, 4}, *m = NULL; m = maior (vet, 4);

return 0; }

(20)

Exemplo #8 a28-maior.c (ponteiro para maior)

Uma função também pode retornar um ponteiro

Escreva uma função em C que receba como parâmetro um vetor de

inteiros, e retorne um ponteiro apontando para a posição do maior

elemento do vetor

#include <stdio.h>

// função tipo ponteiro inteiro int *maior(int vet[], int tamanho) {

int i, *p; // índice e ponteiro de elemento do vetor

p = vet; // aponta para 1o elemento do vetor for (i = 0; i < tamanho; i++)

if (vet[i] > *p)

p = vet + i; // passa a apontar para o maior valor return p; // retorna o ponteiro

}

int main() {

int vet[] = {3, 1, 8, 4}, *m = NULL; m = maior (vet, 4);

return 0; }

(21)

Exemplo #8 a28-maior.c (ponteiro para maior)

Uma função também pode retornar um ponteiro

Escreva uma função em C que receba como parâmetro um vetor de

inteiros, e retorne um ponteiro apontando para a posição do maior

elemento do vetor

#include <stdio.h>

// função tipo ponteiro inteiro int *maior(int vet[], int tamanho) {

int i, *p; // índice e ponteiro de elemento do vetor

p = vet; // aponta para 1o elemento do vetor for (i = 0; i < tamanho; i++)

if (vet[i] > *p)

p = vet + i; // passa a apontar para o maior valor return p; // retorna o ponteiro

}

int main() {

int vet[] = {3, 1, 8, 4}, *m = NULL; m = maior (vet, 4);

return 0; }

(22)

Observação sobre o Exemplo #8

Slide 17 INF 01202

Não se deve retornar um ponteiro para uma

variável criada na subrotina (pois é local)!!!

O ponteiro retornado acaba se referindo a

uma variável que foi passada como

parâmetro para a sobrotina!!!

Cuidados quando a função retornar

ponteiros

Referências

Documentos relacionados

aprovada, será assinada pela Presidente, Professora Nilda de Fátima Ferreira Soares e

Se a temperatura interna no forno for superior àquela proposta para o programa escolhido, o display TEMPERATURA irá mostrar a escrita “Hot” e não será possível iniciar a

• Maior satisfação do cliente.. Engenharia de Software Testes de Software Indicadores para Governança Frameworks Assuntos escolhidos.. Abordagem utilizada Montagem do

É preciso entender que, no sistema Lean, os indicadores de manufatura, por si só, não são capazes de fornecer um retrato preciso do cenário global da organização: eles precisam

Nossas ações, incluindo a transformação digital e os esforços em relação à gestão de pessoas, são orientadas para a satisfação dos nossos clientes, métrica-chave para toda

g) 20% vinte por cento) sobre o valor do Contrato, nas hipóteses de recusa na assinatura do Contrato, rescisão contratual por inexecução do Contrato - caracterizando-se quando

Importante: é necessário que as coordenações dos Programas de Pós-Graduação tenham cadastrado no SIGAA as suas linhas de pesquisa, caso contrário, não será possível selecionar

Pela especial característica de sua atuação, na origem, unitizando e embarcando container com emissão de BL (função de transportador) e, no destino, recebendo cargas de outro