Qual é a diferença entre uma variável e um local de memória? [fechadas]

38

Recentemente, tenho tentado explicar ponteiros de maneira visual, como cartões de memória flash.

Pergunta 001: Este é o desenho de um local na memória do computador. É verdade que seu endereço é 0x23452? Por quê?

insira a descrição da imagem aqui

Resposta: Sim, porque 0x23452descreve onde o computador pode encontrar esse local.


Pergunta 002: É verdade que o caractere bestá armazenado dentro do local da memória 0x23452? Por quê?

insira a descrição da imagem aqui

Resposta: Não, porque o personagem aestá realmente armazenado dentro dele.


Pergunta 003: É verdade que um ponteiro está armazenado dentro do local da memória 0x23452? Por quê?

insira a descrição da imagem aqui

Resposta: Sim, porque o endereço da localização da memória 0x34501é armazenado dentro dela.


Pergunta 004: É verdade que um ponteiro está armazenado dentro do local da memória 0x23452? Por quê?

insira a descrição da imagem aqui

Resposta: Sim, porque o endereço de outro local de memória está armazenado dentro dele.


Agora, a parte que me preocupou. Um engenheiro de software explicou os ponteiros para mim assim:

Um ponteiro é uma variável cujo valor é o endereço de memória de outra variável.

Com base nos quatro flashcards que mostrei a todos, eu definiria ponteiros de uma maneira ligeiramente diferente:

Um ponteiro é um local de memória cujo valor é o endereço de memória de outro local de memória.

É seguro dizer que uma variável é a mesma coisa que um local de memória?

Se não, então quem está certo? Qual é a diferença entre uma variável e um local de memória?

progner
fonte
37
Há um pressuposto implícito aqui que todos lendo essas imagens vai saber a sua intenção de que o número hexadecimal sob a caixa é um endereço de memória, e que o a, 0x23453. niletc coisas dentro deles são os valores. Isso pode lhe parecer óbvio, mas eu não me sentiria confortável em dar respostas decisivas a essas perguntas sem ver como esses campos são definidos. Realmente não há como saber se, ana segunda imagem, há um caractere, uma string (se houver alguma diferença) ou o nome de uma variável. Se é uma string, niltambém é uma string? Ou um valor "nulo"?
ilkkachu
39
A pergunta 1 é uma pergunta ruim. Isso é algo que você precisa dizer aos leitores antes que eles possam responder às outras perguntas. Em vez de uma pergunta, deve haver informações fornecidas ao leitor: "Nas perguntas a seguir, as caixas são localizações de memória e os números hexadecimais abaixo são seus endereços".
17 de 26 de
15
A pergunta 3 é impossível de responder, dado o contexto. Não há como dizer no nível de bytes como o valor armazenado na memória está sendo interpretado / usado no nível do aplicativo.
17 de 26 de
6
Vale notar: tudo o que você está escrevendo aqui é verdadeiro para C ou C ++, mas falso para basicamente qualquer linguagem que não tenha referência / desreferenciação explícitas de ponteiros. Toda a metáfora de variáveis ​​que são slots que os valores são divididos em uma linguagem (como Python, Java, C #, Ruby, JavaScript ou muitas outras) em que a atribuição apenas faz uma variável apontar para um objeto sem copiá-lo , e as mutações no objeto são visíveis em todas as variáveis ​​que apontam para ele. A documentação do Python usa a metáfora alternativa de variáveis ​​como crachás pendurados em objetos por esse motivo.
Mark Amery
19
BTW, e me desculpe se você já entendeu isso, mas parece que isso pode ser um ponto de confusão - essa notação "0x23452" é apenas uma maneira de denotar um número no formato hexadecimal, e foi feita por conveniência. Mas é apenas um número - de maneira alguma o prefixo 0x indica que é um ponteiro, o que é armazenado na memória é literalmente apenas um número sem sentido (você pode rotular os locais da memória com números inteiros decimais simples). O significado (isto é, como o número deve ser interpretado) vem do idioma - o tipo da variável e a maneira como ela é usada.
Filip Milovanović

Respostas:

69

Uma variável é uma construção lógica que é direcionada à intenção de um algoritmo, enquanto um local de memória é uma construção física que descreve a operação de um computador. De um modo geral, para executar um programa, existe um mapeamento (gerado pelo compilador) entre a noção lógica de uma variável e o armazenamento do computador.

(Mesmo na linguagem assembly, temos uma noção de variáveis ​​(lógicas) que vão para o algoritmo e a intenção e os locais (físicos) da memória, embora sejam mais conflitantes no assembly.)

Uma variável é um conceito de nível mais alto. Uma variável representa um desconhecido (como em matemática ou atribuição de programação) ou um marcador de posição que pode ser substituído por um valor (como em programação: parâmetros).

Um local de memória é um conceito de nível mais baixo. Um local de memória pode ser usado para armazenar um valor, às vezes, para armazenar o valor de uma variável. No entanto, um registro de CPU é outra maneira de armazenar o valor de algumas variáveis. Os registradores da CPU também são locais de armazenamento de baixo nível, mas não são locais de memória, pois não possuem endereços, apenas nomes.

Em certo sentido, uma variável é um mecanismo de abstração para expressar a intenção do programa, enquanto um local de memória é uma entidade física do ambiente de processamento que fornece armazenamento e recuperação.

Pergunta 003: É verdade que um ponteiro está armazenado dentro do local da memória 0x23452? Por quê?

Não podemos dizer com certeza. Só porque existe um valor lá que funcionaria como endereço, não significa que seja esse endereço, mas sim o número inteiro (decimal) 144466. Não podemos fazer suposições sobre a interpretação dos valores apenas com base em como eles aparecem numericamente.

Pergunta 004: É verdade que um ponteiro está armazenado dentro do local da memória 0x23452? Por quê?

Esta é realmente uma pergunta estranha. Eles esperam algumas suposições com base nas caixas, no entanto, observe que os endereços aumentam em 1 para cada caixa. Em qualquer computador moderno, isso significa que cada caixa pode conter uma capacidade de endereçamento de byte a byte já é a norma há décadas. No entanto, um byte tem apenas 8 bits e pode variar de 0 a 255 (para valores não assinados); no entanto, eles mostram um valor muito maior armazenado em um desses endereços, muito suspeito. (Isso poderia funcionar se fosse uma máquina endereçada por palavras, mas não diz isso, e poucas máquinas atualmente o são, embora algumas máquinas educacionais sejam).

Com base nos quatro flashcards que mostrei a todos, eu definiria ponteiros de uma maneira ligeiramente diferente:

Um ponteiro é um local de memória cujo valor é o endereço de memória de outro local de memória.

Embora existam situações em que esse pensamento esteja correto, você está misturando metáforas aqui. A noção de uma variável vai para o algoritmo e sua intenção - não é necessário assumir que todas as variáveis ​​têm localizações de memória. Algumas variáveis ​​(especialmente matrizes) possuem locais de memória porque os locais de memória suportam endereçamento (enquanto os registros da CPU podem ser nomeados apenas como não indexados).

Para execução, existe um mapeamento lógico entre variáveis ​​e instruções e localizações da memória do processador e seqüências de instruções do processador. Uma variável cujo valor nunca muda (por exemplo, uma constante) nem exige necessariamente um local de memória, pois o valor pode ser reproduzido à vontade (por exemplo, conforme necessário para seqüências de código geradas pelo compilador).

Erik Eidt
fonte
4
E mesmo os bytes de 8 bits ainda não são universais.
Deduplicator
14
@JimmyJames Considere o caso de um foríndice de loop quando o compilador decide desenrolar completamente o loop. Em nenhum lugar do código de saída produzido (seja montagem, código de máquina ou código de bytes), há um local de memória no qual o contador de loop é armazenado. Mas ainda é uma variável.
dmckee
4
@JimmyJames, No caso do ponteiro de loop desenrolado, sim, se o seu código realmente usar o valor do contador, ele deverá ser carregado em algum lugar , mas (a) esse local poderá ser um registro e (b) em princípio, não há razão para que ele tenha o mesmo local em todas as iterações do loop desenrolado.
Solomon Slow
3
Se o loop estiver executando algo como copiar uma matriz de comprimento fixo sourcepara uma matriz de igual comprimento, destum loop codificado for (int i=0; i<8; ++i) dest[i] = source[i];pode ser compilado até algo equivalente à repetição do dest++ = source++;número apropriado de vezes. Com o próprio contador de loops não está em evidência em lugar algum (nem mesmo em registro), e apenas o número de repetições informa sobre a condição do loop.
dmckee
2
A distinção é um tanto confusa por linguagens como C, cuja semântica se baseia intimamente na abstração de uma máquina cuja memória consiste em localizações numeradas.
Michael Kay
20

É seguro dizer que uma variável é a mesma coisa que um local de memória?

Não. A variável e a localização da memória são duas abstrações em dois níveis diferentes de abstração. Variável e ponteiros são um conceito de nível superior no nível do código / idioma, a localização da memória é um conceito de nível inferior no nível da máquina. Depois que um código foi compilado em um executável, não há mais variáveis. Tentar falar sobre a localização da memória e variáveis ​​dessa maneira é um erro categórico.

Uma variável pode ser implementada usando a memória, mas nem sempre como um compilador pode otimizar um cálculo e fazer todos os cálculos relacionados a uma variável inteiramente em registradores, ou pode colocar uma única variável em vários locais da memória ou pode usar uma única memória local para várias variáveis.

Um ponteiro é um local de memória cujo valor é o endereço de memória de outro local de memória.

Essa série de cartões de memória é tão confusa que eles não apenas não estão certos, mas também não estão errados.

Lie Ryan
fonte
1
Once a code had been compiled into an executable, there's no longer any variables.Isso é algo que eu discordo. É correto que sua variável como você a conhece (ou seja, com esse nome) não exista mais, mas seu fraseado parece sugerir que o executável compilado usa apenas endereços de memória. Isso não está correto. Seu executável compilado, mas não em execução, não tem idéia de quais endereços de memória serão usados ​​quando executados. O conceito de uma variável (isto é, uma referência reutilizável para qualquer endereço de memória que será atribuído em tempo de execução) ainda existe dentro do executável compilado.
Flater
2
Ou o compilador pode otimizar completamente a variável, de várias maneiras. Pré-computando algo, removendo variáveis ​​desnecessárias. Se a variável for uma constante, o compilador pode acabar usando instruções da CPU que usam constantes, e eu diria que não conta mais como a variável em qualquer lugar.
kutschkem 29/08
16

Variáveis ​​são construções de linguagem . Eles têm um nome, residem em um escopo, podem ser referenciados por outras partes do código, etc. Eles são uma entidade lógica . O compilador é livre para implementar essa construção de linguagem da maneira que desejar, desde que o comportamento observável seja o prescrito pelo padrão de linguagem. Como tal, a variável nem precisa ser armazenada em nenhum lugar se o compilador puder provar que isso não é necessário.

Locais de memória são um conceito de hardware . Eles significam um lugar na memória virtual / física. Cada local de memória possui exatamente um endereço físico e qualquer quantidade de endereços virtuais que podem ser usados ​​para manipulá-lo. Mas sempre há exatamente um byte armazenado em cada local da memória.

Ponteiros são um tipo especial de valores . Dizer que algo é um ponteiro é semelhante a dizer que algo é do tipo double. Significa quantos bits são usados ​​para o valor e como esses bits são interpretados, mas isso não significa que esse valor seja armazenado em uma variável, nem significa que esse valor seja armazenado na memória.


Para dar um exemplo em C: Quando tenho uma matriz 2D int foo[6][7];e acesso um elemento dela foo[1][2], fooé uma variável que mantém uma matriz. Quando fooé usado neste contexto, é transformado em um ponteiro para o primeiro elemento da matriz. Esse ponteiro não é armazenado em nenhuma variável, nem na memória, seu valor é gerado apenas dentro de um registro da CPU, usado e depois esquecido. Da mesma forma, a expressão foo[1]é transformada em outro ponteiro nesse contexto, que, novamente, não está em uma variável, não está armazenado na memória, mas é computado na CPU, usado e esquecido. A variável de três conceitos , localização da memória e ponteiro são realmente três conceitos diferentes.


Aliás, eu realmente quis dizer "sempre há exatamente um byte armazenado em cada local da memória". Esse não foi o caso na era da pedra da computação, há cinquenta anos atrás, mas é verdade para praticamente todo o hardware que está sendo usado atualmente. Sempre que você armazena um valor na memória maior que um byte, na verdade você está usando vários locais de memória consecutivos. Ou seja (assumindo a ordem dos bytes big endian), o número 0x01234567 é armazenado na memória como

+------+------+------+------+
| 0x01 | 0x23 | 0x45 | 0x67 |
+------+------+------+------+
    ^      ^      ^      ^
    |      |      |      |
 0x4242 0x4243 0x4244 0x4245

(Pequenas máquinas endian, como a arquitetura X86, armazenam os bytes na ordem inversa.) Isso também vale para ponteiros: um ponteiro em uma máquina de 64 bits é armazenado em oito bytes consecutivos, cada um com seu próprio endereço de memória. Você não pode olhar para uma célula de memória e dizer: "Oh, isso é um ponteiro!" Você sempre vê bytes apenas quando olha para a memória .

cmaster
fonte
Como o computador sabe quando um grupo de locais consecutivos de memória inicia e termina?
progner 29/08
6
@ progogner Não. Ele interpreta os bytes na memória de acordo com as instruções recebidas. Essas instruções também são armazenadas em nada além de uma sequência de bytes. Para a CPU, a única diferença entre um byte que contém uma instrução, um byte que contém um caractere e um byte que contém alguns bits de ponto flutuante, é como foi instruído a usá-lo. Se o byte é buscado porque o contador do programa aponta para ele, é usado como uma instrução. Se buscado porque uma instrução diz para carregá-lo em um registro flutuante, é usado como dados de ponto flutuante.
cmaster 29/08
7
@progner Essa foi realmente a principal inovação da arquitetura von-Neuman: armazenar instruções e dados na mesma memória, permitindo que as instruções alterem os dados que são posteriormente executados como mais instruções. Isso permitiu que o código se modificasse, mas também permite que o kernel do sistema carregue algum programa na memória e, em seguida, diga à CPU para executar esse programa. Antes de von-Neuman, computadores como as máquinas Zuse recebiam suas instruções por meio de um canal totalmente independente dos dados em que operavam.
cmaster 29/08
5

Deixe-me focar na sua pergunta real - "quem está certo?" ao comparar essas duas instruções:

  • Um ponteiro é uma variável cujo valor é o endereço de memória de outra variável
  • Um ponteiro é um local de memória cujo valor é o endereço de memória de outro local de memória.

A resposta para isso é nenhuma . O primeiro fala de um "endereço de memória de outra variável", mas as variáveis ​​não têm necessariamente endereços de memória, como as outras respostas já explicadas. O segundo diz "um ponteiro é um local de memória", mas um ponteiro é literalmente apenas um número, que pode ser armazenado em uma variável, mas, como antes, uma variável não necessariamente tem um endereço de memória.

Alguns exemplos para declarações mais precisas:

  • "Um ponteiro é um número que representa o endereço de memória de um local de memória" ou

  • "Uma variável de ponteiro é uma variável cujo valor é o endereço de memória de um local de memória."

  • "Um endereço de memória pode conter um ponteiro representando o endereço de memória de um local de memória."

Observe que algumas vezes o termo "ponteiro" é usado como um atalho para "variável do ponteiro", o que é aceitável desde que não leve à confusão.

Doc Brown
fonte
Você pode alterar "outro" para "a" porque um ponteiro pode apontar para si mesmo.
Pieter B
@ PieterB: nitty, nitty ;-) não tenho certeza se isso realmente torna mais claro, já que eu queria apenas mudar a redação original para o grau realmente necessário para torná-las sensíveis. Mas, infelizmente, eu fiz a edição.
Doc Brown
Para ser justo, se você entender esse detalhe, "mas um ponteiro é literalmente apenas um número" também não está correto, na verdade um ponteiro é um identificador que faz referência a um número;) Ou pelo menos precisávamos conhecer as especificidades do idioma para entrar nelas. detalhes.
Zaibis
2
Um ponteiro é um valor (o número já é muito específico para algumas implementações), potencialmente referente a algum objeto. Potencialmente, pois também existem indicadores nulos, indicadores selvagens e indicadores pendentes, embora alguns (ou até todos!) Deles possam ser descartados pelo idioma usado.
Deduplicator
2
@ Reduplicador: você está certo, mas acho que o modelo mental de um ponteiro como número é bom o suficiente para o objetivo desta pergunta. Então, vamos manter as coisas simples.
Doc Brown
5

