Beruflich Dokumente
Kultur Dokumente
3 13/9/2011 19:48
Perguntas
Como fao para passar uma varivel para uma funo e,
ao final da funo, o valor DA VARIVEL ser alterado?
Ex.: Escreva uma funo de soma simples que receba como
parmetro a varivel local resultado, operador1 e operador2
Ao fim da funo a varivel resultado DEVE ter o valor
4 13/9/2011 19:48
Ex 1 Soma sem ponteiros
void soma(int resultado, int op1, int op2)
{
resultado = op1+op2;
}
5 13/9/2011 19:48
Seus Problemas Acabaram!
PONTEIROS!
6 13/9/2011 19:48
O que so ponteiros? *
Normalmente, toda varivel C declarada para armazenar
um valor numrico (bytes):
int servem para armazenar valores inteiros
float para armazenar valores numricos com preciso simples,e
assim por diante
Esses tipos fazem referncia a um determinado valor
Int a um num inteiro, float a um num fracionado, etc.
Existe um tipo particular de varivel em C que, ao invs de
conter valores numricos, armazena endereos de memria:
So os ponteiros (ou apontadores).
Um ponteiro uma varivel declarada para armazenar o endereo
de memria onde est armazenada outra varivel.
Declarando ponteiros
Como ponteiros so variveis, logo preciso declar-los para poder utiz-los
Exemplo de declarao:
int *p;
float *pParaFloat;
8 13/9/2011 19:48
Operadores especficos para
Ponteiros
9 13/9/2011 19:48
Inicializando Ponteiros
Nenhum ponteiro pode ser usado antes de ser inicializado
Enquanto no apontarem para um endereo vlido, tem-se o risco de o
programa ser abortado pelo sistema operacional por ter causado uma
operao ilegal (acesso endereo invlido de memria).
A popular falha de segmentao ou segmentation fault.
Logo, preciso inicializar todo ponteiro antes de podermos utiliz-los. Mas
como?
Pergunta-se:
Se um ponteiro deve referenciar (apontar, conter) o endereo de memria de
uma varivel como inicializo um ponteiro int *p com o endereo de int i?
Ex:
main(){
int *p, i;
p = ??;
}
10 13/9/2011 19:48
Inicializando Ponteiros
A maneira mais simples de inicializar um ponteiro
faz-lo apontar para uma varivel existente.
Ex.:
main(){
int *p, i;
p = &i;
}
Observe que se atribui o ENDEREO de i para p. NO o
valor! Pois p um PONTEIRO
Agora p contm o endereo de i;
Logo p aponta para o endereo de i
11 13/9/2011 19:48
Lendo o valor de uma varivel
apontada por um ponteiro
Para ter acesso ao valor (contedo) de uma varivel a qual um ponteiro aponta,
usa a sintaxe
*nomeDoPonteiro
L-se valor apontado por ponteiro
No exemplo
main(){
int *p, i =1;
p = &i;
}
Se se quiser ler o valor de i de maneira indireta atravs do ponteiro p, faz-se:
*p;
Ex.:
main(){
int *p, i=1;
p = &i;
cout << Contedo (valor) do endereo apontado por p << *p;
}
12 13/9/2011 19:48
Testando Referncia Indireta
int main(void)
{
int v=25, *p;
p = &v; /* p aponta para v */
cout << v: << v << p: << *p;
*p = 50; /* atribuio por referencia indireta */
cout << v: << v << p: << *p;
}
Sada: ??
Implemente e descubra por que?
13 13/9/2011 19:48
Aplicaes de Ponteiros
14 13/9/2011 19:48
Passagem de parmetros por
referncia em funes
Voltemos ao problema do Slide 3
Perguntas
Como fao para passar uma varivel para uma funo e,
ao final da funo, o valor DA VARIVEL ser alterado?
Ex.: Escreva uma funo de soma simples que receba como
parmetro a varivel local resultado, operador1 e operador2
Ao fim da funo a varivel resultado DEVE ter o valor
MAS COMO???
Veja o arquivo Ex1
16 13/9/2011 19:48
Ex 1 Soma sem ponteiros
void soma(int resultado, int op1, int op2)
{
resultado = op1+op2;
}
17 13/9/2011 19:48
Agora, como resolver
o problema?
Programando
18 13/9/2011 19:48
Soluo
#include <cstdlib>
#include <iostream>
using namespace std;
void soma(int *presultado, int op1, int op2)
{
*presultado = op1+op2;
}
int main()
{
int resultado;
int op1=2;
int op2=2;
soma(&resultado, op1, op2);
cout << "Resultado: " << resultado << endl;
//Que valor vai ser apresentado?
}
19 13/9/2011 19:48
Recapitulando
O que na realidade se quer que se possa acessar a
varivel resultado indiretamente dentro do corpo da
funo soma
Ento, qual a varivel que preciso ter na funo para
poder referenciar o contedo de outra?
?
Onde preciso ter a referncia ?
?
Como e onde a declaro para tal fim?
?
20 13/9/2011 19:48
Recapitulando
O que na realidade se quer que se possa acessar a
varivel resultado indiretamente dentro do corpo da
funo soma
Ento, qual a varivel que preciso ter para poder
referenciar o contedo de outra?
Uma varivel ponteiro
Onde preciso ter a referncia?
Dentro da funo soma
Como declaro para tal fim?
Preciso ter dentro da funo soma uma referncia a
resultado
21 13/9/2011 19:48
Soluo
Declaro o ponteiro para referenciar a
#include <cstdlib> resultado
#include <iostream>
using namespace std;
void soma( int *presultado, int op1, int op2)
{
*presultado = op1+op2;
} Atribuo ao valor apontado por presultado (ou
seja, a var resultado),
int main()
{
int resultado;
int op1=2;
int op2=2;
soma(&resultado, op1, op2);
cout << "Resultado: " << resultado << endl;
//Que valor vai ser apresentado?
Aqui passo o ENDERECO de resultado para a
} varivel ponteiro *presultado que usar o
endereo para poder
referenciar a varivel.
22 13/9/2011 19:48
Concluindo
Tendo um parmetro ponteiro em uma funo, posso
passar um endereo de uma varivel ao chamar esta
funo
void funcao(float *p)
23 13/9/2011 19:48
Ponteiros para estruturas de
dados compostas
24 13/9/2011 19:48
Ponteiros para vetores
Uma varivel representa um espao em memria para armazenar um
determinado tipo de valor
Um vetor uma varivel que capaz de armazenar N vezes um determinado
tipo
Em se tratando de vetores, o nome do vetor representa o endereo de memria
onde se inicia o armazenamento do vetor
O ndice (entre []) representa o deslocamento que se faz a partir do incio do
vetor na memria.
Logo, o ndice [0] representa o incio daquele vetor a partir do endereo de
memria onde se inicia o armazenamento do vetor;
[1] a prxima posio na memria; e assim por diante
Portanto, em C, quando se refere a um vetor, sem especificar seu ndice
(somente com o nome da varivel), se est referenciando o ENDEREO DE
MEMRIA da 1 posio de um vetor
25 13/9/2011 19:48
Ponteiros para vetores
Assim, em C
&vetor[0] o mesmo que vetor
Assim, como inicializo um ponteiro para um vetor ?
Ex.:
int vetor[] = {0,1,2,4,6};
int *pVetor;
?
26 13/9/2011 19:48
Ponteiros para vetores
Assim, em C
&vetor[0] o mesmo que vetor
Assim, como inicializo um ponteiro para um vetor ?
Ex.:
int vetor[] = {0,1,2,4,6};
int *pVetor;
pVetor = &vetor[0];
OU
pVetor = vetor;
27 13/9/2011 19:48
Resposta
Pois apontando para o incio da memria do vetor,
posso percorr-lo at o seu final indicando o
DESLOCAMENTO (posio do vetor) que se quer
acessar
Ex.: no ponteiro pVetor, acessando-se pVetor[2], se estar
acessando a terceira posio do vetor.
28 13/9/2011 19:48
Exemplo
int main(void)
{
char txt[100], *p;
int i;
cout << "Digite algo: ";
cin >> txt;
p=txt; /* p = &txt[0] */
cout << "Um caracter por linha:\n";
for(i=0; p[i]!='\0'; i++)
cout << p[i] << "\n"; /* p[i] corresponde a txt[i] */
getchar();
return(0);
}
29 13/9/2011 19:48
Ponteiros para matrizes
(vetor = arranjo de uma dimenso);
p = m; // p = m[0]; // p = (int**)m
for(i=0; i<2; i++ )
{
cout << "\n";
for(j=0; j<2; j++)
cout << "\t " << m[i][j];
}
getchar();
return 0;
}
RECADO IMPORTANTE
Se seu compilador no permitir fazer, por exemplo:
int *p, i=1;
p = &i;
Dando um erro como:
/home/elder/PED/TesteGDB/main.cpp|20|error: cannot convert int [2][2] to int* in assignment
preciso fazer um cast para tipo do ponteiro que se est querendo atribuir,
ficando assim:
TIPO *p; i=1;
p = (TIPO*) i;
Na prtica:
int *p, i=1;
p = (int*) &i;
Ponteiros para Registros(struct)
Quando se trata de ponteiros que apontam para variveis do tipo struct, deve-se
observar uma peculiaridade
Quando se deseja acessar um campo do registro atravs de um ponteiro,
deve-se substituir o delimitador . (ponto) pela seta (->) SEM PRECEDER O
PONTEIRO PELO *
Exemplo:
struct data
{
int dia; int mes; int ano;
};
struct data hoje={17, 7, 2002};
struct data *ptr;
ptr = &hoje;
cout << "Ano: " << ptr->ano;
Outra forma de se acessar:
(*ptr).ano;
(*ptr).dia;