C/C++

Где хранится метка массива.

Если метка массива является указателем на начало массива, а указатель это переменная которая хранит адрес, а у переменной есть своё место в памяти. То почему когда я беру адрес метки массива, то он указывает на нулевой элемент, ведь в данной ячейке одновременно не может храниться и адрес и сам элемент?
Имя массива является указателем на его первый элемент. Вы своё внимание сосредоточили на значении, а нужно обратить внимание на адрес. Указатель, это переменная, которая хранит адрес объекта в памяти. Например, для массива типа short, элементы которого занимают в памяти 2 байта, указатель будет занимать четыре байта на платформе x86 или восемь – на платформе x64.

#include <iostream>
#include <iomanip>
using namespace std;
int main() {
short box[] = { 1, 2, 3 };
cout << "Address box: " << setw(12) << box << '\n';
cout << "Address box[0]: " << setw(9) << &box[0] << '\n';
cout << "sizeof(&box[0]): " << sizeof(&box[0]) << '\n';
cout << "sizeof(box[0]): " << setw(2) << sizeof(box[0]) << '\n';
system("pause > nul");
}

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

++box; // не получиться. Как память-то освобождать?

Но если сделать так:

short* beg = box;
++beg; // то получится, т. к. присвоен будет адрес первого элемента массива, а не указателя массива.

Разница в том, что box хранит адрес на массив, а beg хранит адрес на элемент массива и, собственно, ничего об этом массиве уже не знает.

Каждая ячейка памяти имеет свой адрес, который отличается на единицу от соседних с ней ячеек и каждая такая ячейка занимает один байт в памяти. Сам адрес вычисляется системой в момент обращения к данной ячейке по определённой формуле. А в консоль выводится в виде удобно читаемой информации, представленной шестнадцатеричным значением.

Если вы создаёте динамический массив, то разницы в том нет никакой. Указатель, который будет хранить адрес на первый элемент массива в куче, сам будет храниться в стеке и к нему так же вы не сможете получить доступ. Но указатели и статического и динамического массивов, как переменные, хранятся в стеке отдельно от массивов на которые они указывают. В доказательство приведу объявленный но неинициализированный указатель. Он уже есть, но полезной информацией пока не наделён. Кроме того для C/C++ справедливо утверждение, что любая переменная ни что иное как разыменованный типизированный указатель.
АК
Айдос Курмангалиев
79 822
Лучший ответ
Она хранится в компиляторе - в процессе обработки текста программы.

Указатель - это не "переменная, которая хранит адрес", а само значение адреса.

Упрощая:

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

Потому, отдельная переменная для адреса массива в скомпилированном коде не требуется - адрес начала массива вписан компилятором непосредственно в нужные места кода.
В самом языке, а язык тоже программа, значит занимает память у Си шарпа)
Капитан Взц-9
Капитан Взц-9
62 333
Тимур Алхаматов Получается это не переменная а лишь приведение к типу указателя? Само название массива вырождается в ассемблерную метку за которой следует выделение памяти под элементы?
Тимур Алхаматов Ну да, и тут я вспомнил ассемблер и всё встало на свои места...)))
Не знаю, как ты это проверяешь, но вот пример, что адрес указателя отличается от значения указателя

int z = 1;
int *a = &z;
printf("z is %d; %lx != %lx", *a, (long)a, (long)&a);

или:
int a[] = {5, 1, 2};
printf("a[0] is %d; %lx != %lx", *a, (long)a, (long)&a);
Sodiqjon Xolto'rayev
Sodiqjon Xolto'rayev
12 356