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.

image0.jpg

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ãoendereço pValor * p
* P ++Incrementado após o valor é lidoinalterado
* (P ++)Incrementado após o valor é lidoinalterado
(* P) ​​++inalteradoIncrementado após ele é lido
* ++ PIncrementado antes que o valor é lidoinalterado
* (P ++)Incrementado antes que o valor é lidoinalterado
++* PinalteradoIncrementado antes de ser lido
++(* P)inalteradoIncrementado antes de ser lido

menu