O que é a posição [-1] em array ? [RESOLVIDO]

1. O que é a posição [-1] em array ? [RESOLVIDO]

Thiago Henrique Hüpner
Thihup

(usa Manjaro Linux)

Enviado em 10/02/2016 - 23:23h

Olá!

Estava estudando uns códigos, e me deparei com algo parecido com isto:


union VALUE {
long l;
float f;
char *s;
void *p;
};

VALUE *sp;

/*[...]*/

sp[-1].l *= sp[0].l;



E fiquei me perguntando: Posição -1 será a ultima posição do vetor? Dai fiz alguns testes e sempre a posição [-1] possui o valor 1, sendo que é possível alterar o valor desta posição e não afeta os outros elementos do array.

O que isto pode ser? É algum glitch/bug do compilador? Ocorre "buffer underflow" ou algo do gênero?

Abs

Thiago


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 11/02/2016 - 00:21h

O fato de sp no seu exemplo ser um ponteiro, e não um array, é bastante relevante.

Considere o seguinte: um ponteiro p pode apontar para qualquer elemento de um array A. Então, se ele apontar para o n-ésimo elemento de A (do segundo em diante), p+1 aponta para o (n+1)-ésimo elemento e, por simetria, p-1 aponta para o (n-1)-ésimo elemento. Tendo p e sabendo para qual elemento de A ele aponta, se você quiser acesso ao elemento imediatamente anterior, pode fazer “*(p-1)”.

Além disso, como “*(P+N)”, sendo P um ponteiro derreferenciável e N um inteiro qualquer (inclusive negativo), é sinônimo de “P[N]” (e também de “N[P]”, embora eu nunca tenha visto alguém usando isso), “*(p-1)” pode perfeitamente ser escrito como “p[-1]”.

Segue um exemplo (muito ridículo e artificioso, mas funcional) de um código que converte espaços em quebras de linha numa string.

void sp2lf(char *str){
while(*str!='\0')
if(isspace((unsigned char)(*str++)))
str[-1]='\n';
}


Preste atenção, no entanto, que tudo o que eu disse acima vale para ponteiros. Arrays são outra história.

Aplicar índices negativos a um array para obter um elemento é logicamente errado e produz comportamento indefinido.

Entretanto, se não me falha a memória, existe um único caso oficialmente válido (i.e. em conformidade com o padrão) de índice negativo de array, mas somente quando o valor é exatamente -1, e somente se esse índice não for usado para manipular elementos, mas apenas para obter um endereço (i.e., para um array A, “A-1” ou “&A[-1]”, nunca “*(A-1)” ou “A[-1]”) a fim de compará-lo com um ponteiro. Isso permite a construção de loops para percorrer o array em ordem reversa, usando o endereço imediatamente anterior ao início do array como condição de parada.

Veja um exemplo (de novo, artificioso e tosco, mas funcional).

int array[50];
/*
Começo com “&array[50]” (mesmo que “array+50”) e termino com
“&array[-1]” (igual a “array-1”). Sem o operador &, as duas
operações seriam inválidas.
*/
for(int *p=&array[sizeof array/sizeof *array]; --p>&array[-1];)
*p=p-array;


3. Re: O que é a posição [-1] em array ? [RESOLVIDO]

Sergio
SergioRR

(usa Linux Mint)

Enviado em 10/02/2016 - 23:41h

Olá Thihup.
Em algumas linguagens de programação como o php, shell script entre outras, está disponível o artíficio de utilizar um índice negativo como forma de referênciar os elementos do array na ordem do final para o começo. Porém não é o caso do C. Neste caso você está apenas referenciando uma posição com base no endereço de memória do array.
Executar um programa com esta notação, não vai executar um erro de compilação porque o C não faz essa checagem, isto fica a cargo do programador. Então mesmo que o seu array inicial esteja definido com, por exemplo 10 posições, e no seu código você manipular por exemplo a posição 15, não vai ocorrer erro de compilação, porém, podem ocorrer erros diversos por você estar utilizando espaço que não foi devidamente alocado.
Espero ter ajudado, se estiver falando alguma bobagem, alguém por favor me corrija.



4. Re: O que é a posição [-1] em array ? [RESOLVIDO]

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 11/02/2016 - 08:56h

Thihup escreveu:
Olá!
Estava estudando uns códigos, e me deparei com algo parecido com isto:

union VALUE {
long l;
float f;
char *s;
void *p;
};
VALUE *sp;
/*[...]*/
sp[-1].l *= sp[0].l;

E fiquei me perguntando: Posição -1 será a ultima posição do vetor? Dai fiz alguns testes e sempre a posição [-1] possui o valor 1, sendo que é possível alterar o valor desta posição e não afeta os outros elementos do array.
O que isto pode ser? É algum glitch/bug do compilador? Ocorre "buffer underflow" ou algo do gênero?
Abs
Thiago


____________________________________________________________
Bom dia Thiago.
Não conheço a linguagem "C", mas, em JavaScript, quando você busca um elemento na ARRAY, e o mesmo não é encontrado, é retornado "-1", caso contrario retorna a posição do mesmo.

Att.:
Marcelo




5. Re: O que é a posição [-1] em array ? [RESOLVIDO]

Thiago Henrique Hüpner
Thihup

(usa Manjaro Linux)

Enviado em 11/02/2016 - 12:27h

Meus parabéns Paulo! Excelente explicação, como sempre.

Só vou ver se consigo entender certinho qual o objetivo do [-1] no código, mas como está escrito que é o "topo da pilha" acho que já tenho em mente o que possa ser.

[]'s

T+

--

Att,

Thiago Henrique Hüpner

(Mensagem scaneada pelo antivírus........ops! não precisa, afinal eu uso Linux!)



6. Re: O que é a posição [-1] em array ? [RESOLVIDO]

???
gokernel

(usa Linux Mint)

Enviado em 11/02/2016 - 12:35h

Olá !

Acho que no meu note tem um código similar a esse... ;). acredito que isso tenha algo com: ( "PUSH", "POP" "PILHA" )

Veja aqui um pequeno exemplo:
http://codepad.org/XcYyBPef

Esse seu código que vc postou acho que está incompleto .

Vc nunca poderá/deverá usar esse código sem antes passar um valor para a "pilha" ( stack ).

LEMBRANDO: no final que qualquer operação eh necessario um "POP" .. caso isso não ocorra o fim é CRÍTICO. ... veja o resultado, ( sp-stack ) deve ser 0 para UM SUCESSO:

RESUMO: -1 se refere ao primeiro valor passado para a "pilha" ...

Espero que esse comentário tenha ajudado !

T++.







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts