Pergunta

dizer que temos o seguinte código:

int main(){
    int a[3]={1,2,3};
    printf("      E: 0x%x\n", a);
    printf("  &E[2]: 0x%x\n", &a[2]);
    printf("&E[2]-E: 0x%x\n", &a[2] - a);
    return 1;
}

Quando compilado e executar os resultados são os seguintes:

      E: 0xbf8231f8
  &E[2]: 0xbf823200
&E[2]-E: 0x2

Eu entendo o resultado de & E [2] que é 8 mais o endereço do array, uma vez indexados por 2 e do tipo int (4 bytes no meu sistema de 32 bits), mas eu posso' t descobrir por que a última linha é 2 em vez de 8?

Além disso, o tipo da última linha deve ser -? Um inteiro ou um ponteiro de inteiro

Gostaria de saber se é o sistema de tipo C (kinda seleção de elenco) que fazem deste capricho?

Foi útil?

Solução

Você tem que lembrar que o a[2] expressão realmente significa. É exatamente equivalente a *(a+2). Tanto assim, que é perfeitamente legal para escrever 2[a] vez, com efeito idêntico.

Para que isso funcione e faz sentido, ponteiro aritmética leva em conta o tipo da coisa apontada. Mas isso é cuidado nos bastidores. Você começa a simplesmente usar compensações naturais em suas matrizes, e todos os detalhes apenas trabalhar.

A mesma lógica aplica-se às diferenças de ponteiro, o que explica o seu resultado de 2.

De acordo com o capuz, no seu exemplo o índice é multiplicado por sizeof(int) para obter um deslocamento de byte, que é adicionado para o endereço de base da matriz. Você expor esse detalhe em suas duas marcas dos endereços.

Outras dicas

Ao subtrair ponteiros do mesmo tipo, o resultado é o número de elementos e não o número de bytes. Isso ocorre por design para que você pode facilmente matrizes de index de qualquer tipo. Se você quiser número de bytes -. Expressos os endereços para char *

Quando você incrementa o ponteiro por 1 (p + 1), em seguida, ponteiro faria aponta para próxima endereço válido por adição de (p + sizeof (Type)) bytes para p. (Se Type é int então p + sizeof (int))

Lógica semelhante vale para p-1 também (de subtrair claro, neste caso).

Se você acabou de aplicar esses princípios aqui:

Em termos simples:

a[2] can be represented as (a+2)
a[2]-a      ==>  (a+2) - (a)    ==> 2

Assim, por trás da cena,

a[2] - a[0]  
==> {(a+ (2* sizeof(int)) ) - (a+0) }  / sizeof(int) 
==> 2 * sizeof(int) / sizeof(int) ==> 2

A linha & E [2] -2 está fazendo ponteiro subtracção, não inteiro subtração. subtração de ponteiro (quando ambos os ponteiros apontam para dados do mesmo tipo) retorna a diferença dos endereços em dividida pelo tamanho do tipo que apontam para. O valor de retorno é um int.

Para responder à sua pergunta "update", mais uma vez a aritmética de ponteiro (desta vez ponteiro disso) está sendo realizada. Ele é feito desta forma em C para torná-lo mais fácil de "index" um pedaço de dados contíguos apontado pelo ponteiro.

Você pode estar interessado em Aritmética de ponteiro Em C de perguntas e respostas.

Basicamente, + e - operadores tomem tamanho do elemento em consideração quando usado em ponteiros

.

Quando somar e subtrair ponteiros em C, você usa o tamanho do tipo de dados em vez de endereços absolutos.

Se você tem um ponteiro int e adicionar o número 2 para ele, ele vai avançar 2 sizeof * (int). Da mesma forma, se você subtrair dois ponteiros int, você vai obter o resultado em unidades de sizeof (int) em vez da diferença entre os endereços absolutos.

(Ter ponteiros usando o tamanho do tipo de dados é bastante conveniente, de modo que você, por exemplo, pode simplesmente usar p++ vez de ter que especificar o tamanho do tipo de cada vez:. p+=sizeof(int))

Re: "Em addtion, que tipo da última linha deve ser um inteiro, ou um ponteiro inteiro ??"

um inteiro / número. da mesma forma que a: Hoje - 01 de abril = número. não a data

Se você quiser ver a diferença byte, você terá para um tipo que é 1 byte de tamanho, como este:

printf("&E[2]-E:\t0x%x\n",(char*)(&a[2])-(char*)(&a[0]))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top