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;