Olá Natan!
vetores e ponteiros
Se vc já viu a aula sobre vetores, vc vai achar familiar essa sintaxe:
- char palavra[6] = "Natan";
O que acontece é que essa variável palavra tbm pode ser escrita com notação de ponteiro:
vc pode imprimir ou modificar qualquer elemento dentro desse vetor passando o índice desejado, exemplo de impressão:
int main()
{
//nome[0] = 'N', nome[1] = 'a', nome[2] = 't', ...
char nome[] = "Natan";
printf("%c\n", nome[0]); //print elemento 0
printf("%c\n", nome[2]); //print elemento 2
nome[0] = 'L'; // alterar elemento 0
printf("%c\n", nome[0]); //printe novamente elemento 0
/*saida:
N
t
L
*/
return 0;
}
agora o mesmo, mas utilizando ponteiro:
#include <stdio.h>
int main()
{
const char nome[] = "Natan";
char* ptr = &nome[0]; //aponta para o primeiro elemento de 'nome'
printf("%c\n", *ptr); //mesmo que 'nome[0]'
ptr++; // aponta para o proximo elemento
printf("%c\n", *ptr);//memso que 'nome[1]'
*ptr = 'L'; //mesmo que "nome[1] = 'L';"
printf("%c\n", *ptr);//memso que 'nome[1]'
/*saida
N
a
L
*/
return 0;
}
note que eu não inicializei com "char* ptr = "Natan"; " mas sim passando o primeiro elemento de 'nome', pois o ponteiro recebendo uma string literal é diferente de inicializar um array.
Mas qual a diferença entre um e outro?
Os vetores com a sintaxe de colchetes ( char variavel[] = "string" ) :
É alocado um espaço de memória para armazenar os dados, logo, vc pode ler e escrever nesses endereços (alterar os dados de cada índice)
ponteiro char (char* ptr = "string literal") :
Não é alocado um espaço de memória especial para ele, logo, essa variável serve APENAS para LEITURA. Note que vc pode ALTERAR o valor contido nesse espaço, mas isso não é aconselhado, visto que pode haver comportamentos indefinidos no programa .
Quando se utiliza ponteiros para apontarem para essas "strings literais", é aconselhado deixar o ponteiro como 'const';
//isso NÃO é obrigatório, mas evita que o programador tente alterar
const char* palavra = "Natan";
Vc altera o valor de uma string por ponteiro apenas em dois casos:
- Ele aponta para uma outra variável ou vetor, ou seja, aquela string já está alocada em memória para leitura e escrita
- Vc alocou manualmente o espaço de memória para os dados ( com a função 'malloc()', por exemplo);
matrizes
Uma matriz é um vetor de vetores, ou seja, é um vetor que armazena outros vetores. note a sintaxe de uma matriz bidimensional:
//armazena 2 vetores de char, cada vetor de char armazenado pode conter 10 elementos
char matriz[2][10] = { "Natan", "santos"};
a matriz PRÉ-ALOCA o espaço de memória, assim mesmo os nomes "Natan" e "santos" não ocupando aquele espaço de 10 caracteres, aquele espaço vai ficar alocado e vazio, Isso pode gerar um consumo desnecessário de memória.
char** mapa;
Tem a mesma lógica dos vetores e ponteiros. Isso é um ponteiro de ponteiro, como uma matriz, mas ele passa pelo mesmo problema que os ponteiro, caso receba valores literais, fica sendo apenas para leitura.
vantagem de ponteiros com função 'malloc'
Quando se utiliza o 'malloc', vc pode escolher o espaço de memória a ser alocado em tempo de execução, assim não há desperdício de memória.
Mas como eu vou acessar essa memória alocada dinamicamente? Simples, utilizando um ponteiro!
Assim vc aloca o espeço necessário (no caso do seu código, para armazenar o mapa) e não gera desperdício de recurso.
Como o mapa tem linhas e colunas, vc tem que alocar o espaço necessário para as uma quantidade de linhas que vai haver vários elementos (caracteres) em cada uma, resumindo: vc vai alocar dinamicamente um vetor com varios vetores (matriz), por isso está sendo utilizado o 'char** mapa'.