Как работает переменная в C / C ++? - PullRequest
16 голосов
/ 13 августа 2010

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

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

Ответы [ 10 ]

29 голосов
/ 13 августа 2010

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

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

12 голосов
/ 13 августа 2010

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

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", строка);Вы не хотите копировать всю строку, скорее, вы даете адрес, с которого начинается строка (вызов по ссылке).

8 голосов
/ 13 августа 2010

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

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

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

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

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

6 голосов
/ 13 августа 2010

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

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

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

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

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

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

int x = 10;
y += 10;

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

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

4 голосов
/ 13 августа 2010

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

Как работает автоматическая памятьраспределение на самом деле работает в C ++?

2 голосов
/ 13 августа 2010

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

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

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

1 голос
/ 20 августа 2011

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

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

0 голосов
/ 13 августа 2010

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

0 голосов
/ 13 августа 2010

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

0 голосов
/ 13 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...