Где постоянные переменные хранятся в C?

scales::percent имеет аргумент accuracy, который вы можете изменить. Это должно дать вам то, что вы хотите:

ggplot(df, aes(x, y)) + 
  geom_point(
    colour="red",
    size=5
  ) + 
  labs(x="X", y="Y") + 
  xlim(-1,1) + 
  ylim(-1,1) + 
  scale_x_continuous(labels = function(x) scales::percent(x, accuracy = 1)) + 
  scale_y_continuous(labels = function(x) scales::percent(x, accuracy = 1))
51
задан rgettman 28 March 2018 в 09:02
поделиться

10 ответов

То, как они хранятся, является деталью реализации (зависит от компилятора).

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

40
ответ дан 7 November 2019 в 10:10
поделиться

Я проверил x86_64 систему GNU/Linux. При помощи указателя на переменную 'константы' может быть изменено значение. Я использовал objdump. Не нашел переменную 'константы' в сегменте текста. переменная 'константы' хранится на стеке. 'константа' является директивой компилятора в "C". Компилятор бросает ошибку, когда это сталкивается с оператором, изменяющим переменную 'константы'.

0
ответ дан 7 November 2019 в 10:10
поделиться

Некоторые константы даже не сохраняются.

Рассмотрим следующий код: int x = foo (); х * = 2; . Скорее всего, компилятор превратит умножение в x = x + x; , поскольку это уменьшает необходимость загрузки числа 2 из памяти.

0
ответ дан 7 November 2019 в 10:10
поделиться

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

1
ответ дан 7 November 2019 в 10:10
поделиться

Зависит на вашем компиляторе, возможностях вашей системы, вашей конфигурации во время компиляции.

gcc помещает константы только для чтения в раздел .text , если не указано иное.

4
ответ дан 7 November 2019 в 10:10
поделиться

Обычно они хранятся в секции данных только для чтения (в то время как секция глобальных переменных имеет права записи). Таким образом, попытка изменить константу, взяв ее адрес, может привести к нарушению прав доступа, известному как segfault.

Но на самом деле это зависит от вашего оборудования, ОС и компилятора.

1
ответ дан 7 November 2019 в 10:10
поделиться

Рассмотрим код:

const int i = 0;
static const int k = 99;

int function(void)
{
    const int j = 37;
    totherfunc(&j);
    totherfunc(&i);
  //totherfunc(&k);
    return(j+3);
}

Обычно i может храниться в текстовом сегменте (это переменная только для чтения с фиксированным значением). Если его нет в текстовом сегменте, он будет сохранен рядом с глобальными переменными. Учитывая, что он инициализирован нулем, он может находиться в разделе 'bss' (где обычно выделяются обнуленные переменные) или в разделе 'данных' (где обычно выделяются инициализированные переменные).

Если компилятор убежден, что k не используется (что может быть, поскольку он локален для одного файла), он может вообще не отображаться в объектном коде. Если вызов totherfunc () , который ссылается на k , не был закомментирован, тогда k должен быть где-то назначен адрес - он, скорее всего, будет в том же сегменте, что и i .

Константа (если это константа, остается ли она переменная?) j , скорее всего, появится в стеке обычной реализации C. (Если бы вы спрашивали в группе новостей comp.std.c, кто-то упомянул бы, что стандарт не говорит, что автоматические переменные появляются в стеке; к счастью, SO не comp.std.c!)

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

(Стилистически - переменные i и j должны иметь больше , более осмысленные имена, это только пример!)

12
ответ дан 7 November 2019 в 10:10
поделиться

Он может вообще не храниться.

Рассмотрим такой код:

#import<math.h>//import PI
double toRadian(int degree){
  return degree*PI*2/360.0;
}

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

0
ответ дан 7 November 2019 в 10:10
поделиться

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

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

0
ответ дан 7 November 2019 в 10:10
поделиться

В зависимости от сегментации данных, которой следует конкретный процессор, у нас есть пять сегментов:

  1. Сегмент кода - хранит только код, ROM
  2. BSS (или блок, запускаемый символом) Сегмент данных - хранит инициализированные глобальные и статические переменные
  3. Сегмент стека - хранит все локальные переменные и другую информацию, касающуюся адреса возврата функции и т. Д.
  4. Сегмент кучи - все динамические распределения происходят здесь
  5. Данные Сегмент BSS (или блок, запускаемый символом) - хранит неинициализированные глобальные и статические переменные

Обратите внимание, что разница между сегментами данных и BSS заключается в том, что первый хранит инициализированные глобальные и статические переменные, а второй - неинициализированные. 1226] Итак, почему я говорю о сегментации данных, когда я должен просто сказать, где хранятся постоянные переменные ...на то есть причина ...

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

Например:

  • Если у меня есть const int, которая является локальной переменной, то она сохраняется в защищенная от записи область сегмента стека.
  • Если у меня есть глобальная переменная, инициализированная const var, то она сохраняется в сегменте данных.
  • Если у меня есть неинициализированная const var, то она сохраняется в сегменте BSS ...

Подводя итог, «const» - это просто КВАЛИФИКАТОР данных, что означает, что сначала компилятор должен решить, в каком сегменте переменная должна быть сохранена, а затем, если переменная является константой, тогда она подлежит сохранению. в защищенной от записи области этого конкретного сегмента.

  • Если у меня есть const int, которая является локальной переменной, то она сохраняется в защищенной от записи области сегмента стека.
  • Если у меня есть глобальная переменная, которая инициализирована как const var, то она сохраняется в сегменте данных.
  • Если у меня есть неинициализированная const var, то она сохраняется в сегменте BSS ...

Подводя итог, «const» - это просто КВАЛИФИКАТОР данных, что означает, что сначала компилятор должен решить, в каком сегменте переменная должен быть сохранен, а затем, если переменная является константой, тогда она подлежит сохранению в защищенной от записи области этого конкретного сегмента.

  • Если у меня есть const int, которая является локальной переменной, то она сохраняется в защищенной от записи области сегмента стека.
  • Если у меня есть глобальная переменная, которая инициализирована как const var, то она сохраняется в сегменте данных.
  • Если у меня есть неинициализированная const var, то она сохраняется в сегменте BSS ...

Подводя итог, «const» - это просто КВАЛИФИКАТОР данных, что означает, что сначала компилятор должен решить, в каком сегменте переменная должен быть сохранен, а затем, если переменная является константой, тогда она подлежит сохранению в защищенной от записи области этого конкретного сегмента.

затем он сохраняется в сегменте BSS ...

Подводя итог, «const» - это просто КВАЛИФИКАТОР данных, что означает, что сначала компилятор должен решить, в каком сегменте следует сохранить переменную, а затем, если переменная является const, то он подлежит хранению в защищенной от записи области этого конкретного сегмента.

затем он сохраняется в сегменте BSS ...

Подводя итог, «const» - это просто КВАЛИФИКАТОР данных, что означает, что сначала компилятор должен решить, в каком сегменте следует сохранить переменную, а затем, является ли переменная const, то он подлежит хранению в защищенной от записи области этого конкретного сегмента.

32
ответ дан 7 November 2019 в 10:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: