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++ справедливо утверждение, что любая переменная ни что иное как разыменованный типизированный указатель.
#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++ справедливо утверждение, что любая переменная ни что иное как разыменованный типизированный указатель.
Она хранится в компиляторе - в процессе обработки текста программы.
Указатель - это не "переменная, которая хранит адрес", а само значение адреса.
Упрощая:
Когда компилятор видит оператор создания массива, он внутри себя сопоставляет имя массива и адрес его начала и дальше вставляет адрес везде, где используется имя массива - непосредственно в машинный код.
Потому, отдельная переменная для адреса массива в скомпилированном коде не требуется - адрес начала массива вписан компилятором непосредственно в нужные места кода.
Указатель - это не "переменная, которая хранит адрес", а само значение адреса.
Упрощая:
Когда компилятор видит оператор создания массива, он внутри себя сопоставляет имя массива и адрес его начала и дальше вставляет адрес везде, где используется имя массива - непосредственно в машинный код.
Потому, отдельная переменная для адреса массива в скомпилированном коде не требуется - адрес начала массива вписан компилятором непосредственно в нужные места кода.
В самом языке, а язык тоже программа, значит занимает память у Си шарпа)
Тимур Алхаматов
Получается это не переменная а лишь приведение к типу указателя? Само название массива вырождается в ассемблерную метку за которой следует выделение памяти под элементы?
Тимур Алхаматов
Ну да, и тут я вспомнил ассемблер и всё встало на свои места...)))
Алексей Караулов
а муха тоже вертолет
Не знаю, как ты это проверяешь, но вот пример, что адрес указателя отличается от значения указателя
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);
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);
Похожие вопросы
- Заменить нулями элементы массива, которые расположены между первым минимальным и последним максимальным элементами масси
- Помогите исправить и дописать программу с массивами на языке C++. Буду благодарен, т. к. самому уже не понятно.
- Нужна помощь в составлении одномерных массивов С++
- Кольцевой сдвиг массива
- Помогите пожалуйста с Массивами .В языке С .Заполнил 2-мерный массив N и M случайными числами дальше не понимаю.
- Устройство статических и динамических массивов в оперативной памяти (...)
- Помогите пожалуйста - создать 4 массива на c++
- Помощь с Массивами C++
- Создать одномерный массив, состоящий из n вещественных элементов. Элементы массива определить при помощи случайных чисел
- Двумерный динамический массив с неизвестны количеством столбиков или строк