Как работает переменная в C/С++?

Как работает переменная в C/С++?

Я имею в виду, что указатель хранит адрес из переменной, а затем вы должны разыменовать его для доступа к объекту, к которому он относится, поэтому я считаю, что переменная является указателем, который автоматически разыменовывается при использовании... делает это в каком смысле?

Ответы

Ответ 1

Переменная - это абстракция (удобное имя) для позиции памяти на компьютере. В C/С++, если переменная имеет тип int, это будет удобное имя для адреса памяти, содержащего целочисленное значение.

И переменная не является, а указатель автоматически разыменован. Переменная просто удерживает значение, которое предполагается удерживать. Если это указатель, он будет хранить адрес памяти, если он является целым числом, он будет содержать целочисленное значение, если он является float, он будет содержать число с плавающей запятой... И так далее и так далее...

Ответ 2

Рассмотрим следующие определения

char *string="abc";
int b = 10;
int *bptr = &b;

Я немного упрощаю это и использую десятичные значения, переменные (имена) являются заполнителями для адресов, при этом они сохраняют конкретные значения.

Adr  content
1000 a b c 0    // "abc" : string literal '\0' terminated 
1004    1000    // *string: pointer to string (address 1000)
1008      10    // b = 10 : integer value
1012    1008    // *bptr  : pointer to &b 

Используя, например, printf ( "% s\n", строка); вы не хотите копировать всю строку, вместо этого вы указываете адрес, где начинается строка (вызов по ссылке).

Ответ 3

Чтобы прочитать/записать переменную, нужно прочитать/записать кусок байтов в известном местоположении. "знать местоположение" - это местоположение, известное компилятору, оно может быть:

  • Фиксированный адрес. Компилятор знает весь адрес глобальных переменных. Если мы читаем/записываем глобальную переменную, компилятор ставит такую ​​инструкцию: "читать/записывать память по адресу 0x00235A87"
  • Исправлено смещение стека. Локальные переменные помещаются в стек. Указатель на вершину стека ( "указатель стека" или "SP" ) сохраняется в регистрах процессора. Компилятор знает, что такое смещение локальной переменной сверху стека. Если мы читаем/записываем локальную переменную, компилятор ставит такую ​​инструкцию: "читать/записывать память по адресу" SP-0x05 "".
  • Регистры процессора. Переменные, когда они используются, загружаются в регистры процессора. Компилятор знает, какие регистры. Чтобы использовать их, чтение/запись памяти не требуется, компилятор просто вводит инструкции, которые используют регистры типа: "Добавить содержимое регистра B для регистрации A".

Доступ к переменной на самом деле является алгоритмом, написанным в виде инструкций процессора. Переменные могут быть адресами по фиксированному адресу памяти, по вычисленному адресу памяти (с использованием фиксированного смещения и значения, хранящегося в регистре) или регистру процессора. Компилятор ставит инструкцию, которая перемещает значения переменных между памятью/регистром и между регистром/регистром. Переменная может даже не существовать в памяти, она может быть все время храниться в регистрах.

Есть какая-то аналогия в том, что вы говорите.

Учитывая выше, помните, что указатель является переменной, которая хранит адрес (который является целым числом). Если мы разыграем указатель и прочитаем значение, то нужно сделать два шага. Во-первых, мы должны читать переменную указателя, как и любую другую переменную. После этого адрес находится в регистре. Затем мы читаем заостренную переменную с инструкцией типа "чтение памяти по адресу, хранящемуся в регистре A".

Ответ 4

Переменная - это просто абстракция. Это идея именованного значения, которое вы можете ссылаться, читать и (иногда, в зависимости от его типа) изменять.

Где он хранится в аппаратном обеспечении, это просто деталь реализации. Часто они реализуются путем хранения данных по определенному адресу памяти, а затем с использованием этого адреса всякий раз, когда требуется доступ к переменной, поэтому в этом смысле он часто является "автоматически разыменованным указателем", как вы говорите.

Но иногда переменная хранится в регистре, а не в памяти. Тогда у него нет адреса, и вы не можете создать указатели на него.

Иногда он может даже не существовать в скомпилированном коде. Иногда компилятор может преобразовать код, поэтому переменная больше не нужна или переменная может быть преобразована в одну константу времени компиляции.

В конечном счете переменные существуют только в исходном коде. Как только ваш код выполняется, переменные больше не существуют. Некоторые переменные преобразуются в ячейки памяти, а некоторые полностью удаляются или преобразуются во что-то, что вы даже не распознаете как переменную.

Например, этот код:

int x = 10;
y += 10;

может быть скомпилирован путем представления x и y в качестве местоположений памяти, а затем добавление выполняется с помощью команды, такой как "добавить значение из адреса памяти x в значение по адресу памяти y".

Но компилятор также может кодировать константу 10 в самой инструкции, генерируя инструкцию "добавить 10 к значению в памяти адреса y". Конечно, x была переменной в исходном исходном коде, но она больше не является местом памяти. Он закодирован непосредственно в потоке команд.

Ответ 6

Локальная переменная может находиться в памяти или в регистре или может перемещаться между двумя на разных этапах выполнения программы или может совместно использовать пространство с другой переменной. Компилятор может свободно выделять наиболее эффективное пространство для вашей переменной.

Если вы берете указатель на переменную, то компилятор должен поместить эту переменную в память, чтобы иметь уникальный адрес. Но если вы никогда не указали на него, то ваша переменная может остаться в своем собственном регистре CPU. Или, если у вас есть две локальные переменные, и если вы никогда не используете их обоих одновременно, то компилятор может занять их в одной и той же части памяти или регистре CPU.

http://en.wikipedia.org/wiki/Register_allocation

Ответ 7

Переменная - это имя, которое относится к местоположению. Местоположение разрешено во время компиляции - компилятор определяет местоположение во время компиляции и заменяет все переменные на соответствующие местоположения. В принципе, каждый раз, когда компилятор находит определение переменной, он помещает имя в так называемую таблицу символов. Он имеет по крайней мере два столбца: имя (первичный ключ, если хотите), и местоположение. Проще говоря, когда компилятор обработал все переменные и выяснил их местоположения, компилятор заменит все ссылки на переменные своими соответствующими местоположениями. (Там более того, что это, но что книга стоит материала...)

Указатели также являются переменными. Что делает полезный указатель, так это то, что содержимое, хранящееся в местоположении переменной (указатель), может использоваться для чтения или записи значений в другом месте. Это то, что называется разыменованием указателя. Это делается во время выполнения. В этом отношении вы не можете сказать, что переменные, которые автоматически разыменовываются, потому что работа была отложена из времени компиляции для выполнения времени.

Ответ 8

Не дружище указатель представляет собой набор переменных, и для их дифференциации, помимо числа переменных, значения (целое число, символ) должны быть разными!

Ответ 9

Переменная просто содержит значение, которое предполагается удерживать. Если это указатель, он будет хранить адрес памяти, если он является целым числом, он будет содержать целочисленное значение, если он является float, он будет содержать число с плавающей запятой...

Ответ 10

Переменная фактически не выполняет никакой работы. Вместо этого программа может работать с переменными.