Eu certamente não diria que um ponteiro é um local de memória que contém um endereço. Por um lado, não conheço uma arquitetura em que 0x23453possa caber em um único byte. :) Mesmo se você ignorar a distinção byte / palavra, ainda terá o problema de que todo local de memória contenha um endereço. Endereços são apenas números, e o conteúdo da memória são apenas números.

Eu acho que o truque aqui é que "ponteiro" descreve a intenção humana , não qualquer característica específica da arquitetura. É semelhante a como um "caractere" ou "string" não é algo concreto que você pode ver na memória - esses também são apenas números, mas funcionam como strings, porque é assim que são tratados. "Ponteiro" significa apenas um valor destinado a ser usado como um endereço.

Honestamente, se seu objetivo é ensinar um idioma específico (objetivo C?), Não tenho certeza de que desenhar a fita de memória clássica seja útil. Você já está mentindo para branco, mostrando valores digitados e valores muito grandes para um byte. Ensine semântica, não mecânica - o principal insight sobre ponteiros é que eles fornecem indireção , que é uma ferramenta extremamente útil para entender.

Eu acho que uma boa comparação pode ser com um URL, que informa onde encontrar alguns dados, mas não os dados em si. Me ouça:

  • Você raramente se importa com o que realmente é o URL ; a grande maioria deles é esquivada em links com nomes. Muitas pessoas usam a internet sem saber exatamente como um URL resulta em uma página; algumas pessoas ignoram completamente os URLs.

  • Nem toda string é um URL ou deve ser usada como um URL.

  • Se você tentar visitar um URL falso ou uma página que existia, mas que foi excluída desde então, você recebe um erro.

  • Um URL pode apontar para uma imagem, algum texto, música ou qualquer número de outros itens individuais - ou pode apontar para uma página com uma variedade de itens contidos. É muito comum ter várias páginas com layouts semelhantes, mas com dados diferentes.

  • Se você cria uma página da Web e deseja consultar dados em alguma outra página da Web, não precisa copiar e colar tudo; você pode simplesmente fazer um link para ele.

  • Qualquer número de outras páginas pode ser vinculado ao mesmo URL.

  • Se você tiver uma coleção de páginas semelhantes, poderá criar uma página de índice que lista os links para todas elas ou apenas um link "próximo" na parte inferior da página 1, que leva à página 2 e assim por diante. As vantagens e desvantagens de ambas as abordagens são imediatamente óbvias, especialmente se você considerar o que o webmaster precisaria fazer para adicionar ou remover páginas em vários lugares.

