В чем разница между переменной и местом в памяти? [закрыто]

38

Недавно я пытался объяснить указатели наглядно, как карточки.

Вопрос 001: это рисунок места в памяти компьютера. Это правда, что его адрес 0x23452? Зачем?

введите описание изображения здесь

Ответ: Да, потому что 0x23452описывает, где компьютер может найти это место.


Вопрос 002: правда ли, что персонаж bхранится в ячейке памяти 0x23452? Зачем?

введите описание изображения здесь

Ответ: Нет, потому что персонаж aна самом деле хранится внутри него.


Вопрос 003: правда ли, что указатель хранится в ячейке памяти 0x23452? Зачем?

введите описание изображения здесь

Ответ: Да, потому что в 0x34501ней хранится адрес ячейки памяти .


Вопрос 004: правда ли, что указатель хранится в ячейке памяти 0x23452? Зачем?

введите описание изображения здесь

Ответ: Да, потому что внутри него хранится адрес другой ячейки памяти.


Теперь о той части, которая меня беспокоит. Инженер-программист объяснил мне указатели так:

Указатель - это переменная, значением которой является адрес памяти другой переменной.

Основываясь на четырех карточках, которые я вам всем показал, я бы определил указатели немного по-другому:

Указатель - это ячейка памяти, значением которой является адрес памяти другой ячейки памяти.

Можно ли с уверенностью сказать, что переменная - это то же самое, что и ячейка памяти?

Если нет, то кто прав? В чем разница между переменной и местом в памяти?

