как примитивные объявления типов работают в C? - PullRequest
0 голосов
/ 04 сентября 2018

Я не программист на C, поэтому, пожалуйста, поймите;)

Язык C имеет указатели и все его достоинства. Но как работает примитивное объявление типа?

Например, я могу сделать:

char x = 'a';

Там нет указателей, но значение должно храниться где-то в памяти, верно? Могу ли я считать вышеприведенное утверждение переведенным на:

char* _x = malloc(sizeof(char));
char x = *_x;

Ответы [ 5 ]

0 голосов
/ 05 сентября 2018

Это простой вопрос с очень сложным ответом.

На самом деле, вы задаете два разных вопроса - как хранилище выделено для переменной и как имя переменной связано с этим хранилищем.

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

Что касается второго вопроса, ответ (обычно) таков: «это не так». Имена переменных не сохраняются в сгенерированном машинном коде. Вместо этого машинный код обычно ссылается на этот объект через смещение от некоторого адреса, хранящегося в регистре.

0 голосов
/ 04 сентября 2018

Там нет указателей, но значение должно храниться где-то в памяти, верно?

В этом конкретном случае (char x = 'a';) вполне вероятно, что значение будет практически сохраняться только внутри регистра процессора. Но программа ведет себя «как если бы» x находилась в некотором месте памяти.

На практике прочтите Как отлаживать небольшие программы и посмотрите на C ссылку сайт. Если вы хотите более точно понять (хитрую) семантику в C11, обратитесь к ее стандартному n1570 и изучите проект Compcert и статический исходный код. анализаторы типа Frama-C . Семантика памяти из C сложно.

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

PS. Вашему воображаемому коду не хватает free(_x), и это действительно важно, и вы должны спросить себя, где хранится _x! Но не ждите, что мы научим вас Си (нужна целая книга).

0 голосов
/ 04 сентября 2018

Здесь

char x = 'a';

Там нет указателей, но значение должно храниться где-то в памяти, верно? Да, указателей нет, но x является локальной переменной и хранится в разделе stack основной памяти, т.е. x имеет действительную память.

Могу ли я думать о приведенном выше утверждении в переводе: таНос (SizeOf (Char));

char x = * _x;

Нет, вы не можете, поскольку x здесь находится в разделе heap. Таким образом, вы не можете считать оба сценария одинаковыми. И что держит *_x? Garbage. Вам нужно добавить еще одну инструкцию после выделения памяти

*_x = 'a';

0 голосов
/ 04 сентября 2018

Тебе все равно.

Что вам нужно знать, это то, что

char x = 'a';

объявляет x типом char с длительностью автоматического хранения и устанавливает для него int константу 'a', значение которой зависит от кодировки ваша платформа использует, но не должна переполнять char.

Вопрос о том, выживет ли этот сборник или нет, - это совсем другое дело. Возможно, ваш компилятор заменяет число 'a' всякий раз, когда вы пишете x в своем исходном коде; особенно если x никогда не меняется?

0 голосов
/ 04 сентября 2018

Нет, вы не можете.

malloc(sizeof(char));

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

char c = 'a'

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

РЕДАКТИРОВАТЬ: Что касается вашего комментария, как правило, локальные переменные обычно хранятся в стеке (это, конечно, автоматически). malloc , calloc позволяет вам «просить» пространство в куче и использовать его по своему усмотрению. Если вам нужна дополнительная информация, вы можете посмотреть здесь , как упомянуто @ Jabberwocky

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