Esta analogia deixa muito claro o que os ponteiros são para , o que é fundamental para compreendê-los - caso contrário, eles parecem apenas arbitrárias, complicado, e sem sentido. Compreender como algo funciona é muito mais fácil se você já entende o que faz e por que é útil. Se você já internalizou que um ponteiro é uma caixa preta que indica onde está outra coisa, e então você aprende sobre os meandros do modelo de memória, a representação de ponteiros como endereços é bastante óbvia. Além disso, o ensino de semântica colocará seus alunos em um lugar muito melhor para entender e inventar outras formas de indireção - o que é bom quando a maioria dos idiomas principais não tem ponteiros!

Eevee
fonte
every memory location contains an address- Todo local de memória tem um endereço. Não está contido em nenhum lugar, exceto talvez em uma variável de ponteiro.
Robert Harvey
@RobertHarvey toda localização de memória (palavra, pelo menos) contém um número, que pode ser trivialmente interpretado como um endereço. o ponto era que nada no hardware realmente distingue endereços de não endereços
Eevee
2

Sei que você já aceitou uma resposta, e essa pergunta já tem cinco respostas, mas há um ponto que elas não mencionam, que eu acho que te enganou. Os livros didáticos de CS geralmente tentam ser agnósticos quanto à escolha da linguagem de programação, o que leva à suposição implícita de que a terminologia usada para descrever as coisas é universal. Não é.

