(excepto o último tópico, adaptado de http://www.mspc.eng.br/info/cpp_ptr_10.shtml) Show IntroduçãoOs ponteiros são um dos recursos mais poderosos da linguagem C. Qualquer programa de utilidade prática escrito em C dificilmente dispensará o uso de ponteiros. A tentativa de evitá-los implicará quase sempre códigos maiores e de execução mais lenta.Para quem está a começar, pode parecer um conceito difícil. Mas não há outro caminho senão enfrentar a realidade. São muitas as aplicações de ponteiros. A seguir, apresenta-se uma relação das mais comuns. • Aceder a endereços de memória que o programa aloca em tempo de execução. return apenas é possível devolver um valor) Variáveis revisitadas: lvalue e rvalueUma variável é uma zona (conjunto contíguo de bytes) na memória. Por exemplo, no caso de uma variável do tipo inteiro, uma zona de 4 bytes. Estando todas as posições de memória endereçadas univocamente, podemos associar a cada variável o endereço de memória onde essa zona começa. A esse endereço chamamos endereço da variável. Sendo assim, a uma variável estão sempre associados dois valores:
Exemplo:
Definição e declaraçãoUm ponteiro é uma variável que contém o endereço de um objecto de dados, em geral, outra variável. Essa é a razão para o seu nome: ele aponta para outra variável. Conforme qualquer variável em C, o ponteiro deve ser declarado antes de ser usado. Basta inserir o operador de indirecção (*) após o tipo da variável: int *ptr; Esta declaração define a variável ptr como um ponteiro para uma variável do tipo int. Uma declaração de ponteiro não tem o mesmo significado que uma declaração de uma variável. Ela indica apenas o tipo de objeto de dados apontado e o tamanho em bytes que ocupa não tem relação com o tamanho do objeto apontado. O tamanho do ponteiro é fixo e depende apenas do modelo de memória do sistema (2 bytes ou 4 bytes, normalmente). Para declarar mais de um ponteiro por linha, usa-se um operador de indirecção ( *) para cada um deles. Se um operador for omitido (exemplo: char *ch2, ch2;), a variável correspondente não será ponteiro e, certamente, provocará erro de execução se usada como tal: char *ch2, ch2; (um ponteiro para uma variável do tipo char e uma variável do tipo char). char *ch2, *ch2; (dois ponteiros para variáveis do tipo char). O ponteiro pode ser declarado para qualquer tipo legal de variável em C ( char, int, float, double, etc), além de void *, que declara um ponteiro genérico, que pode apontar para qualquer tipo de dados. Inicialização de um ponteiroA simples declaração de um ponteiro não faz dele útil. É necessária a indicação da variável para a qual ele aponta.
Na sequência acima, são declarados uma variável tipo int (var) e um ponteiro para o mesmo tipo (ptr). A terceira linha atribui o valor 10 a var e a última linha inicializa o ponteiro ptr. Observe-se o uso do operador de endereçamento ( &) para inicialização do ponteiro. Isso significa, no código ptr = &var, que ptr passa a conter o endereço de var, e não o seu valor. Supondo que o sistema é endereçado por 2 bytes, a Figura 01 acima dá uma idéia gráfica dessa associação: o conteúdo de ptr é 4052, que é o endereço do primeiro byte da variável var (ptr ocupa 2 bytes por causa do endereçamento do sistema e var também ocupa 2 bytes, mas por ser do tipo int). O valor 4052 para a posição de memória de var é apenas ilustrativo. Na prática, dependerá do local de memória onde o programa foi carregado. Com ptr apontando para var, é possível realizar operações com esta última de forma indirecta (por isso se chama ao operador * de indirecção), a partir de ptr. Exemplos a seguir. Acrescentando a linha int outra_var = *ptr; ao código anterior, o valor de outra_var seria 10, que é o valor de var lido indiretamente através de ptr. E a linha *ptr = 20; modifica o valor de var para 20, ou seja, altera o valor de var de forma indireta através de ptr. É importante lembrar que um ponteiro declarado e não inicializado poderá ter conteúdo nulo ou aleatório, a depender da alocação sistema. Nessas condições, se o conteúdo apontado for lido/modificado, algumas posições de memória verão seus valores indevidamente lidos/alterados e as consequências serão imprevisíveis. Passagem de parâmetros por valor e por referênciaAté aqui, e durante o estudo que fizemos da utilização de funções, a passagem de parâmetros que utilizámos foi sempre por valor. Isto significa que o que a função recebe é uma cópia dos valores das variáveis que são passadas por parâmetro, sendo os seus parâmetros formais (que funcionalmente são variáveis locais à função) inicializados com estes valores na altura da chamada da função. E se desejarmos que o valor de uma variável externa à função seja alterada dentro da função? Podemos aproveitar o conceito de ponteiro para conseguir este efeito. Passando o valor de um endereço a uma função, a função ganha acesso indirecto a essa posição de memória. Estude e execute o seguinte código: Passagem por valor -vs- Passagem por referência#include<stdio.h> // PASSAGEM POR VALOR - Não altera as variáveis // da função main()!!! void troca1(int x, int y){ int aux; aux = x; x = y; y = aux; } // PASSAGEM POR REFERÊNCIA - Permite alterar as // variáveis da função main()!!! void troca2(int *x, int *y){ int aux; aux = *x; *x = *y; *y = aux; } int main(){ int a=10, b=20; printf("Antes de troca1: a=%d, b=%d\n", a, b); troca1(a, b); printf("Depois de troca1: a=%d, b=%d\n", a, b); troca2(&a, &b); printf("Depois de troca2: a=%d, b=%d\n", a, b); getchar(); } Na função main(), repare na diferença entre a chamada de troca1() e troca2(). Na segunda são passados à função os endereços das variáveis a e b, e não os seus valores. Dentro de troca2(), os valores de a e b são modificados indirectamente (por indirecção). O que é uma variável ponteiro?Um ponteiro é uma variável que contém um endereço de memória. Esse endereço é normalmente a posição de uma outra variável na memória. Se uma variável contém o endereço de uma outra, então a primeira variável edita para apontar para a segunda. Se uma variável irá conter um ponteiro, ela deve ser declarada como tal.
Qual a diferença entre um ponteiro é uma referência?A diferença entre ponteiro e referência é sutil. Conceitualmente são dois acessos de indiretos à dados. Tanto ponteiros quanto referência o fazem através de um endereçamento. A diferença é que nas referências esse endereçamento é mais abstrato que no caso dos ponteiros.
O que é um ponteiro em programação?Um ponteiro é uma variável que armazena o endereço de memória de um objeto. Os ponteiros são usados extensivamente em C e C++ para três propósitos principais: para alocar novos objetos no heap, para passar funções para outras funções.
Qual é a função do ponteiro?O uso de ponteiros para funções em C serve principalmente para definir, em tempo de execução, qual função será executada, sem a necessidade de escrever o nome da função, de forma explícita naquele ponto do código.
|