Buscar

3 PONTEIROS

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 81 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 81 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 81 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
ALGORITMOS E ESTRUTURA DE DADOS
PONTEIROS
UNIDADE
3
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
3 PONTEIROS
3.1 Conceitos iniciais
3.2 Aplicações
ROTEIRO
PROFESSOR: EDILSON LIMA
*/35
ROTEIRO
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Para iniciarmos um estudo sobre Ponteiro primeiro temos que entender o que acontece quando declaramos uma variável.
Int A;
Nesse momento o computado armazena um espaço na memória RAM para ser guardado qualquer valor do tipo inteiro a variável A.
A memória do computador é dividida em bytes. Nos locais (bytes) que o computador vai armazenar as informações atribuídas as variáveis, esses locais (exemplo a posição na memoria o endereço 104) estarão em hexadecimal.
3 PONTEIROS
...
A
104
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
A função da memória RAM é guardar dados temporariamente para que o processador possa acessar informações importantes com rapidez. Só para deixar mais claro, toda variável que você declara é guardado um lugar para armazenar os dados atribuídos a essa variável.
char A;
float B;
int A;
25,5
100
A
104 – variável A no endereço com valor igual a 100
...
B
108 – variável B no endereço com valor igual a 25,5
C
112 – variável C no endereço com valor igual a X
3 PONTEIROS
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Sendo assim, nós podemos manipular o conteúdo de uma variável utilizando ela mesmo ou utilizando o seu endereço.
A linguagem C oferece um tipo especial de variável chamado PONTEIRO.
3 PONTEIROS
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Ponteiros (ou Apontadores) 
 
Uma das características mais poderosas oferecidas pela Linguagem C, é a utilização de ponteiros. Os ponteiros são vistos pela maioria das pessoas como um dos tópicos mais difíceis de qualquer linguagem de programação.
 
Um ponteiro, proporciona um modo de acesso as variáveis sem referenciá-las diretamente. O mecanismo usado para isto é o endereço da variável na memória do computador. De fato, o endereço age como intermediário entre a variável e o programa que o acessa.
 
Um ponteiro pode ser entendido como sendo uma representação simbólica de um endereço da memória do computador.
3.1 Conceitos iniciais
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Por que ponteiros são usados? 
Em situações em que a passagem de valores é difícil ou indesejável. Algumas razões para o uso de ponteiros:
 
a) Fornecem maneiras com as quais as funções podem realmente modificar os argumentos que recebem; 
b) Para passar matrizes e textos (strings) mais convenientemente de uma função para outra, isso é, usa-los ao invés de matrizes;
c) Para manipular matrizes mais facilmente através da movimentação de ponteiros para elas (ou parte delas), em vez de a própria matriz; 
d) Para criar estruturas de dados complexas, como listas encadeadas e árvores binárias, onde uma estrutura de dados deve conter referências sobre outra;
e) Para comunicar informações sobre memória, como na função malloc() que retorna a localização de memória livre através do uso de ponteiro; e
f) Uma outra razão importante para o uso de ponteiros é que notações de ponteiros compilam mais rapidamente tornando o código mais eficiente.
3.1 Conceitos iniciais
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Por que evitar o uso de ponteiros? 
 
O uso de ponteiros pelas linguagens de programação foi muito debatido e questionado por muitos que eram contra e a favor de seu uso.
 
Contudo, podemos citar alguns bons motivos para se evitar o uso de ponteiros mesmo que a linguagem de programação que você está utilizando, o provenha com recursos para utilização dos mesmos
3.1 Conceitos iniciais
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
O uso de ponteiros:
a) Torna a programação de um código qualquer muito mais complexa;
b) Dificulta o entendimento de um código;
c) Dificulta a manutenção de um código, principalmente se não foi você quem o escreveu, pois, ao tornar o entendimento mais difícil, consequentemente, o uso de ponteiros torna a manutenção do código, também, mais difícil;
d) A eficiência que se ganha no código com o uso de ponteiros, torna-se irrelevante diante da velocidade das máquinas atuais. E também, é claro, se o código for bem escrito usando as estruturas alternativas; e
e) As linguagens de programação mais recentes no mercado atualmente não provêem recursos para a utilização de ponteiros. (Ex.: “Java” e “.Net”).
3.1 Conceitos iniciais
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Utilizando Ponteiros 
 
Sabemos como fazer para declaramos uma variável normal, do tipo inteiro por exemplo:
 
Declaração de uma variável típica na linguagem C.
int NUM;
 
A declaração de ponteiros na linguagem C. 
Int *PNUM;
3.2 Aplicações
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Exemplo de Utilização de Ponteiros 
O software abaixo, adiciona 3 ao valor da variável X, sem a sua utilização direta.
#include <cstdlib>
#include <iostream>
 
using namespace std; 
 
int main(int argc, char *argv[])
{
 int X = 10;		//atribuir a variável X o valor 10
 int *PX;		//declaramos de um ponteiro (*) do tipo inteiro ponteiro
 
 PX = &X;		//atribui o endereço de X ao ponteiro PX; 
 
 cout << "O valor da variável X é: " << X;
 
 *PX = *PX + 3;
 
 cout << "\n\nO valor da variável X é: " << X << "\n\n";
 system("PAUSE");
 return EXIT_SUCCESS;
}
3.2 Aplicações
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
UMA RÁPIDA EXPLICAÇÃO SOBRE O EXEMPLO:
 