Em C, o operador e comercial unário é chamado de operador "endereço de". Os programadores C não hesitam em dizer que a expressão é &xavaliada para o endereço da variável x. É claro que eles significam "o endereço de memória no qual o valor da variável x é armazenado", mas ninguém é tão pedante em conversas casuais. Em C, a palavra "ponteiro" geralmente se refere ao tipo de dado de uma variável que possui um endereço de memória como valor. Ou equivalente ao tipo de dados do valor. Mas algumas pessoas usariam "ponteiro" como o próprio valor.

Em Java, todas as variáveis ​​do tipo de objeto ou matriz se comportam muito como ponteiros C (exceto para a aritmética dos ponteiros), mas os programadores Java as chamam de referências, não de ponteiros.

O C ++ considera referências e ponteiros como conceitos diferentes. Eles estão relacionados, mas não são exatamente a mesma coisa; portanto, os programadores de C ++ precisam fazer a distinção na conversa. O "e comercial" é lido como "endereço de" em alguns contextos e "referência para" em outros.

Um ponteiro é uma variável cujo valor é o endereço de memória de outra variável.

É assim que um programador C pode descrevê-lo, usando "um ponteiro" no mesmo sentido que "um int". (Como em "um ponteiro mantém um endereço de memória enquanto um int mantém um número inteiro dentro de um determinado intervalo").

