Incremento e Decremento de Ponteiros
O operador ++
adiciona 1 a uma variável. Já vimos seu uso com inteiros (veja Operadores de Incremento e Decremento), mas ele também funciona com ponteiros. Por exemplo, suponha que temos uma série de inteiros positivos, terminada por zero, e queremos somá-los. Aqui está uma forma simples de percorrer esse array avançando um ponteiro:
int
sum_array_till_0(int *p)
{
int sum = 0;
for (;;)
{
/* Busca o próximo inteiro. */
int next = *p++;
/* Sai do laço se for 0. */
if (next == 0)
break;
/* Adiciona ao total acumulado. */
sum += next;
}
return sum;
}
A instrução break;
será explicada mais adiante (veja ). Nesse uso, ela interrompe imediatamente o for
mais próximo.
A expressão *p++
usa o pós-incremento (++
; veja Pós-incremento e Pós-decremento) no ponteiro p
. Ela é interpretada como *(p++)
, pois operadores pós-fixados têm precedência sobre os prefixados. Portanto, primeiro é feita a desreferência do valor atual de p
, e só depois p
é incrementado.
Incrementar um ponteiro significa somar 1 a ele, como em p = p + 1
. Como p
é um ponteiro, somar 1 a ele o avança pelo tamanho do dado apontado — neste caso, sizeof(int)
. Assim, cada iteração do laço busca o próximo inteiro da sequência e o armazena em next
.
Esse for
não tem expressão de inicialização (pois p
e sum
já estão inicializados), nem de condição final (o break
faz isso), nem de avanço explícito (que é feito dentro do laço com p++
e sum += next
). Por isso, as três expressões no cabeçalho do for
são deixadas vazias.
Outra forma de escrever essa função é mantendo p
fixo e usando indexação para acessar os inteiros no array:
int
sum_array_till_0_indexing(int *p)
{
int i;
int sum = 0;
for (i = 0; ; i++)
{
/* Busca o próximo inteiro. */
int next = p[i];
/* Sai do laço se for 0. */
if (next == 0)
break;
/* Adiciona ao total acumulado. */
sum += next;
}
return sum;
}
Nesse programa, ao invés de avançar p
, avançamos i
e o somamos a p
. (Lembre-se que p[i]
equivale a *(p + i)
.) De qualquer forma, o endereço usado para buscar o próximo inteiro é o mesmo.
Não faz diferença nesse código usar i++
ou ++i
, já que o valor da expressão não é usado. O incremento é feito apenas pelo efeito colateral.
O operador --
também funciona com ponteiros, e pode ser usado para voltar por um array, como no exemplo abaixo:
int
after_last_nonzero(int *p, int len)
{
/* Configura q para apontar logo após o último elemento. */
int *q = p + len;
while (q != p)
/* Recuar q até encontrar um elemento diferente de zero. */
if (*--q != 0)
/* Retorna o índice do elemento após o último não zero. */
return q - p + 1;
return 0;
}
Essa função retorna o tamanho da parte não nula do array especificado por seus argumentos — isto é, o índice do primeiro zero na sequência final de zeros.
Atualizado
Isto foi útil?