Programação C: Como trabalhar Pointer matemática em uma matriz
O que acontece quando você incrementa um ponteiro em programação C? Dizer que variável ponteiro dave faz referência a uma variável de 0x8000 endereço de memória. Se assim for, considere a seguinte declaração:
dave ++ -
Qual seria o valor do ponteiro dave ser?
Sua primeira inclinação deve ser a dizer que Dave iria ser incrementado por 1, o que é correto. Mas o resultado do cálculo pode não ser 0x8001. Isso porque o endereço armazenado em uma variável ponteiro é incrementado por um unidade, não por um dígito.
O que é uma unidade?
Depende do tipo de variável. Se ponteiro dave é um ponteiro char, na verdade, o novo endereço poderia ser 0x8001. Mas se Dave eram um int ou um flutuador, o novo endereço seria o mesmo que
0x8000 + sizeof (int)
ou
0x8000 + sizeof (float)
Na maioria dos sistemas, um int é de 4 bytes, assim que você poderia adivinhar que dave seria igual a 0x8004 após a operação de incremento. Mas por que acho que quando você pode codificar?
Arrays e Pointer Math ilustra um programa simples, algo que você pode codificar sem usar ponteiros: Preenche um array int com os valores de 1 a 10, e em seguida, exibir a matriz e os seus valores. Mas em matrizes e matemática do ponteiro, um ponteiro é utilizado para preencher a matriz.
Arrays e MATH POINTER
#include int main () {int números [10] -int x-int * pn-pn = numbers- / * inicializar ponteiro * // * Preencha array * / for (x = 0-xlt; 10 x ++) {* pn = x + 1-pn ++ -} / * matriz de exibição * / for (x = 0-xlt; 10 x ++) printf ( "números [% d] =% d n", x + 1, os números [x] ) -Retornar (0) -}
A linha 7 declara o pn ponteiro e Linha 9 inicializa-lo. o Não é necessário aqui, porque os números é uma matriz, não é uma variável individual. Nesse ponto, o ponteiro contém o endereço base da matriz. Tenha em mente que a matriz está vazia.
O circuito para a linhas 12 a 16 preenche a matriz números. O primeiro elemento é preenchido na Linha 14, utilizando a notação Peeker para PN ponteiro. Em seguida, na Linha 15, ponteiro pn é incrementado uma unidade. Ele agora aponta para o próximo elemento na matriz, e o loop se repete.
Exercício 1: Copie o código-fonte do Arrays e Pointer Math em seu editor. Construir e executar.
Exercício 2: Modificar seu código-fonte do Exercício 1 para que o endereço de cada elemento na matriz é exibido juntamente com o seu valor.
Na saída do Exercício 2, você verá que cada endereço é separado por 4 bytes (assumindo que o tamanho de um int é de 4 bytes em sua máquina). Na verdade, os endereços, provavelmente, todos fim nos dígitos hexadecimais 0, 4, 8, e C.
exercício 3: Concluir a conversão de matrizes e Pointer Math, eo que você começou no Exercício 2, por ter o segundo loop for exibir os valores da matriz usando o lado de Peeker da variável de ponteiro pn.
Exercício 4: Criar um novo projeto que preenche uma matriz de char usando ponteiros semelhantes aos mostrados na Arrays e Pointer Math. Defina o tamanho da matriz de char a 27 de modo que ele pode armazenar 26 letras. Preencher a matriz com as letras 'A' a 'Z', usando a notação ponteiro. Exibir os resultados usando a notação ponteiro.
Aqui está uma grande dica:
* Pn = x + 'A'-
SOLUÇÃO PARA O EXERCÍCIO 4
#include int main () {char alfabeto [27] -int x-char * pa-pa = alphabet- / * inicializar ponteiro * // * Preencha array * / for (x = 0-xlt; 26 x ++) {* pa = x + 'A'-pa ++ -} pa = alfabeto - / * matriz de exibição * / for (x = 0-xlt; 26 x ++) {putchar (* aa) -PA ++ -} putchar (' n ') - return (0) -}
O código-fonte na solução do Exercício 4should ser bastante lúcido, realização de cada tarefa um passo de cada vez. Mas tenha em mente que muitos programadores C gostam de combinar declarações, e tais combinações acontecer frequentemente com ponteiros.
Exercício 5: Combine as duas declarações no primeiro loop da solução do Exercício 4to ser apenas uma instrução:
* Pa ++ = x + 'A'-
Certifique-se de que você digitá-lo corretamente. Construir e executar.
A saída é o mesmo. O que essa bagunça feia faz é descrito aqui:
x + 'A'This parte da instrução é executada em primeiro lugar, adicionando o valor da variável x para a letra A. O efeito líquido é que o código marcha até o alfabeto como o valor de x aumenta.
* Pathe resultado de x + 'A' é colocado na localização de memória especificado por ponteiro PA.
++O valor do pa variável - o endereço de memória - é incrementado uma unidade. Porque a ++ aparece após a variável, o valor é incrementado depois de o valor nesse endereço é lido.
Manter as duas declarações separadas ainda funciona. Mas nem todo programador faz isso! Muitos deles gostam de empilhar ponteiros com o operador de incremento. Atente para isso! Ou, se você entendê-lo, usá-lo.
Exercício 6: Repare o seu código-fonte do Exercício 5 para que o segundo loop for usa o monstro * pa ++.
Felizmente, o * pa ++ ponteiro-coisa faz sentido. Se não, tirar uma soneca e depois voltar e examinar Head-Imploding Programa.
HPROGRAMA EAD-implodir
#include int main () {char alfa = 'A'-int x-char * pa-pa = alfa / * inicializar ponteiro * / for (x = 0-xlt; 26 x ++) putchar ((* aa) ++) - putchar ( ' n') - retorno (0) -}
O código fonte da Listagem 19-4 lida com uma variável de char único e não uma matriz. Portanto, a inicialização do ponteiro na linha 9 requer a prefixo. Não se esqueça disso!
Linha 12 neste código contém o booger (* aa) ++. É parecido com * pa ++, mas definitivamente não é. Ao contrário * pa ++, que espia um valor e, em seguida, incrementa o ponteiro, o (* aa) ++ construção incrementa um valor que está sendo espiou at- o ponteiro não é alterado.
exercício 7: Editar, construir e executar um novo programa usando o código-fonte de Head-Imploding Programa.
A operação (* aa) ++ funciona, graças aos parênteses. O programa recupera o valor representado por * pa primeiro e depois esse valor é incrementado. A variável de ponteiro, pn, não é afectada pela operação.
Para ajudar a evitar a confusão sobre este tema aqui estão as várias bugigangas notação críptica ponteiro / Peeker:
Expressão | endereço p | Valor * p |
---|---|---|
* P ++ | Incrementado após o valor é lido | inalterado |
* (P ++) | Incrementado após o valor é lido | inalterado |
(* P) ++ | inalterado | Incrementado após ele é lido |
* ++ P | Incrementado antes que o valor é lido | inalterado |
* (P ++) | Incrementado antes que o valor é lido | inalterado |
++* P | inalterado | Incrementado antes de ser lido |
++(* P) | inalterado | Incrementado antes de ser lido |