Ir ao conteúdo
  • Cadastre-se

Quando e como usar ponteiros?


diegolinhares

Posts recomendados

Bom Dia pessoal, eu tenho uma dúvida terrível em C e vou precisar muito de ajuda, já que para dominar essa linguagem é necessário dominar esse assunto: Ponteiros. Eu já li toda a teoria, entendi bem, mas eu não sei que critérios usar por exemplo na aplicação em um código, não sei a parte prática da coisa, já fiz alguns exercícios, mas mesmo assim continuo com dúvidas. Espero que possam dar alguma clareada pra mim neste assunto. Agradeço.

Link para o comentário
Compartilhar em outros sites

Calma, nem sempre que a gente estuda uma coisa em exatas a gente começa a usar imediatamente.

As vezes demora até você usar ou é simplesmente pra entender melhor como as coisas funcionam.

Os ponteiros, por exemplo, você vão ser essenciais quando você for estudar Estrutura de Dados, dentre outras aplicações.

Link para o comentário
Compartilhar em outros sites

Não é necessário dominar esse assunto.

Entretanto C é uma linguagem poderosa justamente por você poder trabalhar direto com a memória.

Claro que você pode desenvolve rum sistema sem precisar fazer isso.

Ponteiro é apenas uma ideia de você não precisar ficar criando variaveis em lugares na memória diferente com o mesmo valor, em vez disso você diz que uma variavel é do tipo ponteiro e ela aponta para outea variavel.

Link para o comentário
Compartilhar em outros sites

Ponteiros são muito úteis, mas C é uma das poucas linguagens [populares] que te dá acesso de baixo nível à memória. Isso significa que programadores de outras linguagens não usam ponteiros, e se viram muito bem sem eles. Só que geralmente têm algo "parecido": referências. São como ponteiros, mas mais seguros pois, para o DESENVOLVEDOR, eles não apontam exatamente para um endereço qualquer de memória (para a linguagem talvez, mas não para o desenvolvedor), apontam para o endereço de alguma variável que já foi garantidamente alocada; e não podem ser manipulados como se faz com os ponteiros. Então não há o risco de você acessar memória não alocada com eles geralmente.

Eu realmente acho ponteiros superiores a referências. A maioria dos programadores os odeiam, têm medo de usá-los talvez, mas eu apenas os vejo como um recurso opcional - que eu uso se eu quiser, e não um recurso que eu TENHO que usar só porque existe. Por isso acho que, quando você realmente precisar deles, saberá o "quando usar".

De toda forma, vou te dar umas dicas.

Digamos que você tenha uma função. Essa função recebe um array de inteiros, e informa qual o menor número nesse array. Segue a função:

int menor_numero (int array[], int tamanho)
{
int i, menor = 0;
for (i = 1; i < tamanho; i++)
if (array[i] < array[menor])
menor = i;
return array[menor];
}

Até aí não há problema. O problema só começa a aparecer quando o array que você passa para a função é muito grande. Toda vez que você executa essa função, com um array e o tamanho dese array, é feita uma cópia de TODO o array, que é então passada para a função. Fazer cópias gasta tempo e memória. E é totalmente desnecessário, uma vez que você só quer fazer uma busca. Então o ideal é usar um ponteiro. Assim, a única coisa que é copiada é o endereço do primeiro elemento do array (4 bytes, em vez dos milhares de bytes que precisariamos para copiar um array com milhares de elementos). Teríamos a seguinte função:

int menor_numero (int *array, int tamanho)
{
int i, menor = 0;
for (i = 1; i < tamanho; i++)
if (array[i] < array[menor])
menor = i;
return array[menor];
}

Não mudou nada, só [] para um *, e poupou bastante tempo de execução. Como a sua função não altera nada no array, ainda acho melhor por um const: const int *array.

Existem ainda casos em que você vai precisar realmente do ponteiro (existe a alternativa nada viável de criar uma struct só pra isso):

// subtrai 1 de cada elemento
void decrementar (int *array, int tamanho)
{
int i;
for (i = 0; i < tamanho; i++)
array[i]--;
}

Se você passasse como array[], em vez de ponteiro, você alteraria apenas a CÓPIA (lembra que ele gera uma cópia?), e no fim sua função não faria nada (além de gastar tempo >.<).

Tem mais coisas que eu pretendia postar, mas vou ali assistir um filme, talvez poste depois (ou não...) =P.

Link para o comentário
Compartilhar em outros sites

RafaelCLP,

Existem ainda casos em que você vai precisar realmente do ponteiro (existe a alternativa nada viável de criar uma struct só pra isso):
// subtrai 1 de cada elemento
void decrementar (int *array, int tamanho)
{
int i;
for (i = 0; i < tamanho; i++)
array[i]--;
}

Se você passasse como array[], em vez de ponteiro, você alteraria apenas a CÓPIA (lembra que ele gera uma cópia?), e no fim sua função não faria nada (além de gastar tempo >.<).

Tem mais coisas que eu pretendia postar, mas vou ali assistir um filme, talvez poste depois (ou não...) =P.

Quando você voltar do filme, dê uma olhada aqui:

#include <stdio.h>
#include <stdlib.h>

void decrementar (int [B]array[][/B], int tamanho)
{
int i;
for (i = 0; i < tamanho; i++)
array[i]--;
}

int main ()
{

int i, vet[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

decrementar (vet, 10);

for (i = 0; i < 10; i++)
printf("%d\n", vet[i]);

return 0;
}

jdTmo.png

Depois, dê uma passada aqui:

http://c-faq.com/aryptr/aryptrparam.html

NW

Link para o comentário
Compartilhar em outros sites

Salve, RafaelCLP,

Obrigado, não sabia disso. Lembro que meu prof. disse para usar sempre ponteiros porque ao passar como array era gerada uma cópia, e desde então é o que faço. Nunca decidi testar se realmente acontecia.

Provavelmente ele estava se referindo (ou se confundindo) ao PASCAL (ou outra linguagem).. Lá, realmente rola essa cópia do vetor:

PROGRAM foo;
USES CRT;

PROCEDURE decrementar ( arr : array of integer );
VAR
i : integer;
BEGIN
FOR i := LOW (arr) TO HIGH (arr) DO
DEC(arr[i]);
END;

VAR
vet : array [1..10] of integer;
i : integer;


BEGIN
ClrScr;

FOR i := 1 TO 10 DO
vet[i] := i;

decrementar ( vet );

FOR i := 1 TO 10 DO
WriteLN (vet[i]);
END.

Neste caso sim, ele vai trabalhar com a cópia e ao final vai imprimir o vetor vet com seus valores originais.

Se declarar desta forma:

PROCEDURE decrementar ( [B][COLOR="Blue"]var[/COLOR][/B] arr : array of integer );

Então, sim, ele vai passar como referência (o endereço do vetor) e as modificações serão refletidas no vetor vet passado como parâmetro.

LNW

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!