progner
источник
37
Там это неявное предположение о том, что здесь каждый читающий эти фотографии будут знать ваши намерения , что число шестнадцатеричное под полем является адрес памяти, и что a, 0x23453. nilи т.д. вещи внутри них являются ценностями. Это может показаться вам очевидным, но мне было бы неудобно давать решительные ответы на эти вопросы, не видя, как эти поля определены. На самом деле нет никакого способа узнать, является ли aна втором изображении символ, строка (если они различаются) или имя переменной. Если это строка, то nilтоже строка? Или "нулевое" значение?
Ильккачу
39
Вопрос 1 - это плохой вопрос. Это то, что вы должны сказать читателям, прежде чем они смогут ответить на другие вопросы. Вместо вопроса, это должна быть информация, предоставленная читателю: «В следующих вопросах ящики - это ячейки памяти, а шестнадцатеричные числа под ними - их адреса».
17 из 26
15
На вопрос 3 невозможно ответить, учитывая контекст. На уровне байтов невозможно определить, как значение, хранящееся в памяти, интерпретируется / используется на уровне приложения.
17 из 26
6
Стоит отметить: все, что вы здесь пишете, верно для C или C ++, но false для практически любого языка, который не имеет явной ссылки / разыменования указателя. Вся метафора переменных, представляющих собой слоты, значения которых разбиваются на части для языка (например, Python, или Java, или C #, или Ruby, или JavaScript, или многих других), где присваивание просто делает переменную указывающей на объект, не копируя его и мутации объекта видны через все переменные, указывающие на него. Документация Python использует альтернативную метафору переменных в качестве тегов имен, висящих на объектах по этой причине.
Марк Амери
19
Кстати, и простите, если вы уже это понимаете, но, похоже, это может привести к путанице - эта нотация "0x23452" - это просто способ обозначить число в шестнадцатеричном формате, и это сделано просто для удобства. Но это просто число - ни в коем случае префикс 0x не означает, что это указатель, а то, что хранится в памяти, является буквально просто бессмысленным числом (вы можете пометить места в памяти с помощью простых десятичных целых чисел). Значение (то есть, как следует интерпретировать число) происходит от языка - тип переменной и способ ее использования.
Филипп Милованович

Ответы:

69

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

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

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

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

В некотором смысле переменная является механизмом абстракции для выражения намерения программы, тогда как ячейка памяти является физическим объектом среды обработки, которая обеспечивает хранение и поиск.

Вопрос 003: правда ли, что указатель хранится в ячейке памяти 0x23452? Зачем?

Мы не можем сказать наверняка. То, что там есть значение, которое будет работать как адрес, не означает, что это тот адрес, это может быть целое (десятичное) 144466. Мы не можем делать предположения о толковании ценностей просто исходя из того, как они выглядят численно.

Вопрос 004: правда ли, что указатель хранится в ячейке памяти 0x23452? Зачем?

Это действительно странный вопрос. Они ожидают некоторых предположений на основе блоков, однако отметим, что адреса увеличиваются на 1 для каждого блока. В любом современном компьютере это означало бы, что каждая ячейка может содержать байтово-байтовую адресацию, которая уже десятилетия является нормой. Однако байт только 8 бит и может варьироваться от 0 до 255 (для значений без знака); все же они показывают намного большее значение, сохраненное в одном из этих адресов, что очень подозрительно. (Это могло бы работать, если бы это была машина с адресом слова, но это не говорит об этом, и сегодня мало машин, хотя некоторые образовательные машины так и есть.)

Основываясь на четырех карточках, которые я вам всем показал, я бы определил указатели немного по-другому:

Указатель - это ячейка памяти, значением которой является адрес памяти другой ячейки памяти.

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

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

Эрик Эйдт
источник
4
И даже 8-битные байты все еще не универсальны.
дедупликатор
14
@JimmyJames Рассмотрим случай forиндекса цикла, когда компилятор решает полностью развернуть цикл. Нигде в полученном выходном коде (будь то сборка, машинный код или байт-код) нет места в памяти, в котором хранится счетчик цикла. Но это все еще переменная.
dmckee
4
@JimmyJames, в случае указателя развернутого цикла, тогда да, если ваш код действительно использует значение счетчика, то он должен быть где-то загружен , но (а) это место может быть регистром, и (б) нет никакой принципиальной причины, почему это должно было бы быть то же самое местоположение на каждой итерации развернутого цикла.
Соломон Слоу
3
Если цикл выполняет что-то вроде копирования массива фиксированной длины в массив sourceравной длины, destто цикл, закодированный как, for (int i=0; i<8; ++i) dest[i] = source[i];вполне может скомпилироваться во что-то, эквивалентное повторению dest++ = source++;подходящего числа раз. С самим счетчиком цикла нигде нет свидетельств (даже в регистре), и только количество повторений говорит вам о состоянии цикла.
dmckee
2
Это различие несколько смущает языки типа C, семантика которых тесно связана с абстракцией машины, чья память состоит из пронумерованных мест.
Майкл Кей
20

Можно ли с уверенностью сказать, что переменная - это то же самое, что и ячейка памяти?

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

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

Указатель - это ячейка памяти, значением которой является адрес памяти другой ячейки памяти.

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

Ли Райан
источник
1
Once a code had been compiled into an executable, there's no longer any variables.Это то, с чем я, возможно, не согласен. Правильно, что ваша переменная в том виде, в каком вы ее знаете (то есть под этим именем), больше не существует, но, похоже, ваша фраза предполагает, что скомпилированный исполняемый файл использует только адреса памяти. Это не правильно. Ваш скомпилированный, но не исполняемый исполняемый файл не знает, какие адреса памяти он будет использовать при выполнении. Концепция переменной (т. Е. Повторно используемой ссылки на любой адрес памяти, который будет назначен во время выполнения) все еще существует внутри скомпилированного исполняемого файла.
Флэтер
2
Или компилятор может полностью оптимизировать переменную различными способами. Предварительно вычисляя что-то, удаляя ненужные переменные. Если переменная является константой, то компилятор может в конечном итоге использовать инструкции процессора, которые используют константы, и я бы сказал, что больше не считается переменной где-либо.
Кучкем
16

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

Места памяти - это аппаратная концепция . Они обозначают место в виртуальной / физической памяти. Каждая ячейка памяти имеет ровно один физический адрес и любое количество виртуальных адресов, которые могут использоваться для манипулирования им. Но в каждой ячейке памяти всегда хранится ровно один байт.

Указатели - это особый вид ценностей . Сказать что-то - указатель - все равно что сказать что-то типа double. Он указывает, сколько битов используется для значения и как эти биты интерпретируются, но это не означает, что это значение хранится в переменной, и не означает, что это значение хранится в памяти.


Чтобы привести пример в C: Когда у меня есть 2D-массив, int foo[6][7];и я обращаюсь к его элементу с помощью foo[1][2], тогда fooэто переменная, которая содержит массив. Когда fooиспользуется в этом контексте, он превращается в указатель на первый элемент массива. Этот указатель не хранится ни в одной переменной и не сохраняется в памяти, его значение генерируется только в регистре ЦП, используется и затем забывается. Аналогично, выражение foo[1]превращается в другой указатель в этом контексте, который, опять же, не находится в переменной, не сохраняется в памяти, но вычисляется в ЦП, используется и забывается. Три понятия: переменная , место в памяти и указатель - это на самом деле три разных понятия.


Кстати, я действительно имел в виду «в каждой ячейке памяти всегда хранится ровно один байт». Это было не так в каменном веке вычислений около пятидесяти лет назад, но это верно практически для всего оборудования, которое используется сегодня. Всякий раз, когда вы сохраняете значение в памяти, которое превышает один байт, вы фактически используете несколько последовательных ячеек памяти. Т.е. (при условии порядка байтов с прямым порядком байтов) число 0x01234567 сохраняется в памяти как

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

(Машины с прямым порядком байтов, такие как архитектура X86, хранят байты в обратном порядке.) Это также верно для указателей: указатель на 64-битной машине хранится в восьми последовательных байтах, каждый со своим собственным адресом памяти. Вы не можете посмотреть на ячейку памяти и сказать: «О, это указатель!» Вы всегда видите только байты, когда смотрите на память .

cmaster
источник
Как компьютер узнает, когда группа последовательных областей памяти начинается и заканчивается?
прогр
6
@progner Это не так. Он интерпретирует байты в памяти в соответствии с полученными инструкциями. Эти инструкции также хранятся только в последовательности байтов. Для CPU единственная разница между байтом, который содержит инструкцию, байтом, который содержит символ, и байтом, который содержит некоторые биты с плавающей запятой, состоит в том , как ему было предписано использовать этот байт. Если байт выбирается из-за того, что на него указывает счетчик программы, он используется как инструкция. Если он выбран, потому что инструкция говорит загрузить его в регистр с плавающей запятой, он используется как данные с плавающей запятой.
Учитель
7
@progner Это было на самом деле ключевым нововведением архитектуры фон Неймана: хранить инструкции и данные в одной и той же памяти, позволяя инструкциям изменять данные, которые впоследствии выполняются как дополнительные инструкции. Это позволило самостоятельно модифицировать код, но также позволяет ядру системы загрузить некоторую программу в память, а затем дать указание ЦПУ выполнить эту программу. До появления фон Неймана такие компьютеры, как машины Zuse, получали инструкции по каналу, который был полностью независим от данных, с которыми они работали.
Учитель
5

Позвольте мне сосредоточиться на вашем актуальном вопросе - "кто прав?" при сравнении этих двух утверждений:

  • Указатель - это переменная, значением которой является адрес в памяти другой переменной
  • Указатель - это ячейка памяти, значением которой является адрес памяти другой ячейки памяти.

Ответ на это нет . Первый говорит о «адресе памяти другой переменной», но переменные не обязательно имеют адреса памяти, как уже объяснили другие ответы. Второй говорит, что «указатель - это область памяти», но указатель - это буквально просто число, которое может храниться в переменной, но, как и раньше, переменная не обязательно имеет адрес в памяти.

Несколько примеров для более точных утверждений:

  • «Указатель - это число, представляющее адрес памяти ячейки памяти», или

  • «Переменная-указатель - это переменная, значением которой является адрес памяти ячейки памяти».

  • «Адрес памяти может содержать указатель, представляющий адрес памяти ячейки памяти».

Обратите внимание, что иногда термин «указатель» используется в качестве ярлыка для «переменной указателя», что нормально, если это не приводит к путанице.

Док Браун
источник
Вы можете изменить «другой» на «а», потому что указатель может указывать на себя.
Питер Б
@PieterB: гадость, гадость ;-) не уверен, действительно ли это проясняет ситуацию, так как я хотел только изменить оригинальную формулировку в той степени, которая действительно необходима, чтобы сделать ее разумной. Но, увы, я сделал правку.
Док Браун
Чтобы быть справедливым, если вы получаете то, что придирчиво «но указатель буквально просто число» тоже не правильно, на самом деле указатель является идентификатором, ссылающимся на число;) Или, по крайней мере, мы должны были знать особенности языка, чтобы попасть в эти Детали.
Зайбис
2
Указатель - это значение (число уже слишком специфично для некоторых реализаций), потенциально ссылающееся на некоторый объект. Потенциально, поскольку есть также нулевые указатели, дикие указатели и висячие указатели, хотя некоторые (или даже все!) Из них могут быть исключены используемым языком.
дедупликатор
2
@Deduplicator: вы правы, но я думаю, что ментальная модель указателя как числа достаточно хороша для целей этого вопроса. Так что давайте будем проще.
Док Браун
5

Я, конечно, не сказал бы, что указатель - это область памяти, которая содержит адрес. С одной стороны, я не знаю архитектуры, где 0x23453можно было бы разместить один байт. :) Даже если вы удалите различие в байтах / словах, у вас все равно будет проблема, что каждая ячейка памяти содержит адрес. Адреса - это просто цифры, а содержимое памяти - просто цифры.

Я думаю, что хитрость здесь в том, что «указатель» описывает намерение человека , а не какую-то особенность архитектуры. Это похоже на то, как «символ» или «строка» - это не конкретная вещь, которую вы можете видеть в памяти - все это тоже просто числа, но они функционируют как строки, потому что именно так к ним относятся. «Указатель» просто означает значение, предназначенное для использования в качестве адреса.

Честно говоря, если ваша цель состоит в том, чтобы преподавать определенный язык (Цель C?), Я не уверен, что вытягивание классической магнитной ленты даже настолько полезно. Вы уже говорите ложную ложь, показывая напечатанные значения и значения, слишком большие для байта. Обучайте семантике, а не механике - ключевое понимание указателей заключается в том, что они обеспечивают косвенное обращение , что является чрезвычайно полезным инструментом для понимания.

Я думаю, что хорошее сравнение может быть с URL, который говорит вам, где найти некоторые данные, но не сами данные. Выслушай меня:

  • Вы редко волнует , что URL на самом деле является ; Подавляющее большинство из них скрыто в связях с именами. Многие люди используют Интернет, не зная точно, как URL приводит к странице; некоторые люди полностью забывают об URL.

  • Не каждая строка является URL-адресом или предназначена для использования в качестве URL-адреса.

  • Если вы попытаетесь посетить поддельный URL или страницу, которая раньше существовала, но с тех пор была удалена, вы получите сообщение об ошибке.

  • URL-адрес может указывать на изображение, текст, музыку или любое количество других отдельных элементов - или на страницу, содержащую различные элементы. Очень часто бывает целая куча страниц с одинаковыми макетами, но разными данными.

  • Если вы создаете веб-страницу и хотите ссылаться на данные на какой-либо другой веб-странице, вам не нужно копировать и вставлять все это; Вы можете просто сделать ссылку на него.

  • Любое количество других страниц может ссылаться на тот же URL.

  • Если у вас есть коллекция похожих страниц, вы можете создать индексную страницу со списком ссылок на все из них, или у вас может быть просто «следующая» ссылка внизу страницы 1, которая приведет вас на страницу 2, и так далее. Преимущества и недостатки обоих подходов сразу очевидны, особенно если учесть, что нужно сделать веб-мастеру для добавления или удаления страниц в разных местах.

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

Eevee
источник
every memory location contains an address- Каждая ячейка памяти имеет адрес. Он не содержится нигде, кроме, возможно, в переменной указателя.
Роберт Харви
@RobertHarvey каждая ячейка памяти (по крайней мере, слово) содержит число, которое можно тривиально интерпретировать как адрес. дело было в том, что на самом деле ничто в оборудовании не отличает адреса от
неадресных
2

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

В Си унарный оператор амперсанда называется оператором адресации. Программисты C без колебаний скажут, что выражение &xвычисляется по адресу переменной x. Конечно, они означают «адрес памяти, в котором хранится значение переменной x», но никто не настолько педантичен в случайном разговоре. В языке C слово «указатель» обычно относится к типу данных переменной, для которой в качестве значения используется адрес памяти. Или, что то же самое, тип данных значения. Но некоторые люди использовали бы «указатель» как само значение.

В Java все переменные типа объекта или массива ведут себя подобно указателям на C (за исключением арифметики указателей), но Java-программисты называют их ссылками, а не указателями.

C ++ считает ссылки и указатели разными понятиями. Они связаны, но не совсем одно и то же, поэтому программисты на C ++ должны делать различие в разговоре. Амперсанд читается как «адрес» в некоторых контекстах и ​​«ссылка» в других.

Указатель - это переменная, значением которой является адрес памяти другой переменной.

Вот как программист C может описать это, используя «указатель» в том же смысле, что и «int». (Например, «указатель содержит адрес памяти, а int содержит целое число в определенном диапазоне.»)

Указатель - это ячейка памяти, значением которой является адрес памяти другой ячейки памяти.

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

Можно ли с уверенностью сказать, что переменная - это то же самое, что и ячейка памяти?

Было бы яснее сказать, что адрес памяти - это место в памяти, где хранится значение переменной. (Конечно, не все переменные хранятся в памяти из-за оптимизации компилятора, но любая переменная, адрес которой взят с, &xбудет.)

Гаткин
источник
Как мы педантичны: адрес, по которому что-то хранится. Помимо адреса, не имеющего возможности хранить что-либо, часто вещи хранятся в нескольких смежных местоположениях, только одно из которых (обычно выбираемое по несколько непротиворечивому правилу) адресовано (и использует только один из потенциально многих адресов).
дедупликатор
@Deduplicator Я, например, не пытаюсь быть педантичным.
Гаткин
Стандарт C даже формально различает переменные, которые должны строго следовать шагам абстрактной машины в каждой «точке последовательности» - ради безопасности потоков и определенных низкоуровневых операций на оборудовании с отображенной памятью - и те, которые не т, которые могут быть свободно перемещены в регистр или полностью оптимизированы.
Дэвислор
@Davislor: Стандарт C использует термин «объект» в местах, где в других языковых спецификациях используется «переменная», а также для описания других вещей, которые не являются переменными. В некоторых обсуждениях может использоваться не зависящий от языка термин «переменная», но по какой-либо причине в стандарте отсутствует термин для различия между именованными непересекающимися выделениями (переменными) и другими видами объектов, такими как вложенные выделения (члены структуры / объединения) или неназванными полученными объектами. разыменовывая указатели. Неформально «переменная» - отличный термин, но Стандарт не использует его.
суперкат
@supercat Это не правильно. Стандарт C11 использует термин «переменная» более ста раз, из которых несколько десятков являются существительными, например, «Параллельный доступ к инициализируемой переменной, даже через атомарную операцию, составляет гонку данных».
Дэвислор
1

Оператор Указатель - это переменная, значение которой является адресом памяти другой переменной , упрощенно. Но к тому моменту, когда читатель поймет, что такое область памяти и чем она отличается от переменной, он уже поймет, что такое указатель, и, следовательно, больше не будет нуждаться в этом неточном объяснении.

Оператор Указатель является ячейкой памяти, значение которой является адресом памяти другой ячейки памяти, неверно. Значение указателя не нужно хранить в ячейке памяти, и это спорно , если указатель должен ссылаться на ячейку памяти, в зависимости от предполагаемого определения «памяти».

В чем разница между переменной и местом в памяти

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

Питер
источник
0