Foram criadas duas variáveis: X e PX, ambas do tipo inteiro.
Contudo, quando fizemos a seguinte declaração:
 
Int *PX; //A declaração de um ponteiro para uma variável do tipo inteiro, e não uma declaração de uma variável do tipo inteiro.
 
Em seguida veio a declaração de atribuição de valores:
PX = &X; //Nesta declaração, não estamos passando para PX o valor armazenado em X (que até então era 10). Ao contrário, estamos passando o endereço na memória RAM ocupado pela variável X. Ou seja, acabamos de criar um ponteiro, de nome PX, para a variável X.
 
Em seguida foi impresso o valor da variável X (até aqui, 10).
Logo é feita a seguinte declaração:
*PX = *PX + 3; //A atribuição acima parece estar adicionando ao valor de PX o valor 3. Contudo, PX não é uma variável, e sim um ponteiro, que aponta para o endereço da variável X.
Neste caso, é como se estivéssemos atribuindo o valor 3 para a variável X, pois, apesar de não estarmos trabalhando diretamente com a variável X, estamos trabalhando com o valor contido na posição de memória que a variável X ocupa.
 
E para finalizar, ao imprimirmos novamente o valor da variável X, veremos que este será igual a 13, pois, seu valor foi acrescido de 3 através da utilização de uma operação de adição utilizando o ponteiro PX.
3.2 Aplicações
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
ROTEIRO
PROFESSOR: EDILSON LIMA
*/81
ILUSTRAÇÃO
O operador unário & (“endereço de”), aplicado a variáveis, resulta no endereço da posição da memória reservada para a variável. 
O operador unário * (“conteúdo de”), aplicado a variáveis do tipo ponteiro, acessa o conteúdo do endereço de memória armazenado pela variável ponteiro.
3.2 Aplicações
10
...
*PX
108 – é declarado o ponteiro PX do tipo inteiro
X
104 – variável X é declarada e atribuído o valor 10
104
*PX
108 – PX recebe o endereço de memória da variável X (PX = &X)
13
*PX
108 – soma 3 ao valor que está no endereço 104 (10) 
 10 + 3 = 13
 *PX = *PX + 3
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
A possibilidade de manipular ponteiros de variáveis é uma das maiorespotencialidades de C. Por outro lado, o uso indevido desta manipulação é o maior causador de programas que "voam", isto é, não só não funcionam como, pior ainda, podem gerar efeitos colaterais não previstos.
3.2 Aplicações
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Exemplo:
#include <cstdlib>
#include <iostream>
using namespace std;
int main (int argc, char *argv[])
{
 int a, b, *p;
 a = 2;
	 *p = 3;
	 b = a + (*p);
 printf ("%i", b);
 system("PAUSE");
 return EXIT_SUCCESS;
}
3.2 Aplicações
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Cometemos um ERRO típico de manipulação de ponteiros. O pior é que esse programa, embora incorreto, às vezes pode funcionar. O erro está em usar a memória apontada por p para armazenar o valor 3. Ora, a variável p não tinha sido inicializada e, portanto, tinha armazenado um valor (no caso, endereço) "lixo". Assim, a atribuição *p = 3; armazena 3 num espaço de memória desconhecido, que tanto pode ser um espaço de memória não utilizado, e aí o programa aparentemente funciona bem, quanto um espaço que armazena outras informações fundamentais – por exemplo, o espaço de memória utilizado por outras variáveis ou outros aplicativos. Neste caso, o erro pode ter efeitos colaterais indesejados.
Portanto, só podemos preencher o conteúdo de um ponteiro se este tiver sido devidamente inicializado, isto é, ele deve apontar para um espaço de memória onde já se prevê o armazenamento de valores do tipo em questão.
3.2 Aplicações
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
De maneira análoga, podemos declarar ponteiros de outros tipos:
float *m; 
char *s;
3.2 Aplicações
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Operações com ponteiros
Igualar dois ponteiros:
Fazendo com que p1 aponte para o mesmo lugar que p2 p1=p2.
Para a variável apontada por p1 tenha o mesmo conteúdo da variável apontada por p2 *p1=*p2. 
incremento e decremento
Quando incrementamos um ponteiro ele passa a apontar para o próximo valor do mesmo tipo para o qual o ponteiro aponta. Isto é, se temos um ponteiro para um inteiro e o incrementamos ele passa a apontar para o próximo inteiro.
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Esta é mais uma razão pela qual o compilador precisa saber o tipo de um ponteiro: se você incrementa um ponteiro char* ele anda 1 byte na memória e se você incrementa um ponteiro double* ele anda 8 bytes na memória. O decremento funciona semelhantemente. Supondo que p é um ponteiro:
Estamos falando de operações com ponteiros e não de operações com o conteúdo das variáveis para as quais eles apontam. Para incrementar o conteúdo da variável apontada pelo ponteiro p, faz-se: (*p)++;
P++;
P--;
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Soma e subtração de inteiros com ponteiros. Vamos supor que você queira
incrementar um ponteiro de 15: 
Para usar o conteúdo do ponteiro 15 posições adiante;
p=p+15;
p+=15
*(p+15);
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Comparação entre dois ponteiros.
Para saber se dois ponteiros são iguais ou diferentes (== e !=).
No caso de operações do tipo >, <, >= e <= estamos comparando qual ponteiro aponta para uma posição mais alta na memória. Então uma comparação entre ponteiros pode nos dizer qual dos dois está mais adiante na memória. A comparação entre dois ponteiros se escreve como a comparação entre outras duas variáveis quaisquer: p1>p2 
Há entretanto operações que você não pode efetuar num ponteiro. Você não pode dividir ou multiplicar ponteiros, adicionar dois ponteiros, adicionar ou subtrair floats ou doubles de ponteiros.
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Outros Exemplos Utilizando Ponteiro
A aplicação seguinte utiliza ponteiros, através de variáveis globais, para simular uma calculadora de quatro operações. Passando os valores através de ponteiros para a respectiva função solicitada pelo usuário.
#include <cstdlib>
#include <iostream>
 
