Programar em C/Ponteiros: diferenças entre revisões

[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
Edudobay (discussão | contribs)
Edudobay (discussão | contribs)
Linha 293:
== Ponteiros para Ponteiros ==
 
Acompanhe este exemplo:
Nós já quase que fizemos este ponto mas há apenas um extra
char a;
char * b;
char ** c;
a = 'z'; //atribui a letra para ser guardada na variável a
b = &a; //atribui o endereço de a á variável b
c = &b; //atribui o endereço da variável b a a
**c='M'; //deferência
Repare que não é copiar o valor do ponteiro b, mas antes o endereço do próprio ponteiro!!
 
char a;
Repare ainda que para fazer a deferência no primeiro nível, por assim dizer termo de colocar **c.
char *b;
se tivesse “mais níveis”, mais ponteiros a apontarem para outros, teria de acrescentar mais *****…
char **c;
a = 'z';
b = &a;
c = &b;
**c = 'M';
 
Perceba que temos dois "níveis": ''c'' aponta para ''b'', e ''b'' aponta para ''a''. Assim, para acessar ''a'' usando o ponteiro ''c'', é necessário usar duas vezes o operador <code>*</code>: uma para obter o valor de ''b'' (cujo endereço está guardado em ''c''), e a outra para obter o valor de ''a'', apontado por ''b''.
 
Mais tarde veremos aplicações de ponteiros para ponteiros.
 
 
== Passando vetores como argumentos de funções ==
 
 
== Ponteiros para funções (passando uma função como argumento de outra) ==
Os ponteiros podem ser passados como argumentos de funções. Nisto
 
Parâmetro ponteiro passando um array.
#include <iostreamstdio.h>
using namespace std;
void assignValues(int[], int);
void displayValues(int[], int);
const int MAX = 3;
int main ()
{
int testScorevetorTeste[MAX3]; // crio array,um vetor sem atribuir valores
atribuiValores(vetorTeste, 3);
assignValues(testScore, MAX);//chamo função assign, dou parametro
displayValues mostraValores(testScorevetorTeste, MAX3);
system ("pause")return 0;
return 0;
}
void assignValues(int tests[], int num)
void atribuiValores(int valores[], int num)
{
for (int i = 0; i < num; i++)
{
cout << printf("EnterInsira testvalor score#%d: #" <<, i + 1 << ": ");
cin >>scanf("%d", tests&valores[i]);
}
}
void displayValues(int scores[], int elems)
void mostraValores(int valores[], int num)
{
for (int i = 0; i < elemsnum; i++)
{
cout << printf("TestValor score#%d: #%d\n" <<, i + 1, << ": " << scoresvalores[i] << endl);
}
}
 
Repare que eupassamos dou 2dois parâmetros quando chamopara as funções:
# O "nome" do vetor, que representa o seu endereço na memória. (Temos 3 maneiras para passar o endereço do vetor: diretamente pelo seu "nome", via um ponteiro ou pelo endereço do primeiro elemento.)
* Um é no nome do array, que equivale a dizer que é o address do array.
# Uma constante, que representa o número de elementos do vetor. Isso é importante pois o C não guarda informações sobre o tamanho dos vetores; você não deve tentar alterar ou acessar valores que não pertencem ao vetor.
(temos 3 maneiras para passar o endereço do array: nome do array, endereço do 1º termos, via pointer)
* O outro é uma constante
Mas o que é que significa passar o endereço? É que os valores do array são logo alterados, em vez de se criar uma variável copia.
 
É claro que devemos passar o endereço do vetor (por "referência"), pois os seus valores são alterados pela função atribuiValores. De nada adiantaria passar o vetor por valor, pois o valor só seria alterado localmente na função (como já vimos no caso de troca do valor de duas variáveis).
Vou escrever novamente o mesmo programa mas agora dando, pointer. Mas sem criar um.
#include <iostream>
using namespace std;
void assignValues(int*, int);
void displayValues(int*, int);
const int MAX = 3;
int main ()
{
int testScore[MAX]; //crio array
assignValues(testScore, MAX);//chamo função assign, dou parametro
displayValues(testScore, MAX);
system ("pause");
return 0;
}
void assignValues(int *tests, int num)
{
for (int i = 0; i < num; i++)
{
cout << "Enter test score #" << i + 1 << ": ";
cin >> tests[i];
}
}
void displayValues(int *scores, int elems)
{
for (int i = 0; i < elems; i++)
{
cout << "Test score #" << i + 1 << ": " << scores[i] << endl;
}
}
 
Por causa dessa equivalência entre vetores e ponteiros, podemos fazer uma pequena alteração no protótipo (tanto na declaração quanto na definição) das funções atribuiValores e mostraValores, sem precisar alterar o código interno dessas funções ou a chamada a elas dentro da função main ― trocando
A diferença entre os dois códigos está no protótipo e function headers
void assignValues(int[], int);
void assignValues(int*, int);
 
void atribuiValores(int[], int);
void mostraValores(int[], int);
por
void atribuiValores(int*, int);
void mostraValores(int*, int);
 
Para o compilador, você não fez mudança alguma, justamente por conta dessa equivalência. Em ambos os casos, foi passado o endereço do vetor para as funções.
 
Nestes dois casos anteriores utilizámos a passagem por referência e não por valor! ou seja, quando passámos os parâmetros, para as funções, os valores eram mesmo passados e não eram feitas nenhumas cópias, por isso modificações nos valores nas funções eram automaticamente traduzidas.
mas isto é nós fizemos no capitulo dos arrays, o que é novo é o uso dos ponteiros, do 2º exemplo.
 
 
Talvez seja melhor dar mais um problema: temos duas variáveis e quero trocar os valores.!
{| border 1
|1º PROGRAMA || 2º PROGRAMA || 3º PROGRAMA – por ponteiro
|-
|
#include <iostram>
using namespace std;
int main()
{
int a,b;
a=5;
b=10;
cout<<a<<”\t”<<b;
int t;
t=a;
a=b;
b=t;
cout<<a<<”\t”<<b;
system (“pause”);
return 0;
}
||
#include <iostram>
using namespace std;
void swap(int i, int j)
{
int t;
t=i;
i=j;
j=t;
}
int main()
{
int a,b;
a=5;
b=10;
cout<<a<<”\t”<<b;
swap(a,b);
cout<<a<<”\t”<<b;
system (“pause”);
return 0;
}
||
#include <iostram>
using namespace std;
void Swap (int *i,int *j)
{
int t;
t=*i;
*i=*j;
*j=t;
}
int main ()
{
int a,b;
a=5;
b=10;
cout<<a<<”\t”<<b;
Swap (&a,&b);
cout<<a<<”\t”<<b;
system (“pause”);
return 0;
}
|}
Resulta! porque estamos dentro do main Não resulta! porque temos passagem de valor e não referência Resulta temos passagem por referencia.
Fizemos via pointers.
veja-se o function header
function body
E a function call!
 
Não fiz a passagem por via array, mas aqui fica a proposta.