De Objective Caml para C e C++/Construção de tipos: diferenças entre revisões

[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
Linha 341:
float * pf = &x;
Foram declaradas três variáveis:
* A variável <tt>a</tt> é um ponteiro para um trecho de memória que guarda um valor do tipo <tt>int</tt>. Observe que não tem inicialização e o valor de <tt>a</tt> é qualquer. Como uma variável de qualquer tipo, a variável <tt>a</tt> deverá ser inicializada antes de ser lida, caso contrário o comportamento do programa é indefinido.
* A variável <tt>x</tt> é uma variável não ponteiro, do tipo <tt>float</tt>.
* A variável <tt>pf</tt> é uma variável de tipo ponteiro para <tt>float</tt>, ou <tt>float *</tt>. É inicializada com o endereço da variável <tt>x</tt>. Diz-se que <tt>pf</tt> aponta para <tt>x</tt>.
Linha 350:
=====Ponteiros e Objective Caml=====
Em Objective Caml, um conceito similar, embora mais geral, é o de referência. O conceito de referência OCaml corresponde ao de uma variável C/C++ e também ao de ponteiro. Assim, em OCaml, um valor de tipo <tt>int ref<tt> é alguma locação de memória que contem um valor do tipo <tt>int</tt> e que pode ser alterado (dizemos que é ''mutável''). Ou seja é exatamente a mesma coisa que uma variável C ou C++ do tipo int. Tal variável pode ser lida em expressões e alterada com atribuições. O equivalente a um ponteiro C para um inteiro, ou seja a um valor do tipo <tt>int *</tt> seria, em OCaml, um valor do tipo <tt>int ref ref</tt>: corresponde à memorização de um local onde um inteiro é memorizado.
 
====O operador de dereferenciamento====
 
Dado um valor de algum tipo ponteiro, o operador de dereferenciamento permite acessar o valor do trecho de memória apontado. É um operador prefixado, que se escreve <tt>*</tt>. Se <tt>p</tt> é um valor de tipo <tt>t *</tt> (ponteiro para o tipo <tt>t</tt>), então a expressão <tt>* p</tt> é do tipo <tt>. O valor dela é o valor guardado na memória no endereço guardado por <tt>p</tt>. Por exemplo, o seguinte trecho de código
int n = 42;
int * pi = &n;
printf("O valor apontado por pi é %i.\n", *pi);
resultará na impressão da seguinte mensagem na saída padrão:
O valor apontado por pi é 42.
O resultado do operador de referenciamento é um <i>lvalue</tt>, significando que pode ser alvo de atribuição. Atribuir um valor a <tt>* p</tt> consiste em alterar o conteúdo do trecho de memória apontado por <tt>p</tt>. Por exemplo:
int n = 42;
int * pi = &n;
* pi = 44;
printf("O valor apontado por pi é %i.\n", *pi);
printf("O valor de n é %i.\n", *n);
resultará na seguinte impressão na saída padrão:
O valor apontado por pi é 44.
O valor de n é 44.
Efetivamente, <tt>n</tt> é uma variável que abstrai algum trecho de memória. <tt>pi</tt> é um ponteiro cujo valor é inicializado com o endereço desse trecho de memória. A atribuição a <tt>*pi</tt> resultará então em atribuição do trecho de memória apontado por <tt>pi</tt>, ou seja em atribuição da variável <tt>n</tt>.
 
====Confusões possíveis com os símbolos <tt>*</tt> e <tt>&</tt>====
 
Até o momento, já vimos que o símbolo <tt>*</tt> possui três papeis diferentes nas linguagens C e C++. São eles:
* operador de multiplicação para os diferentes tipos numéricos,
* construtor de expressão de tipo ponteiro.
* operador de dereferenciamento.
Também vimos dois papeis para o símbolo <tt>&</tt>, são:
* operador de conjunção bit a bit,
* operador de endereço.
Ainda tem um terceiro papel explicado mais adiante.
 
Para poder entender programas escritos nessas linguagens, é necessário então conhecer a existência desses diferentes papeis e saber identificar qual papel está sendo realizada por cada ocorrência destes símbolos. No caso do símbolo <tt>*</tt>, quando sucede a uma expressão de tipo e precede um nome, então é um construtir de tipo ponteiro. Quando precede um <i>lvalue</i> sem suceder a uma expressão de tipo, é o operador de dereferenciamento. Finalmente, quando está entre duas expressões numéricas, é o operador de multiplicação. No caso do símbolo <tt>&</tt>, quando precede um <i>lvalue</i>, sem suceder a uma expressão de tipo, é o operador de endereço. Quando está entre duas expressões inteiras, é o operador de conjunção bit a bit.
 
====O operador de dereferenciamento====