using namespace std;
 
int *P1Valor, *P2Valor;
 
int Adicao () { 
 return (*P1Valor + *P2Valor);
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
int Subtracao () { 
 return (*P1Valor - *P2Valor);
}
float Divisao () { 
 return (*P1Valor / *P2Valor);
} 
int Multiplicacao () {
 return (*P1Valor * *P2Valor);
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
int main (int argc, char *argv[]) 
{ 
 int PrimeiroValor, SegundoValor;
 int opcao;
 
 P1Valor = &PrimeiroValor;
 P2Valor = &SegundoValor;
 
 cout << "Entre com o primeiro valor: ";
 cin >> PrimeiroValor;
 cout << "\nEntre com o segundo valor: "; 
 cin >> SegundoValor;
 
 cout << "\n\nEscolha a operação a ser efetuada com os valores
digitados:";
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
 cout << "\n 1 - Adição"; 
 cout << "\n 2 - Subtração";
 cout << "\n 3 - Divisão";
 cout << "\n 4 - Multiplicação";
 cout << "\n\n\n Opção: ";
 cin >> opcao;
 
 switch (opcao) {
 case 1: 
 cout << "\n\nO valor da Adição é: " << Adicao ();
 break; 
 case 2:
 cout << "\n\nO valor da Subtração é: " << Subtracao (); 
 break;
 case 3:
 cout << "\n\nO valor da Divisão é: " << Divisao ();
 break;
 
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
		case 4:
 cout << "\n\nO valor da Multiplicação é: " << Multiplicacao ();
 } 
 
 cout << "\n\n\n";
 system("PAUSE");
 return EXIT_SUCCESS;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Vetores e Ponteiros
Da mesma forma que se cria uma variável ponteiro, pode-se criar também um vetor de ponteiros. O vetor de ponteiros é útil quando se trabalha com informações de tamanho diferente. Por exemplo, para ordenar um vetor de inteiros, pode-se trocar os elementos porque todos têm o mesmo comprimento em bytes. Mas, para ordenar texto, é necessário mais do que uma única operação de comparação. Um vetor de ponteiros é dado através da seguinte definição: 
tipo *nome_ponteiro[tamanho];
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Vetores e Ponteiros
Quando uma matriz é declarada da seguinte forma:
O compilador C calcula o tamanho, em bytes, necessário para armazenar a matriz.
O compilador então aloca este número de bytes em um espaço livre de memória.
O nome da variável é um ponteiro para o tipo da variável da matriz.
Tendo alocado na memória o espaço para a matriz, ele toma o nome da variável (que é um ponteiro) e aponta para o primeiro elemento da matriz.
tipo_variavel nome_varial [tamanha];
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
No C, a indexação começa com zero. É porque, ao pegarmos o valor do primeiro elemento de um vetor, queremos, de fato, *nome_da_variável e então devemos ter um índice igual a zero.
Apesar de, na maioria dos casos, não fazer muito sentido, poderíamos ter índices negativos. Estaríamos pegando posições de memória antes do vetor. Estaríamos pegando posições de memória antes do vetor.
Isto explica porque o C não verifica a validade dos índices. Ele não sabe o tamanho do vetor. Ele apenas aloca a memória, ajusta o ponteiro do nome do vetor para o início do mesmo e, quando você usa os índices, encontra os elementos requisitados.
PROFESSOR: EDILSON LIMA
*/81
Varredura sequencial de uma matriz.
//Vetor
int main (){
	float matrx [50][50];
	int i,j;
	for (i=0;i<50;i++)
		for (j=0;j<50;j++)
			matrx[i][j]=0.0;
	return(0);
}
//Usando ponteiro
int main (){
	float matrx [50][50];
	float *p;
	int count;
	p=matrx[0];
	for(count=0;count<2500;count++){
		*p=0.0;
	return(0);}
No primeiro programa, cada vez que se faz matrx[i][j] o programa tem que calcular o deslocamento para dar ao ponteiro. Ou seja, o programa tem que calcular 2500 deslocamentos. No segundo programa o único cálculo que deve ser feito é o de um incremento de ponteiro. Fazer 2500 incrementos em um ponteiro é muito mais rápido que calcular 2500 deslocamentos completos.
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Há uma diferença entre o nome de um vetor e um ponteiro: um ponteiro é uma variável, mas o nome de um vetor não é uma variável. Isto significa, que não se consegue alterar o endereço que é apontado pelo "nome do vetor":
int vetor[10];
int *ponteiro, i;
ponteiro = &i; 	/* as operacoes a seguir sao invalidas */
vetor = vetor + 2; 	/* ERRADO: vetor nao e' variavel */
vetor++; 		/* ERRADO: vetor nao e' variavel */
vetor++; 		/* ERRADO: vetor nao e' variavel */
vetor = ponteiro; 	/* ERRADO: vetor nao e' variavel */
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Alguns compiladores dirão que vetor não é um Lvalue. Lvalue, significa "Left value", um símbolo que pode ser colocado do lado esquerdo de uma expressão de atribuição, isto é, uma variável. Outros compiladores dirão que tem-se "incompatible types in assignment", tipos incompatíveis em uma atribuição.
/* as operacoes abaixo sao validas */
ponteiro = vetor; 	/* CERTO: ponteiro e' variavel */
ponteiro = vetor+2; 	/* CERTO: ponteiro e' variavel */
O nome de um vetor é um ponteiro constante.
Podemos indexar o nome de um vetor. 
Podemos indexar um ponteiro qualquer. 
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Exemplo
#include <stdio.h>
int main ()
{
	int matrx [10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int *p;
	p=matrx;
	printf ("O terceiro elemento do vetor e: %d", p[2]);
	return(0);
}
Podemos ver que p[2] equivale a *(p+2). 
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
O software a seguir cria um vetor de quatro posições, preenche as quatro posições de memória e depois, através de ponteiros, faz a inversão do mesmo e imprime os valores no vídeo. 
 
Se observarmos atentamente o código, notaremos a falta do caracter “*” (asterisco), que representa “ponteiro” em Linguagem C. Contudo é válido explicar que o nome de uma matriz, é um ponteiro constante, ou seja, diferente dos ponteiros que criamos para acessar outras variáveis e que podem ter o endereço apontado modificado, o nome da matriz aponta sempre para um mesmo endereço, por isto o nome de ponteiro constante. Resumindo, ao criarmos uma matriz, na verdade estamos criando um ponteiro para um endereço fixo na memória (vale lembrar que é fixo em quanto a matriz existir dentro do programa), assim sendo, quando passamos uma matriz como argumento em uma função, não precisamos na função, especificar o argumento com o caracter “*”.
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <cstdlib>
#include <iostream>
#define MAX 4
using namespace std;
void InverteValoresVetor (int VX[]) {
 VX [0] = 4;
 VX [1] = 3;
 VX [2] = 2;
 VX [3] = 1; 
}
void ImprimeVetor (int VX[]) {
 cout << "\n\n";
 for (int P = 0; P < MAX; P++) {
 cout << "\nValor Vetor Posição: " << P << " = " << VX [P];
 }
 cout << "\n\n";
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
int main (int argc, char *argv[]) 
{
 int Vetor [MAX]; 
 
 Vetor [0] = 1;
 Vetor [1] = 2;
 Vetor [2] = 3;
 Vetor [3] = 4;
 
 ImprimeVetor (Vetor);
 
 InverteValoresVetor (Vetor);
 
 ImprimeVetor (Vetor);
 system("PAUSE");
 return EXIT_SUCCESS;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
A seguir temos um software que cria uma matriz 2 x 2 de números inteiros. As posições da matriz são preenchidas com os números de 1 a 4. Temos também uma função de inversão dos valores e uma de impressão da matriz. Neste caso, os parâmetros das funções “InverteValoresMatriz” e “ImprimeMatriz” são ponteiros mas, sem o uso do caracter “*” (asterisco). Essa é uma particularidade dos vetores e das matrizes. Nos primeiros colchetes dos parâmetros de ambas as funções não existem um valor fixo delimitando a quantidade de colunas da matriz, contudo, existe um valor fixo delimitando a quantidade de linhas da matriz. Essa é outra particularidade das matrizes, ou seja, da segunda dimensão em diante é necessário especificar o valor da dimensão. Para vetores, passados como parâmetro em funções não é necessário especificar valor algum. Por terem somente uma dimensão, somente a presença dos colchetes já é o suficiente para que o compilador entenda que receberá um vetor como parâmetro.
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <cstdlib>
#include <iostream>
 
#define MAXCOL 2
#define MAXLIN 2
 
using namespace std;
 
void InverteValoresMatriz (int MX[][MAXLIN]) {
 MX [0][0] = 4;
 MX [0][1] = 3;
 MX [1][0] = 2;
 MX [1][1] = 1;
}
 
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
void ImprimeMatriz (int MX[][MAXLIN]) {
 cout << "\n\n";
 for (int C = 0; C < MAXCOL; C++) {
 for (int L = 0; L < MAXLIN; L++) {
 cout << "\nValor Matriz Coluna: " << C << " Linha: " << L << " 
= " << MX [C][L];
 } 
 }
 cout << "\n\n";
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Utilizando ponteiro em matriz
Dados do tipo matriz podem ser indexados através de ponteiros, como mostram os exemplos a seguir:
Dados do tipo matriz podem ser indexados através de ponteiros, como mostram os exemplos a seguir:
Exemplo 1 
{
	int v[10]; 
	int *p; // o sinal * indica que a variável é do tipo ponteiro
	p = v; //atribui a p o endereço do primeiro elemento de vetor 
}
 
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Exemplo 2 
{
 int i[10]; 
	int *p; // o sinal * indica que a variável é do tipo ponteiro
	p = i; // atribui a p o endereço do primeiro elemento de i 
	p[5] = 100; // 6º elemento recebe 100 usando o índice
	*(p+5) = 100; // 6º elemento recebe 100
}
Dado o vetor i[10] definido como expresso a seguir:
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Se declaramos um ponteiro para inteiro: 
int *pont;
a atribuição: 
pont = i;
faz com que "pont" aponte para o elemento zero do vetor "i" (&i[0]);
 
Se "pont" aponta para um elemento particular de um vetor, então "pont+1" aponta para o próximo elemento. 
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Ou seja:
pont + n aponta para n elementos após pont. 
pont - n aponta para n elementos antes de pont.
 
Obs 1: O nome do vetor já é o endereço do vetor;
Obs 2: Também são válidas as operações com ponteiros para matrizes multidimensionais. 
Exemplo:
		mat[10][10]; equivale a &mat[0][0]
		mat[0][4], pode ser acessado por *(mat+3)
		mat[1][2], pode ser acessado por *(mat+13) 
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
Exemplo 3:
Elabore uma função em C que retorne o tamanho de uma cadeia de caracteres, usando ponteiros.
int strlen(char *S) 
{
 	int n; 
 	for ( n = 0; *S != '\0' ; S++ ) n++; 
 		return n; 
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
int main (int argc, char *argv[])
{
 int Matriz [MAXCOL][MAXLIN];
 
 Matriz [0][0] = 1;
 Matriz [0][1] = 2;
 Matriz [1][0] = 3;
 Matriz [1][1] = 4; 
 
 ImprimeMatriz (Matriz);
 InverteValoresMatriz (Matriz);
 
 ImprimeMatriz (Matriz);
 
 system("PAUSE");
 return EXIT_SUCCESS;
}
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
#define MAX 2
int main (int argc, char *argv[])
{
	int *x[MAX], var1, var2;
	int *x[MAX], var1, var2;
	var1 = 3;
	var2 = 4;
	x[0] = &var1;
	x[1]= &var2;
	printf ("&var1: %d \n", &var1);
	printf ("&var2: %d \n", &var2);
	printf ("var1: %d\n", var1);
	printf ("var2: % d\n", var2);
	printf ("x[0]: %d \n", x[0]);
	printf ("x[1]: %d \n", x[1]);
	printf("*x[0]: %d\n", *x[0]);
	printf("x[1]: %d\n", x[1]);
	printf("*x[1]: %d\n", *x[1]);
	system ("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
	int *p1, x = 10;
	p1 = &x;
	printf("p1: %d \n", p1);
	printf(“&x: %d \n", &x);
	printf("p1: %d \n", p1);
	printf("x: %c \n", x);
	p1++;
	printf ("p1: %d \n", p1);
	printf (“&x: %d \n", &x);
	printf ("x: %c \n", x);
	system ("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
Int main (int argc, char *argv[])
{
	char *p1, x = ‘a’;
	p1 = &x;
	printf ("p1: %d \n", p1);
	printf ("&x: %d \n", &x);
	printf ("p1: %d \n", p1);
	printf ("x: %c \n", x);
	p1 = p1 + 4;
	printf ("p1: %d \n", p1);
	printf ("&x: %d \n", &x);
	printf ("x: %c \n", x);
	system("PAUSE");
	return 0;
}
#include <stdio.h>
#include <stdlib.h>
Int main (int argc, char *argv[])
{
	double x = 1.23212345;
	p1 = &x;
	printf ("p1: %d \n", p1);
	printf ("&x: %d \n", &x);
	printf ("p1: %d \n", p1);
	printf ("x: %lf \n", x);
	p1 = p1 + 2;
	printf ("p1: %d \n", p1);
	printf ("&x: %d \n", &x);
	printf ("x: %lf \n", x);
	system("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
#define MAX 4
int main (int argc, char *argv[])
{
	int i, x[MAX] = {0,1,2,3};
	printf ("Endereco\t Conteudo\t \n");
	for (i = 0; i<MAX; i++)
		printf("%d\t\t %d\t \n", &x[i], x[i]);
	
	system("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
#define MAX 4
int main (int argc, char *argv[])
{
	int i, x[MAX] = {0,1,2,3};
	int i, x[MAX] = {0,1,2,3};
	printf ("Endereco\t Conteudo\t \n");
	printf ("Notacao de vetor \n");
	printf ("%d\t\t %d\t \n", &x[0], x[0]);
	printf ("Notacao de ponteiro \n");
	printf ("%d\t\t %d\t \n", x, *x);
	system ("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
#define MAX 4
int main (int argc, char *argv[])
{
	int i, x[MAX] = {0,1,2,3}, *p1;
	int i, x[MAX] = {0,1,2,3}, *p1;
	p1 = x;
	printf ("Endereco\t Conteudo\t \n");
	printf ("Notacao de vetor \n");
	printf ("%d\t\t %d\t \n", &x[0], x[0]);
	printf ("Notacao de ponteiro \n");
	printf ("%d\t\t %d\t \n", p1, *p1);
	system ("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
#define MAX 4
int main (int argc, char *argv[])
{
	int i, x[MAX] = {0,1,2,3};
	int i, x[MAX] = {0,1,2,3};
	printf ("Endereco\t Conteudo\t \n");
	printf ("Notacao de vetor:\n");
	for (i=0; i<MAX; i++)
		printf ("%d\t\t %d\t \n", &x[i], x[i]);
		printf(“Notacao de ponteiro:\n");
		for (i=0; i<MAX; i++)
			printf ("%d\t\t %d\t \n", x+i, *(x+i));
	system("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
#define MAX 4
int main (int argc, char *argv[])
{
	int i, x[MAX] = {0,1,2,3}, *p1;
	int i, x[MAX] = {0,1,2,3}, *p1;
	printf ("Endereco\t Conteudo\t \n");
	p1 = x;
	printf ("Notacao de vetor:\n");
	for (i=0; i<MAX; i++)
		printf ("%d\t\t %d\t \n", &x[i], x[i]);
		printf (“Notacao de ponteiro:\n");
		for (i=0; i<MAX; i++)
			printf ("%d\t\t %d\t \n", p1+i, *(p1+i));
	system("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
#define MAX 4
int main (int argc, char *argv[])
{
	int x[MAX], i, *p;
	for (i=0; i<MAX; i++)
		a[i]=i;
		for(i=0; i<MAX; i++)
			printf ("%d ",*(p+i));
	
	system ("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
	char *p;
	p = "Segunda-feira";
	printf ("%s \n", p);
 	system ("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
int main (int argc, char *argv[])
{
	char *x[MAX] = {“Segunda-feira”,
			 “Terca-feira”,
			 “Quarta-feira”,
			 “Quinta-feira”,
			 “Sexta-feira”};
	printf (“%s \n”, x[2]);
	system (“PAUSE”);
	return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
int main (int argc, char *argv[])
{
char *x[MAX] = {“Segunda-feira”,
			 “Terca-feira”,
			 “Quarta-feira”,
			 “Quinta-feira”,
			 “Sexta-feira”};
	printf(“%s \n”, x[2]);
	printf(“%s \n”, *(x+2));
	system(“PAUSE”);
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
Chamada de funções passando argumentos por referência. Suponha o seguinte código (cuja função divpordois utiliza
passagem de argumentos por valor):
#include <stdio.h>
#include <stdlib.h>
float divpordois( float);
int main (int argc, char *argv[])
{
	float x, y = 5.0;
	printf ("y = %.2f \n", y);
	x = divpordois(y);
	printf ("%.2f/2 = %.2f \n", y, x);
	system ("PAUSE");
	return 0;
}
float divpordois (float n){
	float result;
	result = n/2;
	return result;
}
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
void divpordois (float *);
int main (int argc, char *argv[])
{
	float y = 5.0;
	printf ("y = %.2f \n", y);
	divpordois(&y);
	printf ("y = %.2f \n", y);
	
	system("PAUSE");
	return 0;
}
void divpordois (float *n){
	
	*n = *n/2;
}
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
int divpordois (float *);
int main (int argc, char *argv[])
{
	float y = 5.0, sucesso;
	printf ("y = %.2f \n", y);
	sucesso = divpordois(&y);
	printf ("y = %.2f \n", y);
	printf ("sucesso = %d \n", sucesso);
	system("PAUSE");
	return 0;
}
int divpordois( float *n){
	*n = *n/2;
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
int retornavarios(float *, int *);
int main (int argc, char *argv[])
{
	float y = 5.0;
	int x = 5, sucesso;
	int x = 5, sucesso;
	printf("y = %.2f - x = %d \n", y, x);
	sucesso = retornavarios(&y, &x);
	printf ("y = %.2f - x = %d \n", y, x);
	printf ("sucesso = %d \n", sucesso);
	system("PAUSE");
	return 0;
}
int retornavarios( float *n1, int *n2){
	*n1 = *n1/2;
	*n2 = *n2%2;
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
#include <stdlib.h>
#define MAX 10
int retornavetor (float *, int);
int main (int argc, char *argv[])
{
	float x[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
	int i, sucesso;
	float x[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
	printf ("Vetor antes de chamar a funcao\n");
	for (i = 0; i<MAX; i++)
		printf("%.2f \n", x[i]);
		sucesso = retornavetor(x, MAX);
		printf ("Vetor depois de chamar a funcao\n");
		for (i = 0; i<MAX; i++)
		printf("%.2f \n", x[i]);
	system("PAUSE");
	return 0;
}
int retornavetor ( float *vet, int N){
	
	int retornavetor( float *vet, int N){
	int i;
	for (i = 0; i<N; i++)
		*(vet+i) = i;
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
Retorno de vetores, via return.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
char *string_maiusc(char *);
int main (int argc, char *argv[])
{
	char letras[] = "Teste", *string;
	string = string_maiusc(letras);
	printf("%s \n", string);
	system("PAUSE");
	return 0;
}
char *string_maiusc(char *str)
{
	int i;
	size_t N;
	N = strlen(str);
	for(i = 0; i<N; i++) {
	 *(str+i) = toupper (*(str+i));
	 *(str+i) = toupper (*(str+i));
	}
	return str;
}
PROFESSOR: EDILSON LIMA
*/81
Retorno de vetores,via return.
#include <stdio.h>
#include <stdlib.h>
#define MAX 6
int *soma_um(int *, int);
int main (int argc, char *argv[])
{
	int main (int argc, char *argv[])
	int numeros[MAX] = {0, 1, 2, 3, 4, 5}, *p, i;
	p = soma_um(numeros, MAX);
	for (i = 0; i < MAX; i++)
		printf("%d \n", *(p+i));
	system("PAUSE");
	return 0;
}
int *soma_um(int *nums, int N)
{
	int i, *p_nums;
	p_nums = nums;
	for(i = 0; i<N; i++) {
		*(p_nums+i) = *(p_nums+i) + 1;
		*(p_nums+i) = *(p_nums+i) + 1;
	}
	return p_nums;
}
PROFESSOR: EDILSON LIMA
*/81
Nomes de strings, são do tipo char*. Isto nos permite escrever a nossa função StrCpy(), que funcionará de forma semelhante à função strcpy() da biblioteca:
#include <stdio.h>
Void StrCpy (char *destino, char *origem){
	while(*origem)	{
		*destino=*origem;
		origem++;
		destino++;
	}
	destino++;
}
int main () {
	char str1[100],str2[100],str3[100];
	printf ("Entre com uma string: ");
	gets (str1);
	StrCpy (str2,str1);
	StrCpy (str3,"Voce digitou a string ");
	printf ("\n\n%s%s",str3,str2);
	return(0);
}
Observe que podemos passar ponteiros como argumentos de funções.
Funções como gets() e strcpy() funcionam assim. Passando o ponteiro, a função pode alterar o conteúdo das strings.
No comando while (*origem), usamos o fato de que a string termina com '\0' como critério de parada.
Quando fazemos origem++ e destino++, poderia ser argumentado que estamos alterando o valor do ponteiro-base da string, contradizendo o que foi recomendado anteriormente. Entretanto, em C, são passados para as funções cópias dos argumentos (e que será estudado em detalhe mais adiante).
Desta maneira, quando alteramos o ponteiro origem na função StrCpy() o ponteiro str2 permanece inalterado na função main().
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
 
Essa notação é válida e retorna o endereço do ponto do vetor indexado por índice. Isto seria equivalente a nome_da_variável [indice]. 
Como exemplo, o ponteiro nome_da_variável tem o endereço &nome_da_variável[0], que indica onde na memória está guardado o valor do primeiro elemento do vetor. 
VETORES DE PONTEIROS
pmatrx é um vetor que armazena 10 ponteiros para inteiros.
&nome_da_variável[índice] 
int *pmatrx [10];
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
ATIVIDADE
Fizemos a função StrCpy(). Faça uma função StrLen() e StrCat() que funcionem como as funções strlen() e strcat() de string.h espectivamente
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
PONTEIROS PARA PONTEIROS
Um ponteiro para um ponteiro é como se você anotasse o endereço do lugar que tem o endereço da casa do seu amigo. Podemos declarar um ponteiro para um ponteiro com a seguinte notação: 
Onde: **nome_da_variável é o conteúdo final da variável apontada;
 *nome_da_variável é o conteúdo do ponteiro intermediário. 
Em C podemos declarar ponteiros para ponteiros para ponteiros, ou então, ponteiros para ponteiros para ponteiros para ponteiros e assim por diante. Para fazer isto basta aumentar o número de asteriscos na declaração. fazer isto basta aumentar o número de asteriscos na declaração. 
Para acessar o valor desejado apontado por um ponteiro para ponteiro, o operador (*) asterisco deve ser aplicado duas vezes.
tipo_da_variável **nome_da_variável;
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
#include <stdio.h>
int main() {
	float fpi = 3.1415, *pf, **ppf;
	pf = &fpi; 	/* pf armazena o endereco de fpi */
	ppf = &pf; 	/* ppf armazena o endereco de pf */
	printf("%f", **ppf); /*Imprime o valor de fpi */
	printf("%f", *pf); /*Tambem imprime o valor de fpi*/
	return(0); 
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
PONTEIROS E ESTRUTURA
Da mesma forma que outras variáveis, podemos ter ponteiros para estruturas. 
struct funcionario x, *pf;
struct data d, *pd;
pf = &x;
pd = &d;
(*pf).numero = 123456; é o mesmo que x.numero = 123456;
(*pd).ano = 2001; é o mesmo que d.ano = 2001;
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
O motivo do parêntesis em (*pf) é a prioridade dos operadores * (estrela) e. (ponto).
Outra forma de usar ponteiro com estrutura é usar a abreviatura p-> para (*p).
Os comando ficam: 
pf->numero = 123456; é o mesmo que x.numero = 123456;
pd->ano = 2001; é o mesmo que d.ano = 2001;
A notação p-> é mais clara e um pouco menos carregada que a notação (*p). Também um pouco mais intuitiva. 
PROFESSOR: EDILSON LIMA
*/81
Exemplo de Estrutura e Ponteiro
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Estrutura
struct dados_aluno{
	char nome[80];
	float media;
};
int main( int argc, char *argv[])
{
	struct dados_aluno aluno, *p_aluno;
	p_aluno = &aluno;
	strcpy ((*p_aluno).nome, “Alexandre Zaghetto”);
	(*p_aluno).media = 9.5;
	printf("%s \n", (*p_aluno).nome);
	printf("%f \n", (*p_aluno).media);
	system("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
int main (int argc, char *argv[])
{
	struct dados_aluno aluno, *p_aluno;
	p_aluno = &aluno;
	strcpy (p_aluno->nome,"Alexandre Zaghetto");
	p_aluno->media = 9.5;
	printf("%s \n", p_aluno->nome);
	printf ("%f \n", p_aluno->media);
	system("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
Passando structs como parâmetro de funções, utilizando ponteiros.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Estrutura
struct dados_aluno{
	char nome[80];
	float media;
};
// Protótipo da função que recebe a estrutura
void imprime_struct(struct dados_aluno *);
// Protótipo da função que altera a estrutura
void altera_struct(struct dados_aluno *);
int main (int argc, char *argv[])
{
	struct dados_aluno aluno, *p_aluno;
	p_aluno = &aluno;
	strcpy (p_aluno->nome,"Alexandre Zaghetto");
	p_aluno->media = 9.5;
	p_aluno->media = 9.5;
	imprime_struct(p_aluno);
	altera_struct(p_aluno);
	imprime_struct(p_aluno);
	system("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
// Imprime a estrutura
void imprime_struct(struct dados_aluno *parm){
	printf ("%s \n", parm->nome);
	printf ("%f \n", parm->media);
}
// Altera a estrutura
void altera_struct(struct dados_aluno *parm){
	strcpy (parm->nome, "Zaghetto Alexandre");
	parm->media = 5.9;
};
PROFESSOR: EDILSON LIMA
*/81
Ponteiro para Função
 Exemplo 1:
#include <stdio.h>
#include <stdlib.h>
// Ponteiro para função
int pega_result(int, int, int (* )(int, int));
int max(int, int);
int min(int, int);
int main (int argc, char *argv[])
{
	int result, x1 = 10, x2 = 232;
	result = pega_result(x1,x2, &max);
	printf("O maximo entre %d e %d ‚ %d\n",x1,x2, result);
	
	result = pega_result(x1,x2, &min);
	printf("O minimo de %d e %d ‚ %d\n",x1,x2, result);
	system("PAUSE");
	return 0;
}
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
int pega_result(int a, int b, int (*compare)(int , int ))
{
	return compare(a, b); // Chama a função passada
}
int max(int a, int b)
{
	printf("Em max:\n");
	return (a > b) ? a: b;
}
int min(int a, int b)
{
	printf("Em min:\n");
	return (a < b) ? a: b;
}
PROFESSOR: EDILSON LIMA
*/81
Exemplo 2:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
	srand ( time(NULL) );
	ImprimeDois(aleatorio);
	ImprimeDois(acimade9mil);
	ImprimeDois(quarantaedois);
	system("PAUSE");
	return 0;
}
void ImprimeDois(int (*numberSource)(void)) {
	printf("%d and %d\n", numberSource(), numberSource());
}
int acimade9mil(void) {
	return (rand() % 1000) + 9000;
}
int quarentaedois(void) {
	return 42;
}
PROFESSOR: EDILSON LIMA
*/81
Cuidados a serem tomados com ponteiros
Principais cuidados ao se usar um ponteiro: 
– saiba sempre para onde o ponteiro está apontando.– nunca use um ponteiro que não foi inicializado.
Um pequeno programa que demonstra como não usar um ponteiro: 
/*Errado - Não Execute */
int main () 
{ 
	int x,*p;
	x=13;
	*p=x;*p=x;
	return(0);
}
O exemplo compilará e rodará. O que acontecerá? Não se sabe. 
– O ponteiro p pode estar apontando para qualquer lugar.
– Você estará gravando o número 13 em um lugar desconhecido. 
– Com um número apenas, você provavelmente não vai ver nenhum defeito.
– Agora, se você começar a gravar números em posições aleatórias no seu computador, não vai demorar muito para travar o micro (se não acontecer coisa pior). 
PROFESSOR: EDILSON LIMA
*/81
Cuidados a serem tomados com ponteiros
O exemplo anterior compilará e rodará. O que acontecerá? Não se sabe. 
– O ponteiro p pode estar apontando para qualquer lugar.
– Você estará gravando o número 13 em um lugar desconhecido. 
– Com um número apenas, você provavelmente não vai ver nenhum defeito.
– Agora, se você começar a gravar números em posições aleatórias no seu computador, não vai demorar muito para travar o micro (se não acontecer coisa pior). 
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
RESOLVA A LISTA DE EXERCÍCIO DA UNIDADE III
FIM DA UNIDADE III
BONS ESTUDOS
3.2 Aplicações
PROFESSOR: EDILSON LIMA
*/81
PROFESSOR: EDILSON LIMA
*/81
ROTEIRO
PROFESSOR: EDILSON LIMA
Bibliografia
ARAÚJO, Everton C. Algoritmos: fundamento e prática. 2.ed. Florianópolis: VisualBooks, 2005.
MANZANO, José Augusto N. G.; OLIVEIRA, Jayr Figueiredo. Algoritmos: lógica para desenvolvimento de programação de computadores. 17.ed. São Paulo: Érica, 2005.
SALIBA, Walter Luís Caram. Técnicas de programação: uma abordagem estruturada. São Paulo: Pearson Education do Brasil, 1992.
GUIMARÃES, Ângelo de Moura; LAGES, Newton Alberto de Castilho. Algoritmos e Estrutura de Dados. 28ª Tiragem. Editora LTC São Paulo.
*/81
*

Outros materiais