Você está na página 1de 24

Na aula passada…

Tipos de funções:
•  Funções void*: não retornam valor associado à função
1.  sem parâmetros (parâmetros void*)
2.  com parâmetros:
1.  passados por valor
2.  passados por referência (endereço)
•  Funções tipadas ou com retorno: devolvem um único
valor associado a execução da função, usando o comando
return.
1.  sem parâmetros (parâmetros void*)
2.  com parâmetros.
1.  passador por valor
2.  passados por referência (endereço)

1 INF 01202 - Prof. Marcelo Walter – Aula 19


O que são ponteiros?

•  Ponteiros são variáveis que guardam endereços de memória.

A posição de memória 1000 armazena o endereço de


memória 1003, cujo conteúdo é o caracter D.

O endereço é a posição de uma outra variável na memória


Se uma variável a armazena o endereço de uma variável b,
dizemos que a aponta para b.

2 INF 01202 - Prof. Marcelo Walter – Aula 19


Declaração de Ponteiros
  Sintaxe:
  tipo *nome_da_variavel_ponteiro;

asterisco indica que a variável


armazena um endereço de memória,
cujo conteúdo é do tipo especificado.

qualquer tipo válido em C

Exemplos:
float *f; // f é um ponteiro para variáveis do tipo float
int *p; // p é um ponteiro para variáveis do tipo inteiro
char a, b, *p, c, *q; // pode declarar junto com variáveis de mesmo tipo

3 INF 01202 - Prof. Marcelo Walter – Aula 19


Operadores de Ponteiros

operador unário, que devolve o endereço de memória de seu


& operando

operador unário que devolve o valor da variável localizada


* no endereço que o segue

void troca(int *x, int *y) int main()