Um ponteiro é um local de memória cujo valor é o endereço de memória de outro local de memória.

É uma maneira estranha de dizê-lo, porque requer uma definição muito vaga e informal de "é".

É seguro dizer que uma variável é a mesma coisa que um local de memória?

Seria mais claro dizer que um endereço de memória é o local na memória em que o valor de uma variável é armazenado. (Concedido, nem todas as variáveis ​​são armazenadas na memória, devido a otimizações do compilador, mas qualquer variável cujo endereço seja utilizado &xserá).

Gatkin
fonte
Como estamos sendo pedantes: o endereço em que algo está armazenado. Além de um endereço não poder armazenar nada, muitas vezes as coisas são armazenadas em vários locais adjacentes, apenas um dos quais (geralmente selecionado por uma regra um tanto consistente) é endereçado (e usando apenas um dos endereços potencialmente muitos).
Deduplicator
@Duplicador Eu não estou tentando ser pedante.
gatkin
O padrão C distingue formalmente entre variáveis ​​que devem seguir estritamente as etapas da máquina abstrata em cada "ponto de sequência" - por questões de segurança do encadeamento e certas operações de baixo nível no hardware mapeado pela memória - e aquelas que não t, que podem ser movidos para um registro ou otimizados completamente.
Davislor 30/08
@ Davidislor: O padrão C usa o termo "objeto" em locais onde outras especificações de linguagem usam "variável", além de descrever outras coisas que não são variáveis. Algumas discussões podem usar o termo independente de idioma "variável", mas por qualquer motivo o Padrão carece de um termo para distinguir entre alocações disjuntas (variáveis) nomeadas de outros tipos de objetos, como alocações aninhadas (membros de struct / union) ou objetos não nomeados gerados desreferenciando ponteiros. Informalmente, "variável" é um ótimo termo, mas o Padrão não o utiliza.
supercat
@ supercat Isso não está correto. As utilizações comuns C11 o termo “variável” mais de uma centena de vezes, das quais dúzia vários são substantivos, por exemplo, “Acesso concorrente para a variável que está sendo inicializado, mesmo através de uma operação atômica, constitui uma corrida de dados.”
Davislor
1

