Para tornar mais fácil para mim entender o ponteiro:

Pointer

Por quê?

Mover é caro e deve ser evitado à custa de tornar o código mais complicado.

Considere esta analogia. Bob e você têm terras agrícolas idênticas, mas Bob tem 1000 ovelhas, enquanto você tem 1000 vacas. Um dia, vocês dois decidem trocar todas as suas ovelhas por todas as suas vacas. Você pode contratar um pastor para mover as ovelhas e as vacas, ou vocês dois podem simplesmente trocar de fazenda, informando aos correios que seus endereços foram trocados.

Por exemplo, digamos que desejamos trocar duas matrizes de 1000 entradas aeb 100001 vezes.
A maneira ingênua é mudar as milhares de entradas assim

#include <stdio.h>

int main() {
int array_size = 1000;
char a[array_size];
char b[array_size];

int i;
for (i = 0; i < array_size - 1; i++){
a
[i] = 'a';
b
[i] = 'b';
}
a
[array_size] = '';
a
[array_size] = '';

printf
("Before swapping, first char of a is %cn", a[0]);
printf
("Before swapping, first char of b is %cn", b[0]);


char temp[array_size];
int j;
for (j = 0; j < 100001; j++){
for (i = 0; i < array_size; i++) {
temp
[i] = b[i];
b
[i] = a[i];
a
[i] = temp[i];
}
}

printf
("After swapping, first char of a is %cn", a[0]);
printf
("After swapping, first char of b is %cn", b[0]);

return 0;
}

Isso leva um tempo considerável. Mas se não trocarmos os locais dos dados, mas apenas trocarmos como os nomeamos, isso levará menos tempo:

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

int main() {
int array_size = 1000;
char* a;
char* b;
a
= (char*) malloc(sizeof(char) * array_size);
b
= (char*) malloc(sizeof(char) * array_size);

int i;
for (i = 0; i < array_size - 1; i++){
a
[i] = 'a';
b
[i] = 'b';
}
a
[array_size] = '';
a
[array_size] = '';

printf
("Before swapping, first char of a is %cn", *a);
printf
("Before swapping, first char of b is %cn", *b);

int j;
for (j = 0; j < 100001; j++){
char* tmp;
tmp
= b;
b
= a;
a
= tmp;
}

printf
("After swapping, first char of a is %cn", *a);
printf
("After swapping, first char of b is %cn", *b);
return 0;
}

Antes de tentar entender o que está acontecendo acima, vamos começar com algo mais simples

Fundamentos

Considere o programa

#include <stdio.h>

int main() {
int x;
x
= 1;
printf
("%dn", x);
return 0;
}

O que está acontecendo?

  1. int x; alocar 4 bytes de espaço denominado x, cujo endereço é & x
  2. x = 1; atribua 1 ao espaço localizado em & x
  3. printf obtém o valor em espaço & x

Aqui está um procedimento semelhante, mas com uma flexibilidade extra.

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

int main() {
int* p;
p
= (int*) malloc(sizeof(int));
*p = 1;
printf
("%dn", *p);
return 0;
}

Você deve pensar em x anterior como * p, e o valor do endereço & x como p. Antes, & x é constante porque é um endereço físico. Agora, p pode ser alterado, como p = & y, porque p é o valor do endereço, não o endereço físico real. Aqui está o que está acontecendo

  1. int * p; aloca espaço para p, que armazena o valor de um endereço
  2. malloc aloca espaço para * p (aka x)
  3. * p = 1; atribua 1 ao espaço (também conhecido como x)
  4. recupera o valor * p (também conhecido como x)