2016-12-13 3 views
2

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

int a = 101; 
int b[5] = {1, 2, 3, 4, 5}; 

Мне сказали, что b является указателем здесь. например '* (b + 1) = 3;' совпадает с «b [2] = 3 '. Означает ли это, что в кадре стека здесь есть целое число для a, указатель для b и массив (из 5 * sizeof (int) байтов), на который указывает b (я назвал эту ситуацию A) или просто целым числом для a и массива для b (я назвал эту ситуацию B).

Я создал картинку, чтобы сделать это немного более ясно: enter image description here

Если ситуация А правда, почему разработчики C выбрали для реализации массивов так по-разному к переменным? Разве это не означает, что массив должен постоянно иметь дополнительный поиск памяти для указателя, чтобы получить его адрес?

+3

для начала, '* (b + 1) = 2;' (not 3) – artm

+1

C не применяет конкретную схему размещения объектов. Также не требуется куча, ни стопка. И вопрос слишком широк. Также: массивы ** не ** указатели!Тот, кто сказал вам, должен выучить язык, прежде чем учить его. – Olaf

+2

Массивы * распад * указателям. Они сами не являются указателями. – StoryTeller

ответ

2

Означает ли это, что фрейм стека здесь есть целое число для а, указатель на б и массив (5 * SizeOf (INT) байт), который указывал на на б

int b[5] = {1, 2, 3, 4, 5}; 

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

Если объявить дополнительный указатель

int *c = b; 

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

4

C не имеет понятия стек. Используя правильную терминологию, можно сказать, что

int b[5] = {1, 2, 3, 4, 5};

имеет автоматическую продолжительность хранения.

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

Таким образом, b[2] и *(b + 2) эквивалентны. Дизайнеры C сделали это для ясности.

Что происходит в «стек» - это выбор реализации, а не язык.

Отношения между a и b не имеют особого значения. Обратите внимание, что вы не можете «достигнуть» a любопытным индексированием b (и наоборот). Поведение при попытке сделать это: undefined.

Смежные вопросы