Vou tentar explicar sobre ponteiros:
Explicação GERAL:
a sua memória é composta de duas partes essenciais: a posição da memória e o valor que ela armazena. Uma frase do tipo HELLO WORLD, não ocupa apenas 1 posição de memória, pois cada letra ocupa uma posição de memória. Ai é que entra os ponteiros. Os ponteiros conseguem "andar" na posição de memória e te retornar o valor que ele está apontando. No exemplo acima:
char *teste = "Hello World" representa isso na memória:
- Código: Selecionar todos
H E L L O W O R L D \0
1 2 3 4 5 6 7 8 9 10 11 12
#
A variável teste, por ser um ponteiro está apontando para a primeira posicao da memória que é aonde está o #. Se vc fizer
teste++;
o # irá para 2, uma vez que teste é o ponteiro e vc está incrementando o ponteiro. Note que a variavel que ele armazena continua a mesma. Agora se vc fizer isso:
*teste++;
Vc está dizendo que o valor que está na posição de memória é que tem que ser incrementada. Como teste está na posição 2, a letra E irá mudar para F(Veja a tabela ASCII para isso).
OBS: Toda frase em C/C++ deve terminar com \0, que é adicionado automaticamente na maioria dos casos.
Vc tem isso em C:
INICIALIZACAO:
------------------------------
int *A; --> Vc até agora só disse que A é um ponteiro, mas nao sabe para aonde está apontando. Na verdade A está apontando para lixo de memória. E o que ela está armazenando é lixo!
int *A = 0X0001 --> Vc está inicializando o ponteiro A com uma posicao. Isso quer dizer que A está apontando para a posicao de memoria 0x0001. E o que ela está armazenando é lixo!
int B --> Aqui vc está dizendo que quer uma variavel B. Isso quer dizer que o ponteiro da posicao de memória dela é automaticamente criado e vc não precisa se preocupar com isso. POrém, o valor que ela está armazenando é lixo!
int B = 0x0001 --> Esse parece igual aos outros, não é? Mas neste caso é o único que o valor armazenado está sendo setado! o valor é 0x0001. E a posição de memória?!?!?! Ela é automaticamente criada e vc não precisa se preocupar com isso. Entendeu que aqui, o valor passado vai para a posição de memória enquanto que nos segundo exemplo vc está passando o endereço da memória? Novamente neste caso a posição de memória foi criada automaticamente.
USO:
-------
Então temos que a variável A é um ponteiro e a variável B não é ponteiro. OK?
printf("%x", A); --> Aqui, se usarmos o segundo método de inicialização, teríamos 0x0001 no resultado do printf. E se usásemos a primeira inicialização? Teríamos lixo! O que é lixo? é um valor qualquer, como por exemplo 0x45D87. O que mostramos aqui é que A, por ser um ponteiro, retorna a posicao do ponteiro quando usamos ela apenas (A).
printf("%x", *A); --> Agora colocamos um *, que significa que queremos ler o que tem na posicao de memoria da variavel A. Nas duas inicializações teríamos LIXO! Porque? Porque nào passamos nenhum valor para A, apenas inicializamos o ponteiro dela. Então como fazemos para passar um valor para ela? Simplesmente fazemos *A = 0X2345;
E se fizermos A = 0x2345? Dá na mesma? NÃO! Porque isso estará mudando a posição de memória de A que agora estará apontando para 0x2345.
printf("%x", B); --> Lembra que B é uma variavél apenas, certo? Então, isso irá mostra o valor que B está armazenando. Se usarmos a quarta inicialização, teremos 0x0001.
printf("%x", *B); --> Isso vai dar error, porque B não é ponteiro, então não pode usar o * na frente dele. Para isso a gente apenas usa a variável B, que nem mostrado acima.
Tá mas ainda quero ver a posição de memória de B, é possível? Claro! é só fazer printf("%x", &B); O & mostra a posição de memória de B!
OUTROS COMANDOS LEGAIS:
----------------
Ainda usando A E B de cima:
Passar endereço de memória:
A = &B; --> Isso quer dizer que A e B estão apontando para o mesmo lugar. Ou seja, se eu mudar o valor da posicao de memoria de A, usando o *A, vou estar mudando o o valor de B. Exemplo:
int B = 0x0001; --> Iniciei B com valor de 0x0001.
int *A = &B; --> Aqui iniciei um ponteiro A com o endereço do ponteiro de B
* A = 0x0003; --> A posicao de memória de A recebeu 0x0003;
printf("%x", B); --> O valor vai ser 0x0003, uma vez que a linha de cima mudou o valor de B;
Incrementando ou descrementando:
Usamos o ++ e o -- para isso:
int B = 1; -->Valor de B é 1
B++; --> Valor de B é 2 agora
Mas para ponteiro? O que acontece?
int *A = 0x0001; --> Posicao de memória de A é 0x0001. O valor que essa posicao guarda eu nao tenho nem idéia de qual é! é lixo!
A++; --> Aqui ele incrementa o ponteiro da posicao de memória! ou seja, vc está apontando para 0x0002!
Por fim, vou explicar sobre a nossa string de character!
Quando fazemos isso:
char *teste = "ISTO É UM TESTE!!!";
Nós não sabemos aonde gravamos o teste, mas sabemos que teste está apontando para o começo da string.
Como assim?
Isso significa que quando fazemos um
printf("%s", teste);
Estamos passando o endereço inicial da string. O %s irá mostrar até achar um \0.(Entendeu porque temos automaticamente um \0 na maioria dos casos?)
internamente, o printf faz algo + - assim:
- Código: Selecionar todos
char *texto = parametro; --> Pega o endereço de parametro1(teste no nosso caso);
while(*teste != '\0') --> Verifica se a variavel é \0 e para dai.
{
printf("%c", *teste); --> imprime apenas aquele caracter
teste++; --> Incrementa o ponteiro para testar o proximo caracter
}
CUIDADOS!!!!!
---------------
se vc tiver isso:
int *A = 0x0001; --> O endereço de memória de A é 0x0001
int *B = A; --> B tem o mesmo endereço de memória de A
A = 0x0003 --> Mudei o endereço de A é mudado para 0x0003
Somente B agora sabe como pegar novamente o valor de A, pois B ainda tem o endereço de A, que é 0x0001. Quer um exemplo prático?
- Código: Selecionar todos
char *A = "TESTE123" ;
char *B = A;
while (*A != '\0')
{
A++;
}
printf("A variavel A tem %d caracteres!", A - B);
Explicacao: A variavel A PERDEU o seu ponteiro inicial, uma vez que eu fiz A++ e o ponteiro andou. Mas a variavel B salvou a posicao inicial de A. Então, apenas fazendo uma subtracao de A com B, sabemos a quantidade de elementos que tem neste vetor.
Acho que isso.
Desculpa se foi longa a explicação, mas tava vendo algumas coisas chatas aqui no trampo e isso me deixou mais relaxado para continuar a trabalhar agora!
[]'s