[RESOLVIDO] (C) Pra que serve os ponteiros?

Estou aprendendo ponteiros, mas não entendi por que usa-los.

Com ponteiros:

#include <stdio.h>
int main() {
  int num, valor;
  int *ptr;
  ptr = 0;
  ptr = &num;
  num = 10;
  valor = *ptr; 
  printf("%d", valor);
  return(0);
}

Isso não seria a mesma coisa que isso:

#include <stdio.h>
int main() {
  int num, valor;
  int ptr;
  ptr = num;
  num = 10;
  valor = ptr;
  printf("%d", valor);
  return(0);
}

?
E ainda economizou uma linha =)

No inicio imaginei que o motivo estivesse relacionado a memoria, mas depois li que há memória reservada para o *ptr também!
Onde errei? Por que usar? :frowning:

O ponteiro nada mais é do que uma variável que armazena um determinado endereço de memória. Um exemplo de uso de ponteiros é uma função que deve receber um parâmetro e alterar ele. Para fazer isso você deve usar um ponteiro.

Um outro exemplo de ponteiro é a lista encadeada. digamos que você tenha a seguinte struct:

struct elemento { int valor; elemento* proximo; };

Essa struct possui dois campos, um para guarda o valor de um elemento da lista e outro que aponta para o próximo elemento da lista.

[quote=matheuslmota]O ponteiro nada mais é do que uma variável que armazena um determinado endereço de memória. Um exemplo de uso de ponteiros é uma função que deve receber um parâmetro e alterar ele. Para fazer isso você deve usar um ponteiro.

Um outro exemplo de ponteiro é a lista encadeada. digamos que você tenha a seguinte struct:

struct elemento { int valor; elemento* proximo; };

Essa struct possui dois campos, um para guarda o valor de um elemento da lista e outro que aponta para o próximo elemento da lista.
[/quote]

Entendi nada… mas valeu!! É melhor eu seguir estudando e tentando fazer os exercícios, acho que assim eu aprendo. :roll:

Outro exemplo clássico é referenciar um conteúdo que está no heap, e não no stack:

int* valores = malloc(10 * sizeof(int)); //Inicia o vetor com a tabuada do 5 for (int i = 0; i &lt; 10; i++) { valores[i] = i*5; } free(valores);

void main()
{
int i, j, *ptr;
i = 1;
j = 2;
ptr = &i;
*ptr = *ptr + j;
printf("%d", i);
}

O valor de i que vai sair no printf é 3?
O que eu queria saber é se for mudado o valor do ponteiro, estará também mudando o valor da variável a que ele se refere?

Deixa eu tentar explicar de uma forma mais clara.
Como disse antes, um ponteiro é uma variável que guarda um endereço de memória. Por exemplo:

Aqui eu declarei uma variável que armazena um endereço de memória e nesse endereço de memória está guardado um inteiro. O asterisco é usado para declarar um ponteiro.

int i = 5; ptr = &i;
Nesse ponto eu declarei uma variável inteira i e abribui o valor 5. A variável i está armazenada em algum lugar da memória. Por meio do operador “endereço de” (que é representado pelo &), eu obtive o endereço da variável i. Esse endereço é atribuido ao ponteiro ptr.
Agora eu faço:

O asterisco representa o operador de derreferência e é usado para acessar o conteúdo de um ponteiro. A linha acima imprime 5 no console.
Se eu fizer a seguinte atribuição:

Eu estarei mudando o conteúdo do ponteiro, antes naquele endereço estava armazenado 5, agora está armazenado 6.
Se você fizer a seguinte chamada:

Vai ver que i não vale mais 5, agora vale 6.
Ou seja, ponteiros são variáveis que permitem armazenar um endereço de memória e modificar o que está armazenado naquele endereço.

[quote=Neviat]O valor de i que vai sair no printf é 3?
O que eu queria saber é se for mudado o valor do ponteiro, estará também mudando o valor da variável a que ele se refere?[/quote]

Sim. Um ponteiro é um endereço de memória.
O valor que ele aponta, é o que aquele endereço contém.

Então, se vc faz o ponteiro apontar para uma variável, significa que ele conterá o endereço de memória daquela variável.
E mudar o conteúdo desse endereço, vai mudar o conteúdo da variável.

Veja só:

[code]void teste(int* valor)
{
valor++;
}

int main(int argc, char* argv[])
{
int x = 10;
teste(&x);
printf("Valor: %d", x);
}[/code]

Outra coisa interessante:

int x[3]; x[0] = 0; x[1] = 1; x[2] = 2; int *ptr = x; //ptr aponta para x[0]. for (int i = 0; i &lt; 3; i++) { printf(&quot;Valor %d&quot;, ptr); ptr++; //Avança 1 int na memória. }

vlw matheuslmota ! entendi ^ :smiley:

agora fiquei com duvida no que ViniGodoy escreveu:

Dúvidas ^^

  1. “int* valor” -> por que o * está no int?
  2. o que é “int argc, char* argv[]” ?
  3. “teste(&x)” -> int* valor = &x ? -> está dando o endereço de [b]x[\b] ao valor, sim? Mas ele é uma variável, pq n tem * =/ (dúvida 1)

[quote=Neviat]
Dúvidas ^^

  1. “int* valor” -> por que o * está no int?

  2. o que é “int argc, char* argv[]” ?

  3. “teste(&x)” -> int* valor = &x ? -> está dando o endereço de [b]x[\b] ao valor, sim? Mas ele é uma variável, pq n tem * =/ (dúvida 1)[/quote]

  4. int* também declara um ponteiro para inteiro. A diferença aparece em uma declaração como essa:

Nesse caso, só i1 é um ponteiro para inteiro, i2 é uma variável inteira normal.

  1. argc é uma variável que recebe a quantidade de parâmetros que foram passadas para seu programa e argv é um vetor dos parâmetros que foram passados. Vamos supor que você executou a aplicação main.exe assim:
    main.exe maria jose

argc é igual a 3 (o nome do programa também entra na quantidade de parâmetros)
argv[0] = "main.exe"
argv[1] = "maria"
argv[2] = “jose”

  1. Você passou o endereço de x para o método teste, assim, valor é o nome do parâmetro que recebe esse endereço (int* valor é um ponteiro para inteiro).

matheuslmota e ViniGodoy, vlw denovo… entendi! :smiley: