Buscar

[NEW] Resumo_Ponteiro

Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original

Resumo Ponteiro:
*********************************************************************************
OBS: Essa matéria é cobrada na P2 e P3!
********************************************************************************* 
Antes de aprender a usar ponteiro é importantíssimo entender a diferença entre passagem por valor e passagem por referência.
OBS: Recomendo relembrar o que é Passagem por valor, só dar uma olhada no final do bloco "Resumo_Função" :)
---------------------------------------//--------------------------------------
- Passagem por referência:
Uma função recebe como parâmetro o endereço de uma variável ao invés de uma cópia de seu valor.
Ex: Faça um programa que inicializa 2 variáveis com valor 5 e 10 respectivamente e crie uma função que recebe como parâmetro o endereço dessas variáveis e faz a troca do seu conteúdo. Imprima o conteúdo das variáveis antes e depois da troca. 
void troca (int *num, int *num2){
 int temp;
 temp = *num;
 *num = *num2;
 *num2 = temp;
}
int main (void){
 int num, num2;
 num = 5;
 num2 = 10;
 printf("num vale: %d\nNum2 vale: %d\n",num, num2);
 troca ( &num, &num2);
 printf("num vale: %d\nNum2 vale: %d\n",num, num2);
 return 0;
}
 
Chamei a função troca e enviei como parâmetro o endereço da variável num e num2. 
Precisamos usar o >> & << antes do nome da variável, pois o & representa o endereço daquela variável. (Só lembrar de como é feito a leitura no scanf!)
Tentar explicar de uma forma bem simples: 
Toda variável que declaramos possui um endereço, como se fosse uma casinha, ela mora em algum lugar na memória do pc e dentro dessa casinha tem o conteúdo dela (algum valor) que será 'lixo de memória' se vc não tiver inicializado ela ainda.
Lembrando que no momento que declaramos um variável: int num, num2; 
Ela possui lixo de memória! E não podemos acessar seu conteúdo e nem fazer contas antes de inicializar!
OBS: Lembra que na passagem de valor é feito uma cópia do valor da variável? "Copia" o valor da variável local num e num 2 da main e "cola" esses valores nas variáveis locais da função troca! Lembrando que se são variáveis diferentes, possuem endereços diferentes também! 
Então se vc só passar pra função uma cópia desse valor (Passagem por valor), a função não pode fazer nenhuma alteração pq ela não tem o endereço onde a variável mora! 
Mas...Se enviarmos pra função o endereço da variável (Passagem por referência/Ponteiro), ai sim! A função vai saber onde a variável mora e pode ir até lá e alterar o conteúdo dela! (Sim, invasão total de domicílio :D )
------------------------------------//----------------------------------------
- Quando se deve usar ponteiro?
Sempre que o enunciado pedir que uma função >> Retorne << mais de um valor. 
Lembrando que qualquer função só pode retornar no máximo >> 1 << valor.
Sempre que o enunciado pedir que você use passagem por referência.
Se o enunciado disser que uma função recebe o endereço de uma variável como parâmetro, isso é o mesmo que dizer que a função recebe um ponteiro!
------------------------------------//---------------------------------------
- Como se usa um ponteiro? 
Considerando o exemplo do começo do bloco:
O primeiro passo é interpretar no enunciado quantos, quais e onde vamos precisar usar ponteiro.
Como já vimos que o enunciado deixa bem claro que a função troca recebe como parâmetro o endereço de duas variáveis da main. É certeza total que vamos precisar usar dois ponteiros!
Então vamos criar na função main variáveis comuns: 
int num, num2;
Próximo passo é chamar a função que vai receber o ponteiro e enviar o endereço das variáveis como parâmetro. Cuidado pra >> Não << esquecer do &!
troca ( &num, &num2);
Analisando o protótipo da função troca: Ela espera receber dois ponteiros. 
Então temos que colocar o >> * << antes do nome de cada variável do parâmetro!
void troca (int *num, int *num2){
Próximo passo é trocar o conteúdo de num e num2.
Se vc escrever num = 10; vai dar um erro, porque nessa função >> num << é um endereço de memória! Então a única forma de acessar seu conteúdo é usando o >> * << antes de num para acessar e alterar o conteúdo daquele endereço!
OBS: Percebe que se fizermos *num = *num2, vamos perder o valor que estava em *num? E isso Seria triste né? :(
Por isso precisamos criar uma variável temporária pra "Salvar" o valor armazenado em num! E só depois podemos fazer a troca!
temp = *num;
*num = *num2;
*num2 = temp;
Nessa parte acabamos de atruibuir o valor 10 que é o conteúdo de num2 em num1.
E o valor que salvamos em temp em num2.
OBS: >>QUALQUER<< alteração feita através do endereço de uma variável, é uma alteração >>Definitiva<<! Ou seja, a alteração vale pro programa inteiro! Independente da variável num e num2 serem variáveis locais da main ou de qualquer outra função!
A partir de agora, a variável num que está lá na main também vale 10! 
 
printf("num vale: %d\n",num); 
O valor impresso será 10. Porque a modificação feita na função troca é válida pro programa inteiro!
------------------------------------//-----------------------------------------
- Qual a vantagem de usar ponteiro? 
É a única forma de uma função "Retornar" mais de um valor, pois na verdade ela não está retornando e sim alterando o conteúdo daquela variável através do seu endereço.
Qualquer modificação feita pela função no conteúdo da variável (ponteiro), modifica o conteúdo dela no programa inteiro! Se fosse uma variável comum, qualquer alteração só iria valer apenas pra função que fez a alteração! (Variável local)
 
------------------------------------//----------------------------------------
- Pegadinhas de prova: 
EX: Faça uma função chamada le_notas que recebe como parâmetro o endereço de uma variável do tipo int e peça pro usuário digitar a sua nota:
void le_notas(int *nota){
 puts("Digite sua nota: ");
 scanf("%d",nota);
}
int main (void){
 int nota;
 le_notas(&nota);
 return 0;
} 
Notou algo diferente no scanf? Pois é...Até então todo scanf tinha o & ao lado do nome da variável, será que eu esqueci? :D
É aí é que tá! Lembra que a palavra "nota" sozinha representa um endereço? 
E como o scanf precisa de um endereço pra poder armazenar o que usuário digitar, nesse caso, e >>SOMENTE<< nesse caso, >>Não<< usamos o & na leitura do Scanf!
-----------------------------------//-------------------------------------------
EX: Crie uma função que leia notas de vários usuários e depois retorne o somatório das notas e a quantidade de notas lidas por referência.
OBS: Wait! Uma função que >> Retorna << dois valores!? :o
Já sabemos que qualquer função retorna >> no máximo << um valor! Então obrigatoriamente o segundo será através de ponteiro! E como o enunciado já deixou claro que um dos valores retornados será por referência, tudo faz sentido! :)
OBS: Em alguns casos o enunciado exige que todos os valores sejam retornados por referência! Então nesse caso o tipo de retorno da função será >> void <<! 
int le_notas (int *qtd){
 int nota, soma = 0;
 do{
 puts("Digite a nota ou -1 para encerrar: ");
 scanf("%d",&nota);
 if(nota != -1){
 soma+= nota;
 (*qtd)++;
 }
 }while(nota != -1); 
 
 return soma;
}
int main (void){
 int qtd, total;
 total = le_notas(&qtd);
 printf("Somatorio: %d\nQuantidade de notas lidas: %d\n",total, qtd);
 return 0;
}
OBS: Não lembra como usa o 'do while'? Ouviu falar num negócio chamado repetição, mas já esqueceu porque pensou que só ia cair na P1? :D
Sem problemas! Recomendo que leia urgentemente meu "Resumo_Repetição" :)
O interessante nessa questão é justamente a forma como um ponteiro é usado como contador. Na parte que o contador é incrementado!
(*qtd)++;
Muito cuidado! É obrigatório
o uso dos parênteses! Pensa assim: É como se fosse uma forma de dizer que queremos incrementar o conteúdo daquele endereço e não o endereço em si!
Cuidado! Esse é um dos erros mais comuns em toda P2 e P3!
-------------------------------------//----------------------------------------

Teste o Premium para desbloquear

Aproveite todos os benefícios por 3 dias sem pagar! 😉
Já tem cadastro?

Continue navegando