Этот ответ фокусируется на C и C ++; это кажется уместным, поскольку ваш вопрос касается указателей, которые являются более неотъемлемой частью C / C ++, чем других языков. Большая часть этого поста будет применяться к большинству скомпилированных языков без сложного времени выполнения (например, Pascal или Ada, но не как Java или C #).

Хорошие ответы, которые уже даны, подчеркивают, что переменная - это языковая конструкция на более абстрактном уровне, чем физическая память. Я хотел бы подчеркнуть, что эта абстракция имеет определенное обоснование и систему:

Абстракция в основном состоит в использовании имени вместо буквального адреса.

Основная идея заключается в том, что переменная является именованным дескриптором для типизированного объекта; объекты в C / C ++ обычно находятся в памяти. Затем языки добавляют некоторые тонкости, касающиеся управления временем жизни и маршалингом данных для преобразования типов. Концепция переменных является более абстрактной, чем физические адреса, потому что нас не волнует числовое значение адресов или точное расположение функций в памяти. Мы просто называем их, а затем называем их по имени, а компилятор, компоновщик и система времени выполнения заботятся о мельчайших деталях.

И не делайте вид, что C / C ++ не зависят от памяти: в конце концов, существует универсально применимый адресный оператор. Да, правда, вы не можете взять адрес переменной C в классе хранения регистров; но когда вы последний раз использовали один? Это особое исключение из общей концепции, а не массовое отклонение аргумента. Наоборот, общее правило заключается в том, что получение адреса переменной фактически заставляет компилятор действительно создавать объект в памяти, даже если это не будет сделано иначе (например, с константами). Концепция «именованного дескриптора» также является хорошей парадигмой для ссылок C ++: ссылка - это просто другое имя для того же объекта.

Когда я писал встроенный ассемблер для 68k, было приятно видеть, как вы можете использовать имена переменных в качестве смещений для адресов регистров (и вы можете использовать имена переменных, объявленные registerвместо имен регистров с нуля!). Для компилятора переменная - это постоянное смещение адреса. Повторим: переменные называются дескрипторами, обычно для объектов в памяти.

Питер - Восстановить Монику
источник
Указатели также являются основной частью C #, Java, JS и других языков. Называя их по-другому, это не меняет, хотя это хороший пиар.
дедупликатор
@Deduplicator :-) Добрый старый Тони ...
Питер - восстанови Монику
0

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

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

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

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

Применение &оператора к переменной даст указатель, который инкапсулирует адрес и его тип. Применение унарного *или []оператора к указателю приведет к тому, что биты почтовых ящиков, начинающиеся с инкапсулированного адреса, будут интерпретированы или установлены способом, соответствующим инкапсулированному типу.

Supercat
источник
Звучит так, как будто вы обдумываете вопрос.
Роберт Харви
0

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

В эти времена, в чем разница между значениями, хранящимися в этих местах памяти?

Время 1

введите описание изображения здесь

Время 2

введите описание изображения здесь

Правильный ответ: ничего. Все они представляют собой одинаковые ценности, представленные в разных интерпретациях их значения.

Откуда я это знаю? Потому что я тот, кто придумал это. Вы действительно еще этого не знаете.

Вы сталкиваетесь с тем, что я называю проблемой вне группы . Как правильно интерпретировать значение этих значений здесь не хранится. Это знание хранится в другом месте. Тем не менее, когда вы представляете эти ценности на бумаге, вы помещаете эту интерпретацию. Это означает, что вы добавили информацию, которой просто нет в этих местах памяти.

Например, значения здесь идентичны, но вы знаете, что это правда, если вы правы, когда вы предполагаете, что кодировка символов ASCII / UTF-8 - это то, как я получил первое, а не произнесение EBCDIC . И вы также должны предположить, что второе - это шестнадцатеричные выражения числовых значений, хранящихся в этих ячейках памяти, которые могут быть указателями на другие адреса, а не ссылками на строки, которые начинаются с «0x». :П

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

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

candied_orange
источник
Еще веселее, когда одна и та же память используется для разных постоянных вещей одновременно.
дедупликатор
@Deduplicator True. Это всегда заставляет меня задуматься о переинтерпретации бросков C ++ . Те же биты видятся по-другому.
candied_orange
@Deduplicator или, если подумать, объединение в c
candied_orange