Ao ler um artigo descrevendo as diferenças de OO e programação funcional , deparei-me com indicadores de função. Já faz um tempo desde que terminei meu curso de Ciência da Computação (2003) e, portanto, procurei indicadores para refrescar minha memória.
Ponteiros são variáveis que contêm uma referência a um endereço de memória. Eles podem ser considerados para apontar para os dados contidos nesse endereço de memória, se esses dados existirem. Ou, como no caso do artigo, eles podem indicar o ponto de entrada para uma seção do código e podem ser usados para chamar esse código.
Por que isso é diferente de uma variável? Variáveis são nomes simbólicos para endereços de memória e os compiladores substituirão o nome pelo endereço real. Isso significa que as variáveis contêm referências aos locais da memória e podem ser consideradas como apontando para os dados nesse endereço, se esses dados existirem.
Se a diferença está no comportamento (talvez um ponteiro não possa ser reatribuído em tempo de execução ou apenas um nome de variável simbólico possa ser atribuído, e não qualquer outro valor), isso não significa que é apenas uma variável de um tipo específico, o tipo de ponteiro? Da mesma maneira, uma variável declarada como do tipo inteiro é restringida pela compilação para a qual ela pode ser usada.
O que estou perdendo aqui?
fonte
Respostas:
Sua pergunta é interessante de várias maneiras, pois requer distinções cuidadosas para vários problemas. Mas sua visão me parece essencialmente correta. Não li sua referência antes de escrever a maior parte desta resposta para evitar influenciar minha resposta.
Primeiro, sua afirmação
Variables are symbolic names for memory addresses
está quase correta, mas confunde o conceito e sua implementação usual. Uma variável é na verdade apenas um contêiner que pode conter um valor que pode ser alterado. Geralmente, esse contêiner é implementado em um computador como um monte de espaço na memória, caracterizado por endereço e tamanho, já que as variáveis podem conter objetos que requerem representações com mais ou menos informações.Mas considerarei principalmente um ponto de vista mais abstrato da semântica das linguagens, independentemente das técnicas de implementação.
Portanto, variáveis são apenas contêineres de um ponto de vista abstrato. Esse contêiner não precisa ter um nome. No entanto, os idiomas geralmente têm variáveis nomeadas pela associação a um identificador, para que os usos da variável possam ser expressos pelo identificador. Uma variável pode realmente ter vários identificadores através de vários mecanismos de alias. Uma variável também pode ser uma subparte de uma variável maior: um exemplo é uma célula de uma variável de matriz, que pode ser nomeada especificando a variável de matriz e o índice da célula, mas também pode ser associada a identificadores por meio de alias.
Estou usando deliberadamente o contêiner de palavras que é um pouco neutro, para evitar invocar outras palavras que podem ser semanticamente carregadas tecnicamente. Na verdade, está próximo do conceito de referência descrito na wilipedia , que geralmente é confundido com um endereço de memória. A palavra ponteiro em si é muitas vezes entendida como um endereço de memória, mas não acho que isso seja significativo ao considerar a maioria das linguagens de alto nível e provavelmente inapropriado no documento de discussão a que você se refere (embora os endereços possam ser usados), pois é inapropriado. referindo-se a uma implementação específica. No entanto, é apropriado para uma linguagem como C, que deveria estar muito mais próxima dos conceitos de implementação e da arquitetura da máquina.
Na verdade, se você examinar variáveis ou valores no nível de implementação, pode haver vários sistemas complexos de indireção, de "indicadores no nível da máquina", mas que são (e devem ser) invisíveis para o usuário, de modo que o ponto de vista abstrato Eu desenvolvo pode ser válido. Para a maioria das linguagens de programação, o usuário não precisa se preocupar, ou mesmo saber, sobre implementação, pois a implementação pode variar muito para um determinado idioma. Isso pode não ser verdade para alguns idiomas, como C, que são intencionalmente próximos da arquitetura da máquina, como um substituto avançado para linguagens assembly que estão quase diretamente relacionadas à codificação binária explícita, mas com um nível muito baixo para uso conveniente na maioria dos casos. situações.
O que o usuário de um idioma deve saber e, às vezes, deve ser ainda menor que isso, são o que são valores e operações associadas, onde podem estar contidos, como podem ser associados a nomes, como o sistema de nomes funciona, como pode tipos de valores sejam definidos, etc.
Portanto, outro conceito importante é identificadores e nomeação. A nomeação de uma entidade (um valor) pode ser feita associando um identificador a um valor (geralmente em uma declaração). Mas um valor também pode ser obtido aplicando operações a outros valores nomeados. Os nomes podem ser reutilizados e existem regras (regras de escopo) para determinar o que está associado a um determinado identificador, de acordo com o contexto de uso. Também existem nomes especiais, chamados literais, para nomear os valores de alguns domínios, como números inteiros (por exemplo, ) ou booleanos (por exemplo, verdadeiro ).612
A associação de um valor imutável a um identificador é geralmente chamada de constante. Os literais são constantes nesse sentido.
"Contêineres de valor" também podem ser considerados valores, e sua associação com um identificador é uma variável no sentido "ingênuo" usual que você está usando. Então você pode dizer que uma variável é uma "constante de contêiner".
Agora você pode se perguntar qual é a diferença entre associar um identificador a um valor (declaração constante) ou atribuir um valor a uma variável, ou seja, armazenar o valor no contêiner definido como uma constante do contêiner. Essencialmente, a declaração pode ser vista como uma operação que define uma notação, que associa um identificador que é uma entidade sintática a algum valor que é uma entidade semântica. A atribuição é uma operação puramente semântica que modifica um estado, ou seja, modifica o valor de um contêiner. Em certo sentido, a declaração é um meta-conceito sem efeito semântico, além de fornecer um mecanismo de nomeação (isto é, sintático) para entidades semânticas.
Na verdade, as atribuições são operações semânticas que ocorrem dinamicamente à medida que o programa é executado, enquanto as declarações têm uma natureza mais sintática e geralmente devem ser interpretadas no texto do programa, independentemente da execução. É por isso que o escopo estático (isto é, o escopo textual) é geralmente a maneira natural de entender o significado dos identificadores.
Depois de tudo isso, posso dizer que um valor de ponteiro é apenas outro nome para um contêiner, e uma variável de ponteiro é uma variável de contêiner, ou seja, um contêiner (constante) que pode conter outro contêiner (com possíveis limitações no jogo contido impostas por alguns sistema de tipos).
Em relação ao código, você declara
[pointers] might indicate the entry point to a section of code and can be used to call that code
. Na verdade, isso não é bem verdade. Uma seção do código geralmente não faz sentido sozinha (do ponto de vista de alto nível ou implementação). Do ponto de vista de alto nível, o código geralmente contém identificadores, e você deve interpretá-los no contexto estático em que foram declarados. Mas, na verdade, existe uma possível duplicação do mesmo contexto estático, devido essencialmente à recursão, que é um fenômeno dinâmico (tempo de execução), e o código só pode ser executado em uma instância dinâmica apropriada do contexto estático. Isso é um pouco complexo, mas a consequência é que o conceito apropriado é o de um fechamento que associa um pedaço de código e um ambiente em que os identificadores devem ser interpretados. O fechamento é o conceito semântico adequado, ou seja, é um valor semântico adequadamente definível. Então você pode ter constantes de fechamento, variáveis de fechamento,Uma função é um fechamento, geralmente com alguns parâmetros para definir ou inicializar algumas de suas entidades (constantes e variáveis).
Estou pulando muitas variações nos usos desses mecanismos.
Os fechamentos podem ser usados para definir estruturas de OO em linguagens imperativas ou funcionais. Na verdade, o trabalho inicial no estilo OO (provavelmente antes do nome) foi feito dessa maneira.
O artigo que você mencionou, que eu examinei rapidamente, parece ser interessante, escrito por uma pessoa competente, mas possivelmente não é uma leitura fácil se você não tiver uma experiência significativa com uma variedade de idiomas e seus modelos computacionais subjacentes.
Mas lembre-se: muitas coisas estão nos olhos de quem vê, desde que ele preserve uma visão consistente. Os pontos de vista podem ser diferentes.
Isso responde sua pergunta?
PS: Esta é uma resposta longa. Se você considera uma parte inadequada, seja explícito sobre qual é. Obrigado.
fonte
A diferença é por definição e aplicação, um ponteiro é uma variável especializada para armazenar um endereço de memória de outra variável; em termos OO, talvez se considere que um ponteiro herda seu comportamento de uma classe geral chamada variável.
fonte