Alterar ponteiro para uma matriz para obter um elemento de matriz específica
Pergunta
Eu entendo o significado geral de ponteiros e referências (ou pelo menos eu acho que eu faço), eu também entendo que quando eu uso de memória Estou alocar dinamicamente novo.
A minha pergunta é a seguinte:
Se eu fosse usar cout << &p
, ele iria mostrar o "local de memória virtual" de p
.
Existe uma maneira em que eu poderia manipular esta "posição de memória virtual?"
Por exemplo, os seguintes programas de código de uma matriz de int
s.
Se eu quisesse mostrar o valor de p[1]
e eu sabia que o "local de memória virtual" de p
, eu poderia de alguma forma fazer "&p + 1
" e obter o valor de p[1]
com cout << *p
, que agora apontam para o segundo elemento na array?
int *p;
p = new int[3];
p[0] = 13;
p[1] = 54;
p[2] = 42;
Solução
Claro, você pode manipular o ponteiro para acessar os diferentes elementos na matriz, mas você vai precisar de manipular o conteúdo do ponteiro (ou seja, o endereço do que p está apontando para), em vez do endereço do ponteiro em si .
int *p = new int[3];
p[0] = 13;
p[1] = 54;
p[2] = 42;
cout << *p << ' ' << *(p+1) << ' ' << *(p+2);
Cada adição (ou subtração) significa que o elemento posterior (antes) na matriz. Se p aponta para uma variável de 4 bytes (por exemplo, int em PCs típicos 32-bits) no endereço dizer 12345, p + 1 irá apontar para 12349, e não 12346. Nota que pretende alterar o valor de que p contém antes dereferencing-lo para acessar o que ele aponta.
Outras dicas
Não é bem assim. &p
é o endereço do p
ponteiro . &p+1
irá referir-se a um endereço que é um int*
mais adiante. O que você quer fazer é
p=p+1; /* or ++p or p++ */
Agora, quando você faz
cout << *p;
Você vai ter 54. A diferença é, p
contém o endereço do início da matriz de inteiros , enquanto &p
é a endereço de p . Para mover um item ao longo, você precisa apontar mais para o array int , e não mais ao longo sua pilha, que é onde vidas p
.
Se você só tinha &p
então você precisa fazer o seguinte:
int **q = &p; /* q now points to p */
*q = *q+1;
cout << *p;
Isso vai também de saída 54, se não me engano.
Tem sido um tempo (vários anos) desde que eu trabalhei com ponteiros, mas eu sei que se p está apontando para o início da matriz (isto é p [0]) e você incrementado-lo (ou seja, p ++), então p será agora apontando para p [1].
Eu acho que você tem que de-referência p para chegar ao valor. Você dereference um ponteiro colocando um * na frente dele.
Assim * p = 33 com a mudança p [0] a 33.
Eu estou supondo que para obter o segundo elemento que você usaria * (p + 1), de modo a sintaxe que você precisaria seria:
cout << *(p+1)
ou
cout << *(++p)
Eu gosto de fazer isso:
&p[1]
Para mim parece mais puro.
Pense em "tipos de ponteiro" em C e C ++ como que estabelece um tempo muito longo, lógico linha de células sobrepostos sobre os bytes no espaço de memória da CPU, começando no byte 0. A largura de cada célula, em bytes, depende do "tipo" do ponteiro. Cada tipo de ponteiro estabelece penas consecutivas com diferentes larguras de célula. Um ponteiro "int *"
estabelece uma linha de células de 4 bytes, uma vez que a largura de armazenamento de um int é de 4 bytes. Um "double *"
estabelece uma fileira de 8 bytes por célula; um ponteiro "struct foo *"
estabelece uma linha com cada célula a largura de um único "struct foo"
, seja o que for. O "endereço" de qualquer "coisa" é o deslocamento de byte, a partir de 0, da célula na linha segurando a "coisa".
Ponteiro aritmética é baseado em células na linha, não bytes. "*(p+10)
" é uma referência para a célula 10 passado "p", onde o tamanho da célula é determinada pelo tipo de p. Se o tipo de "p" é "int", o endereço de "p + 10" é de 40 bytes p passado; se o símbolo p representa um ponteiro para uma estrutura 1000 bytes de comprimento, "p + 10" é de 10.000 bytes p passado. (Note que o compilador começa a escolher um tamanho ideal para uma estrutura que pode ser maior do que o que você pensaria;. Isso é devido a "padding" e "alinhamento" A struct 1000 byte discutido pode realmente ter 1024 bytes por célula, por exemplo, tão "p + 10" seria realmente 10,240 bytes p passado.)