fredericopissarra Posted November 3, 2019 Posted November 3, 2019 Artigo original: https://is.gd/55lrpk Alguns de vocês já devem ter lido por aqui e feito experiências com relação ao “endereço” base de um array. Considere o seguinte array: int a[] = { 1, 2, 3, 4 }; O identificador a é, de forma bastante comum, encarado como o ponteiro para o início do array. De fato, a especificação ISO 9989 nos diz que o operador [] pode ser, seguramente, interpretado como a = *(a + i). Mas, há uma distinção sutil aqui: O identificador a não é um ponteiro! Ele é interpretado como sendo um… “Porra, tio Fred, assim você dá um nó na minha cachola!”. O problema aparece quando usamos o operador & (endereço-de): #include <stdio.h> int a[] = { 1, 2, 3 4 }; int main( void ) { printf( "a=%p, &a=%p\n", a, &a ); } Ao compilar e executar isso você verá que os endereços impressos são os mesmos. Como pode um ponteiro apontar para uma coisa e um ponteiro para um ponteiro apontar para a mesma coisa? Não pode! O fato é que a, usando usado em expressões, é convertido em um ponteiro, mas ele não é um. O símbolo a aqui é um array “identificado” pelo nome a. Parece que não há diferença, não é? Então, vejamos esse outro exemplo: Se a e &a forem, de fato, o mesmo ponteiro, apontar para o próximo item do array deveria fornecer o mesmo endereço, não é? #include <stdio.h> int a[] = { 1, 2, 3 4 }; int main( void ) { printf( "a=%p, &a=%p\n", a, &a ); printf( "next(a)=%p, next(&a)=%p\n", a + 1, &a + 1 ); } Compilando e executando você obtém algo assim: $ cc -O2 -o test test.c $ ./test a=0x563c50e5a010, &a=0x563c50e5a010 next(a)=0x563c50e5a014, next(&a)=0x563c50e5a020 Ué?! Por que &a+1 resultou em um endereço diferente de a+1? Note que em nossa tentativa de obter o endereço do próximo item com o ponteiro, no primeiro caso obtemos, corretamente, o endereço 4 bytes além da base, mas no segundo (usando &a), obtemos o endereço além do final do array (16 bytes além da base)… Isso ocorre porque os tipos dos ponteiros convertidos à partir de a são diferentes… O primeiro ponteiro, a+1 é do tipo int *, o segundo, do tipo int (*)[4]. Ou seja, a e &a fornecem o mesmo endereço porque estamos obtendo o endereço do identificador a, que aponta para o início do array. No primeiro caso (a) o identificador é convertido para um ponteiro, no segundo (&a) obtemos o “endereço-do array identificado por a. Sim, você pode assumir que o identificador de um array seja um ponteiro para sua base, se usar apenas o nome do identificador como ponteiro (não o seu endereço), mas, além do problema acima, existe outro: O identificador de um array definido carrega consigo, em tempo de compilação, o tamanho do array. Se você usar o operador sizeof com o identificador a, obterá 16 (4 vezes o tamanho de um int), no exemplo acima… Se a fosse apenas um ponteiro, obteria 4 (i386) ou 8 (x86-64) que, aliás, é o que obterá se tentar obter sizeof(&a).
Recommended Posts
Archived
This topic is now archived and is closed to further replies.