В чем смысл статики? - PullRequest
       3

В чем смысл статики?

0 голосов
/ 29 января 2019

Рассмотрим следующий код:

static uint8_t tab[] = {1, 2};

void foo() {
    uint8_t tab2[] = {1, 2};
}

У меня здесь два массива, один с ключевым словом static, второй внутри функции.Как правильно назвать каждого из них?Потому что эти двое статичны.Я знаю разницу в том, что массив tab будет существовать вечно в отличие от tab2, который существует только при выполнении функции foo().Если tab2 является статическим массивом, который умирает после выхода из функции, не должен ли он называться другим?Каковы собственные имена этих массивов, соответствующих программированию theroy?

Другой пример:

void bar() {
  static uint8_t tab[] = { 1, 2 };
}

Что такое собственное имя согласно теории программирования такой переменной?"статический статический" массив?

Ответы [ 6 ]

0 голосов
/ 29 января 2019

static в декларациях файловой области означает «локально для этой единицы перевода».

Пример:

static int variable=42; 
static int function(){return 0;}
//won't be visible in other translation units

static в декларациях в области блока означает «со статической продолжительностью хранения»:

Пример:

uint8_t *bar() {
  static uint8_t tab[] = { 1, 2 };
  return  &tab[0]; 
  //ok with static but pretty much always an error otherwise
}
int how_many_times_i_ran(){ static unsigned x; return x++; }

static в скобках параметров функции типа «массив» означает, что следующее целочисленное выражение обозначает минимальное количество элементов, на которые должен указывать указатель.

void take3(int Three[static 2+1]); 

void call()
{
    take3((int[3]){0}); //OK
    take3(0); //undefined
    take3((int[2]){0}); //undefined
}
0 голосов
/ 29 января 2019

Условия очистки:

1) static uint8_t tab[] = {1, 2};

2) void foo() { uint8_t tab2[] = {1, 2}; ...

Область действия:
1) Является ли переменная, объявленная в область действия файла .2) переменная, объявленная в локальной области действия .Область действия определяет, где переменная доступна.

  • Локальные переменные, очевидно, доступны только внутри области, в которой они были объявлены.
  • Переменные области видимости файла доступны по всему блоку перевода , где объявлена ​​переменная.Единицей перевода является файл .c и все включенные в него файлы .h.

Срок хранения:

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

Все переменные, объявленные в области видимости файла, имеют статическую продолжительность хранения.
Все переменные, объявленные как static, имеют статическую продолжительность хранения.
ВсеПеременные, объявленные в локальной области, без static, имеют автоматическую продолжительность хранения.

(Некоторые другие случаи существуют для extern и т. Д., Но здесь это не актуально. Есть термин «связь», который я не буду здесь рассматривать.)

Зная это, тогда «потому что тедва статичны "не имеет смысла.У них статически установленный и фиксированный размер, но это все, что у них общего.


Что касается именования, это субъективно и соответствует вашему собственному стандарту кодирования.Дайте им интуитивно понятные имена, поясняющие, что они содержат, а не то, какого они типа.

Некоторые старые стандарты кодирования предпочитали рассматривать объявленные static переменные области видимости файлов как частные и поэтому использовали префикс _ для указанияэтот.Но это плохая практика, потому что она вступает в противоречие с правилами именования стандарта C (и стандарта POSIX).

0 голосов
/ 29 января 2019

C имеет полный набор классов (имя мое) переменных, с вариациями области (для какой части кода доступна переменная) и продолжительности.

Вуровень файла (вне какой-либо функции):

  • без квалификатора: длительность: полная длина программы, область действия: файл, доступный как extern: из любой единицы компиляции программы (которая имеет внешнюю связь))
  • static: длительность: полная длина программы, область действия: файл, доступный как extern: нет (говорят, что имеет внутреннюю связь)

Внутри функции или блока:

  • нет квалификатора: длительность: блок (переменная исчезает в конце блока, где она объявлена), область действия: блок, доступный как extern: нет (называется автоматическим и не имеетlinkage)
  • static: длительность: полная длина программы, область действия: блок, доступный как extern: no (называется блоком static и не имеет связи)

InКроме того, переменная может быть объявлена ​​как extern.В этом случае переменная объявляется только и должна быть определена в другом месте с таким же объявлением в том же модуле компиляции или в другом.

Чтобы быть исчерпывающим, C имеет другую категориюна срок: выделено.Он используется для объектов, созданных с помощью malloc и сохраняющихся до тех пор, пока они не будут явно освобождены.Но будьте осторожны: программист отвечает за сохранение указателя на объект с помощью нормальных правил области видимости, чтобы иметь возможность освободить его.

0 голосов
/ 29 января 2019

Каковы собственные имена этих массивов в соответствии с теорией программирования?

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

0 голосов
/ 29 января 2019

Ключевое слово static означает статическая длительность хранения и внутренняя связь (кроме случаев, когда это относится к области блока, где оно означает статическую длительность хранения и нет связь, поскольку объекты в области блока никогда не связаны).

Ваш tab2 не является статичным , имеет автоматический срок хранения и отсутствие связи.(Для этого есть даже ключевое слово auto, которое подразумевается и обычно не используется. Однако не путайте это с C ++, который «переработал» это ключевое слово для совершенно другого значения.)

Какой идентификатор вы дадите своим переменным - например, tab или tab2 - зависит от вас.Но то, что они являются , очень хорошо определяется языком:

  • Ваш первый tab является статическим глобальным массивом из двух uint8_t.Он имеет статическую продолжительность хранения и внутреннюю связь.
  • Ваш tab2 представляет собой область блока массив из двух uint8_t.Он имеет автоматический срок хранения и нет связь.
  • Ваш второй tab представляет собой область статического блока массив из двух uint8_t.Он имеет статический срок хранения и нет связь.
0 голосов
/ 29 января 2019

Кажется, здесь недоразумение.Это не совсем ваша вина, потому что «С.» означает, по крайней мере, две разные вещи в С.

Ваш tab2 не является статичным.Он не имеет статической длительности хранения и никак не связан со статическим хранением.Это просто массив.Это локальная переменная, которая является массивом.

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

На вашем месте я бы не слишком беспокоился о терминологии;вместо этого беспокойтесь о том, чтобы заставить вашу программу делать то, что вы от нее хотите!

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