Índices negativos?!

O post anterior deixou de explicar o possível fenômeno de uso de índices negativos, quando usamos arrays. Sim! É possível, e às vezes, necessário. Considere o seguinte caso:

char str[] = "Frederico Pissarra";
char *p = &str[10];

O ponteiro ‘p’ apontará exatamente para a posição do array ‘str’ que contém o char ‘P’.

E se eu tiver acesso apenas ao ponteiro ‘p’ e quiser apontar para o char ‘F’?

printf("%s\n", &p[-10]);

A função acima vai imprimir a string inteira!!!

Lembre-se que o operador ‘[]’, no caso de ‘p[-10]’, é apenas um atalho para:

*(p - 10);

Assim, se o ponteiro ‘p’ for encarado como endereço base, o índice de um array é um offset, que pode ser negativo! Ou seja, seu array pode começar num offset negativo, depende de como o ponteiro para ele foi inicializado.

Vale lembrar, de novo, que a declaração de um array também é uma declaração de um ponteiro (o nome do array) que aponta para uma região da memória de tamanho definido (o tamanho do array informado). No exemplo de ‘str’ o tamanho é de 19 chars (incluindo o ” final). Neste caso, ‘str’ aponta o para a posição 0 do array. Mas nada nos impede de declarar um ponteiro que aponte para o meio de um array!!

Sob o ponto de vista da linguagem C a variável ‘str’ é encarada como um ponteiro, mas um que não pode ser alterado. O ponteiro ‘p’, por outro lado, pode apontar para qualquer lugar…

Anúncios

5 comentários sobre “Índices negativos?!

  1. Frederico, em primeiro lugar, agradeço por compartilhar sempre um excelente conteúdo. Estou acompanhando seu site há pouco tempo mas todos os posts me convidam por serem sobre bits (o que me fascina).

    Bom, estou curioso a respeito de índices negativos, uma vez que sei que não há obstrução pelo compilador por conta da aritmética de ponteiros , “The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))”, no entanto, posso citar aqui outro trecho do core book (K&R):

    “If one is sure that the elements exist, it is also possible to index backwards in an array; p[-1] , p[-2] , and so on are syntactically legal, and refer to the elements that immediately precede p[0] . Of course, it is illegal to refer to objects that are not within the array bounds.”

    E do ISO/IEC 9899:201x:

    “An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6)

    6.5.6
    10 EXAMPLE
    Pointer arithmetic is well defined with pointers to variable length array types.
    {
    int n = 4, m = 3;
    int a[n][m];
    int (*p)[m] = a;
    p += 1;
    (*p)[2] = 99;
    n = p – a;
    }
    11 If array a in the above example were declared to be an array of known constant size, and pointer p were declared to be a pointer to an array of the same known constant size (pointing to a), the results would be the same.”

    De toda sorte, o uso de índices negativos, sintaticamente, está ok, mas é um acesso ilegal no que se refere a objetos além dos limites do array em questão.

    Sem falar que podemos ter um wrap-arround no endereço [2], concorda?

    Aparentemente há outros caveats [3-4] também.

    [] o/

    Fontes:
    [1] http://stackoverflow.com/questions/3473675/negative-array-indexes-in-c
    [2] http://c-faq.com/aryptr/non0based.html
    [3] http://www.devx.com/tips/Tip/41349
    [4] http://stackoverflow.com/a/2361940/2776344

      1. Geyslan, acredito que o seu comentário cobre tudo sobre o assunto…

        – Usar índices negativos é possível;
        – Ultrapassar as fronteiras de um array pode causar problemas;

        Qual outro problema você tem em mente? De repente, estou deixando passar algo importante!

Deixe um comentário

Faça o login usando um destes métodos para comentar:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s