












Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Os melhores documentos à venda: Trabalhos de alunos formados
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Comunidade
Peça ajuda à comunidade e tire suas dúvidas relacionadas ao estudo
Descubra as melhores universidades em seu país de acordo com os usuários da Docsity
Guias grátis
Baixe gratuitamente nossos guias de estudo, métodos para diminuir a ansiedade, dicas de TCC preparadas pelos professores da Docsity
Linguagem C - Ponteiros
Tipologia: Notas de aula
1 / 20
Esta página não é visível na pré-visualização
Não perca as partes importantes!
-^
-^
-^
Quando você anota o endereço de um colega você está criando um ponteiro.
Qual é o sentido disto? Quando você anota o endereço de um colega, depoisvocê vai usar este endereço para achá-lo. Em C funciona desta mesmamaneira, você anota o endereço de algo numa variável ponteiro para depois usar.usar.
Uma agenda, onde são guardados vários endereços , poderia ser vista comosendo uma matriz de ponteiros em C.
-^
quando você anota um endereço de um amigo você o trata diferente dequando você anota o endereço de uma firma. Apesar de o endereço dos doislocais ter o mesmo formato (rua, número, bairro, cidade, etc.) eles indicamlocais cujos conteúdos são diferentes. Então os dois endereços são ponteirosde
tipos
diferentes.
Em C quando declaramos ponteiros, informamos ao compilador para que tipode variável vamos apontá-lo. Um ponteiro
int
aponta para um inteiro, isto é,
guarda o endereço de um inteiro.
-^
Como saber a posição na memória de uma variável do nosso programa? Seriamuito difícil saber o endereço de cada variável que usamos, mesmo porque estesendereços são determinados pelo compilador na hora da compilação erealocados na execução.
O compilador faz este trabalho.
Criamos um inteiro
count
com o valor 10 e um apontador para um inteiro
pt
. A
expressão
&count
nos dá o endereço de
count
, o qual armazenamos em
pt
.
-^
-^
Como
pt=&count,
a expressão
*pt
é equivalente ao próprio
count
.
Isto significa que para mudar o valor de
count
para 12, basta fazer
*pt=
.
#include <stdio.h>int main (){
int num,valor;int *p;num=55;p=#
/* Pega o endereco de num */
valor=*p;
/*
valor
é igualado a
num
de uma maneira indireta */
printf ("\n\n%d\n",valor);printf ("Endereco para onde o ponteiro aponta: %p\n",p);printf ("Valor da variavel apontada: %d\n",*p); return(0); }^
return(0); } #include <stdio.h>int main (){
int num,*p;num=55;p=#
/* Pega o endereco de num */
printf ("\nValor inicial: %d\n",num);p=100; / Muda o valor de num de uma maneira indireta */printf ("\nValor final: %d\n",num);return(0); }
o código
%p
usado na função
printf()
indica à função que
ela deve imprimir um endereço
Operações com ponteiros
-^
Soma e subtração de inteiros com ponteiros. Vamos supor que você queiraincrementar um ponteiro de 15:
p=p+15;
ou
p+=15;
Para usar o conteúdo do ponteiro 15 posições adiante;
*(p+15);
Comparação entre dois ponteiros.
-^
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. Acomparação entre dois ponteiros se escreve como a comparação entre outrasduas variáveis quaisquer:
p1>p
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 float
s^
ou
double
s^
de ponteiros.
-^
Exercícios a) Explique a diferença entrep++;
(*p)++;
*(p++);
O que quer dizer *(p+10);?
Explique o que você entendeu da comparação entre ponteiros
b) Qual o valor de y no final do programa? Tente primeiro descobrir e depois verifique no
computador o resultado. A seguir, escreva um /* comentário */ em cada comando deatribuição explicando o que ele faz e o valor da variável à esquerda do '=' após sua execução. int
main() int
main() {
int y, p, x;y = 0;p = &y;x = p;x = 4;(p)++;x--;(p) += x;printf ("y = %d\n", y);return(0); }
-^
Ponteiros e Vetores
-^
Vetores como ponteiros
-^
Agora podemos entender como é que funciona um vetor!
-^
Fica claro, por exemplo, porque é que, 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
. Então sabemos que:
*nome_da_variável
é equivalente a
nome_da_variável[0]
-^
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 também porque 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 parao início do mesmo e, quando você usa os índices, encontra os elementos requisitados.
-^
Vamos ver agora um dos usos mais importantes dos ponteiros: a varredura sequencial deuma matriz. Quando temos que varrer todos os elementos de uma matriz de uma formasequencial, podemos usar um ponteiro, o qual vamos incrementando. Qual a vantagem?Considere o seguinte programa para zerar uma matriz:
10
-^
Ponteiros e Vetores
-^
Vetores como ponteiros
-^
Vamos ver agora um dos usos mais importantes dos ponteiros: a
varredura sequencial de uma matriz
. Quando
temos que varrer todos os elementos de uma matriz de uma forma sequencial, podemos usar um ponteiro, oqual vamos incrementando. Qual a vantagem? Considere o seguinte programa para zerar uma matriz: 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);} Podemos reescrevê
int main (){
float matrx [50][50];float *p;int count;p=matrx[0];for (count=0;count<2500;count++)
{
*p=0.0;p++;
} 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 quedeve ser feito é o de um incremento de ponteiro. Fazer 2500 incrementos em um ponteiro é muito mais rápidoque calcular 2500 deslocamentos completos.
-^
Ponteiros e Vetores
-^
Ponteiros como vetores
-^
Sabemos que o nome de um vetor é um ponteiro constante.
-^
Sabemos que podemos indexar o nome de um vetor.
-^
Como conseqüência podemos indexar um ponteiro qualquer. O programa mostrado a seguirfunciona perfeitamente: #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)
.
-^
Strings
-^
Seguindo o raciocínio acima, 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++;^ }
Observe que podemos passar ponteiros comoargumentos de funções
.
Funções como
gets()
e
strcpy()
funcionam assim.
Passando o ponteiro, a função pode
alterar
o
conteúdo das strings. Já estávamos passando os ponteiros. No comando
while (origem)*
, usamos o fato de que
a string termina com '
\0' como critério de parada.
} *destino='\0';
} 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); }^
a string termina com '
\0' como critério de parada.
Quando fazemos
origem++
e
destino++,
poderia ser
argumentado que estamos alterando o valor doponteiro-base da string, contradizendo o que foirecomendado anteriormente. Entretanto, em C, sãopassados 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
str
permanece
inalterado na função
main()
.
Inicializando Ponteiros
-^
Toda string que o programador insere no programa é colocada num banco destrings que o compilador cria.
-^
No local onde está uma string no programa, o compilador coloca o endereço doinício daquela string (que está no banco de strings).
-^
Por isto que podemos usar
strcpy()
do seguinte modo:
strcpy (string,"String
constante.");
-^
strcpy()
pede dois parâmetros do tipo
char*
Como o compilador substitui a string
"String constante."
pelo seu endereço no
banco de strings, tudo está bem para a função
strcpy()
banco de strings, tudo está bem para a função
strcpy()
O que isto tem a ver com a inicialização de ponteiros? Para uma string que vamosusar várias vezes, podemos fazer:
char *str1="String constante.";
Então poderíamos, em todo lugar que precisarmos da string, usar a variável
str
Deve-se ter cuidado ao usar este ponteiro:
Se o alterarmos vamos perder a string
.
Se o usarmos para alterar a string podemos facilmente corromper o banco de stringsque o compilador criou.
Mais uma vez fica o aviso: ponteiros são poderosos mas, se usados com descuido,podem ser uma ótima fonte de bugs.
16
Exercício
-^
Escreva a função
int strend(char *s, char *t)
que retorna 1 (um) se a cadeia de
caracteres
t
ocorrer no final da cadeia
s
, e 0 (zero) caso contrário.
Exercicio
-^
Verifique o programa abaixo. Encontre o seu erro e corrija-o para que escreva onumero 10 na tela.#include <stdio.h>int main(){
int x, *p, **q;p = &x; q = &p;q = &p; x = 10;printf("\n%d\n", &q);return(0); }
Cuidados a Serem Tomados ao se Usar 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:
int main ()
/ Errado - Nao Execute /
int x,*p;x=13; p=x;p=x; return(0);}
-^
Este programa 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 vaidemorar muito para travar o micro (se não acontecer coisa pior).
Exercício:
Escreva um programa que declare uma matriz 100x100 de inteiros. Você
deve inicializar a matriz com zeros usando ponteiros para endereçar seuselementos. Preencha depois a matriz com os números de 1 a 10000, também usando ponteiros.