{ // conteúdo dos endereços
int temp; {
int a=5, b=10;
temp=*x; printf("a=%p b=%p\n",&a,&b);
*x = *y; printf("a=%d b=%d\n",a,b);
*y = temp; troca(&a,&b); //aqui, endereços
printf(“\n*** Na funcao\n:”);
printf("a=%d b=%d\n",a,b);
printf(”x=%d-y=%d\n", *x,*y);
printf(”x=%p-y=%p\n", x, y);
return 0;
} }
•  Fazer uma função que receba 2 inteiros x e y e troque seus
4 valores. INF 01202 - Prof. Marcelo Walter – Aula 19
Estruturando Programas

•  Dado um problema, qual a melhor maneira de


estruturar em funções?
•  As opções são:
–  Funções void
•  Sem parâmetros
•  Parâmetros por valor
•  Parâmetros por referência
–  Funções Tipadas
•  Sem parâmetros
•  Parâmetros por valor
•  Parâmetros por referência

•  Lembrando que uma mesma função pode receber ao


mesmo tempo parâmetros por valor e/ou referência.
Ex:
void baskara(float a, float b, float c, float *r1, float *r2)

5 INF 01202 - Prof. Marcelo Walter – Aula 19


Exemplos:
Faça um programa que calcula as médias aritmética, harmônica e geométrica
de 3 números. O programa exibe um menu de opções ao usuário.
int main()
{
float a,b,c; Função tipada que retorna int
int op, sair=0;
do{ Função void param por referência
op=menu();
if (op>=1 && op<=3) le_3_numeros(&a, &b, &c);
switch(op){
case 1: printf(“A media aritmetica vale %3.2f\n”, media_aritmetica(a,b,c));
break;
case 2: printf(“A media harmonica vale %3.2f\n”, media_harmonica(a,b,c));
break;
case 3: printf(“A media geometrica vale %3.2f\n”, media_geometrica(a,b,c));
break;
case 4: sair = 1; break;
default: printf(“Opcao invalida!\n”);
}
}while(!sair); Função tipada que retorna float
return 0;
} INF 01202 - Prof. Marcelo Walter – Aula 19
6
Protótipos das funções

int menu();
float media_aritmetica(float n1, float n2, float n3);
float media_harmonica(float n1, float n2, float n3);
float media_geometrica(float n1, float n2, float n3);

void le_3_numeros(float *n1, float *n2, float *n3);

7 INF 01202 - Prof. Marcelo Walter – Aula 19


Aula de hoje: Aritmética de Ponteiros
•  Adição e Subtração de ponteiros:
–  Ponteiro é um endereço de memória

–  Podemos somar ou subtrair inteiros de ponteiros

–  O valor do ponteiro irá aumentar ou diminuir,


dependendo do número de bytes que o tipo base
ocupa, isto é, o endereço de memória apontado será
deslocado em tantos bytes quanto forem os
reservados para o tipo associado ao ponteiro

8 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

Memória

2000
p1 2000 2004 Endereços

Após p1++

2004
p1 2000 2004
9 INF 01202 - Prof. Marcelo Walter – Aula 19
Aritmética de Ponteiros: exemplos
/* Programa para ilustrar algumas operações com ponteiros */
#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);

return 0;
}
10 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
declaração do ponteiro v
de inteiros com 100
aponta para a posição inicial, mas
elementos indica que v é
não aloca área para isso.
um ponteiro que aponta
para o 1º elemento do
vetor (v[0]), alocando a
área necessária

11 INF 01202 - Prof. Marcelo Walter – Aula 19


Semelhanças entre Ponteiros e Vetores
Exemplo:
#include <stdio.h>

int main()
{
int v[5];
int i;
printf("Leitura com acesso tipo ponteiro\n");
for (i = 0; i < 5; i++)
scanf("%d",v+i); // ja eh ponteiro, nao vai &

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


for (i = 0; i < 5; i++)
printf("%d ",*(v+i));

printf(”\nImpressao com acesso tipo vetor\n");


for (i = 0; i < 5; i++)
printf("%d ",v[i]);

printf("\n");

return 0;
}
12 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)
13 INF 01202 - Prof. Marcelo Walter – Aula 19
Ex 1: Vetores como parâmetros por referência
•  Faça uma função le_vetor de floats que receba como parâmetro o vetor a
ser preenchido e o número de elementos a serem lidos :
•  Por referência: preenche o vetor
•  Por valor: número de elementos a serem lidos
#include <stdio.h>

#define NUMELEM 5
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]);
}
Flexibilidade.
int main() Podemos variar o num
{
int i;
de elementos como
float vec[40]; necessário, dentro do
printf(“leitura de 5 elementos \n");
le_vetor(vec, NUMELEM);
máximo permitido (40
neste caso)
for (i=0; i < NUMELEM; i++)
printf(“%f ”, vec[i]);
return 0; void le_vetor(float *vetor, int num_vet)
}
14 Maneira
INF 01202 - Prof. Marcelo Walter – Aulaalternativa
19
Vetores e parâmetros de funções

•  Vetores são ponteiros. Assim:


–  Vetores são SEMPRE passados por referência!

–  Alterações feitas no vetor dentro da subrotina


o modificam após a saída da subrotina!
–  Apenas o endereço do primeiro elemento do
vetor é passado (v, ou seja, & v[0])
•  Dessa forma, o tamanho (comprimento) do vetor
também deve ser passado como argumento para
a subrotina.

15 INF 01202 - Prof. Marcelo Walter – Aula 19


Matrizes e parâmetros

•  Passagem de arrays com mais de uma dimensão em C um


pouco mais trabalhosa
•  Todas as dimensões (com exceção da primeira) devem ser
fixas na declaração da função.
•  Há outras possibilidades (fora do escopo da disciplina)

Exemplo:

void funcao1 (float array1[][10]);


void funcao2 (int array2[][20][30]);
// a primeira dimensão não precisa ser especificada, mas as
demais DEVEM!

16 INF 01202 - Prof. Marcelo Walter – Aula 19


Exercício

Escreva uma função em C que receba uma matriz (com


dimensões conhecidas NLIN x NCOL, dadas através
de um #define), e imprima os elementos da matriz
na tela.

17 INF 01202 - Prof. Marcelo Walter – Aula 19


// Exemplo de uso de funcao com passagem de matrizes como parametros
#include <stdio.h>
#define NCOL 10
#define NLIN 5

void imprime_matriz (int mat[][NCOL]) // imprime matriz de tamanho NLIN x NCOL


{
int i,j;
for (i = 0; i < NLIN; i++)
{
for (j = 0; j < NCOL; j++)
printf("%2d ",mat[i][j]);
printf("\n"); // quebra de linha ao final de cada linha da matriz
}
}
int main()
{
int mat[NLIN][NCOL];
int i,j;
// preenche a matriz com a soma dos elementos de linha e colun
for (i = 0; i < NLIN; i++)
for (j = 0; j < NCOL; j++)
mat[i][j] = i + j;
imprime_matriz(mat); //imprime a matriz
return 0;
}
18 INF 01202 - Prof. Marcelo Walter – Aula 19
Exercício

Escreva uma função em C que receba uma matriz e o


numero de linhas e colunas e troca todos os
elementos da diagonal principal por 0 (zero). O
tamanho máximo de linhas e colunas é 5. O programa
principal deve ler do usuário o valor para o número
de linhas e colunas, a matriz e imprimir a matriz
original e a matriz resultante após a conversão.

19 INF 01202 - Prof. Marcelo Walter – Aula 19


20 INF 01202 - Prof. Marcelo Walter – Aula 19
21 INF 01202 - Prof. Marcelo Walter – Aula 19
Ex 2
•  função que devolve o maior elemento de um vetor de inteiros, e sua posição
(nome do vetor passado como parâmetro, respostas devolvidas através de
parâmetros), com o seguinte protótipo:

int omaior( int vetor[], int num_elem, int *posicao);

Retorna o maior valor pelo retorno da função

Retorna a posição dentro do vetor como parâmetro


por referência

22 INF 01202 - Prof. Marcelo Walter – Aula 19


#include <stdio.h>
#define MAXELEM 40

int main()
{
int maior, posicao;
int vec[MAXELEM];

printf(“leitura de 5 elementos \n");


le_vetor(vec, 5);

maior = omaior(vec,5,&posicao);
printf(“O maior elemento do vetor eh %d na posicao %d\n”, maior, posicao);
return 0;
}

23 INF 01202 - Prof. Marcelo Walter – Aula 19


#include <stdio.h>
#define MAXELEM 40

int omaior(int v[ ], int num_vet, int *pos) //


{
int i, maior=v[0];
*pos=0;
for (i=1; i < num_vet; i++){
if (v[i] > maior){
maior=v[i];
*pos=i;
}
}
return maior;
}

void le_vetor(int vetor[ ], int num_vet) //leitura de um vetor de inteiros


{
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(“%d”,&vetor[i]);
} Adaptamos a função le_vetor de floats para
ler inteiros

24 INF 01202 - Prof. Marcelo Walter – Aula 19

Você também pode gostar