A instrução Um ponteiro é uma variável cujo valor é o endereço de memória de outra variável é simplificada demais. Porém, quando o leitor entender exatamente o que é um local de memória e como ele difere de uma variável, ele já entenderá o que é exatamente um ponteiro e, portanto, não precisará mais confiar nessa explicação imprecisa.

A instrução Um ponteiro é um local de memória cujo valor é o endereço de memória de outro local de memória está incorreto. O valor de um ponteiro não precisa ser armazenado em um local de memória e é discutível se um ponteiro precisar apontar para um local de memória, dependendo da definição pretendida de "memória".

Qual é a diferença entre uma variável e um local de memória

Um local de memória é um dos vários locais possíveis onde os dados podem ser armazenados. Esses dados podem ser uma variável ou parte de uma variável. Variáveis ​​são uma maneira de rotular dados.

Pedro
fonte
0

Esta resposta se concentra em C e C ++; isso parece apropriado, pois sua pergunta se refere a ponteiros que são parte mais integrante do C / C ++ do que de outros idiomas. A maior parte deste post será aplicada à maioria das linguagens compiladas sem um tempo de execução elaborado (como Pascal ou Ada, mas não como Java ou C #).

As boas respostas já dadas enfatizam que uma variável é uma construção da linguagem em um nível mais abstrato do que a memória física. Eu gostaria de enfatizar, no entanto, que essa abstração tem uma certa lógica e sistema:

A abstração consiste principalmente em usar um nome em vez de um endereço literal.

A idéia principal é que uma variável seja um identificador nomeado para um objeto digitado; objetos em C / C ++ geralmente estão na memória. Os idiomas adicionam alguns detalhes sobre gerenciamento de vida útil e empacotamento de dados para conversões de tipo. O conceito de variáveis ​​é mais abstrato do que endereços físicos, porque na verdade não nos importamos com o valor numérico dos endereços ou com a localização exata das funções na memória. Nós simplesmente os nomeamos e depois os nomeamos, e o compilador, o vinculador e o sistema de tempo de execução cuidam dos detalhes.

E não finja que C / C ++ seja independente de memória: afinal, existe o operador de endereço universalmente aplicável. Sim, é verdade, você não pode usar o endereço de uma variável C na classe de armazenamento de registro; mas quando você usou um pela última vez? É uma exceção especial ao conceito geral, não uma rejeição total do argumento. A regra geral é, ao contrário, que pegar um endereço de uma variável realmente força o compilador a criar um objeto na memória, mesmo que não o faça de outra forma (por exemplo, com constantes). O conceito "identificador com nome" também é um bom paradigma para referências em C ++: Uma referência é apenas outro nome para o mesmo objeto.

Quando escrevi o assembler em linha para 68k, foi bom ver como você poderia usar nomes de variáveis ​​como compensações para endereçar registros (e você poderia usar os nomes de variáveis ​​declaradas em registervez dos nomes de registro bare metal!). Para o compilador, uma variável é um deslocamento de endereço constante. Para reiterar: As variáveis ​​são identificadas como identificadores, geralmente para objetos na memória.

Peter - Restabelecer Monica
fonte
Os ponteiros também são uma parte muito básica de C #, Java, JS e outras linguagens. Chamá-los de maneira diferente não muda isso, embora seja um bom PR.
Deduplicator 30/08
@Deduplicator :-) Good ol 'Tony ...
Peter - Reinstate Monica
0

Parece que a pergunta é voltada para uma linguagem popular formada pelo aprimoramento do Padrão C com a garantia adicional "Nos casos em que algumas partes do Padrão ou da documentação de uma implementação descrevem o comportamento de alguma ação, e outra parte o categoriza como indefinido , a parte anterior domina. ", bem como uma definição de" variável "consistente com o uso do termo por outras línguas.

Nesse idioma, cada local de memória pode ser visualizado como uma caixa de correio numerada que sempre mantém um número (normalmente oito) de bits, cada um dos quais pode ser independentemente zero ou um. Os locais da memória geralmente são organizados em linhas de dois, quatro ou oito. e algumas operações são processadas em vários locais consecutivos de memória ao mesmo tempo. Dependendo da máquina, algumas operações que operam em grupos de dois, quatro ou oito locais de memória podem ser limitadas a operar em locais dentro de uma única linha. Além disso, enquanto algumas máquinas podem ter uma única sala de caixas de correio numeradas consecutivamente, outras podem ter vários grupos separados de caixas de correio numeradas.

Uma variável identifica um intervalo de locais de memória associados exclusivamente a ele e um tipo como o qual esses locais de memória devem ser interpretados. A leitura de uma variável fará com que os bits em seus locais de armazenamento associados sejam interpretados de maneira apropriada ao tipo da variável, e a gravação de uma variável fará com que os bits associados sejam configurados de maneira apropriada ao seu tipo e valor.

Um endereço encapsula todas as informações necessárias para identificar uma caixa de correio. Isso pode ser armazenado como um número simples ou como algum tipo de designador de grupo, juntamente com o número de uma caixa de correio dentro desse grupo.

A aplicação do &operador a uma variável produzirá um ponteiro que encapsula o endereço e o tipo do mesmo. A aplicação do unário *ou do []operador a um ponteiro fará com que os bits das caixas de correio iniciando no endereço encapsulado sejam interpretados ou configurados de maneira apropriada ao tipo encapsulado.

supercat
fonte
Parece que você está pensando demais na pergunta.
Robert Harvey
0

Estou chegando atrasado para esta festa, mas não resisto a colocar meus 2 centavos.

Nesses momentos, qual é a diferença entre os valores armazenados nesses locais de memória?

Tempo 1

insira a descrição da imagem aqui

Tempo 2

insira a descrição da imagem aqui

Resposta correta: nada. Todos são valores idênticos sendo apresentados com diferentes interpretações de seu significado.

Como eu sei disso? Porque sou eu quem inventou isso. Você ainda não sabe disso.

Você está encontrando algo que eu chamo de problema fora da banda . Como interpretar corretamente o significado desses valores não é armazenado aqui. Esse conhecimento é armazenado em outro lugar. No entanto, quando você apresenta esses valores no papel, coloca essa interpretação. Isso significa que você adicionou informações que simplesmente não existem nesses locais de memória.

Por exemplo, os valores aqui são idênticos, mas você só sabe que isso é verdade se você estiver correto ao assumir uma codificação de caracteres ASCII / UTF-8. Foi assim que obtive o primeiro, em vez de EBCDIC . E você também deve assumir que o segundo é expressões hexadecimais dos valores numéricos armazenados nesses locais de memória, que podem ser ponteiros para outros endereços, em vez de dizer referências a seqüências de caracteres que começam com "0x". : P

Nada armazenado nesses locais de memória informa que qualquer uma dessas suposições está correta. Essa informação pode ser armazenada. Mas seria armazenado em outro lugar.

Este é o problema de apresentação . Você não pode expressar nenhum número sem antes concordar em como apresentá-lo. Você pode se basear em suposições, convenções e contexto, mas se você a analisar profundamente, quando a apresentação não for definida explicitamente, a única resposta verdadeiramente correta será "informações insuficientes".

candied_orange
fonte
É ainda mais divertido quando a mesma memória é usada para diferentes coisas constantes ao mesmo tempo.
Deduplicator
@Deduplicator True. Isso sempre me faz pensar na reinterpretação do c ++ . Os mesmos bits vistos de uma maneira diferente.
candied_orange
@Deduplicator ou, pense bem, união em c
candied_orange 02/09