Инициализировать размер массива в C на уровне файла
Я хотел бы инициализировать массив на основе вычислений, но компилятор выдает мне ошибку, когда я пытаюсь это сделать (я использую GCC версии 6.3.0):
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
char textgrid[SCREEN_HEIGHT/16][SCREEN_WIDTH/16];
Ошибка компилятора выглядит следующим образом:
error: variably modified 'textgrid' at file scope
Есть ли способ сделать это на уровне файла?
Кажется, я не могу использовать вычисления как часть оператора #define, чтобы выполнить это, потому что следующее дает мне ту же ошибку:
#define TEXTGRID_WIDTH (SCREEN_WIDTH / 16)
#define TEXTGRID_HEIGHT (SCREEN_HEIGHT / 16)
char textgrid[TEXTGRID_HEIGHT][TEXTGRID_WIDTH];
3 ответа
Согласно стандарту C (6.7.6.2 Массив объявлений)
- ... Если размер является целочисленным константным выражением и тип элемента имеет известный постоянный размер, тип массива не является типом массива переменной длины; в противном случае тип массива является типом массива переменной длины.
и (6.7.6.2 Массив объявлений)
2 Если идентификатор объявлен как имеющий переменно измененный тип, он должен быть обычным идентификатором (как определено в 6.2.3), не иметь никакой связи и иметь либо область действия блока, либо область действия прототипа функции. Если идентификатор объявлен как объект со статическим или потоковым сроком хранения, он не должен иметь тип массива переменной длины.
и наконец ( 6.6 постоянных выражений)
6 Целочисленная константа-выражение117) должна иметь целочисленный тип и иметь только те операнды, которые являются целочисленными константами, константами перечисления, символьными константами, выражениями sizeof, результатом которых являются целочисленные константы, и плавающими константами, которые являются непосредственными операндами приведений. Операторы приведения в выражении с целочисленной константой должны преобразовывать только арифметические типы в целочисленные типы, кроме как в качестве части операнда к оператору sizeof.
Таким образом, вы можете использовать любые определенные именованные константы, такие как
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
или счетчики
enum { SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600 };
Когда ты пишешь const int SCREEN_WIDTH = 800
Вы определяете объект с именем SCREEN_WIDTH
который содержит значение 800.
Так как SCREEN_WIDTH
это объект, а не значение, вы не можете использовать его для значения в константном выражении. Хотя его значение для нас не меняется и не очевидно, оно не может считаться константой времени компиляции.
Чтобы определить массив в области видимости файла, вы должны использовать измерения, которые являются константными выражениями (выражениями, сформированными полностью из констант времени компиляции).
В С const
квалифицированная переменная не считается постоянной времени компиляции. Вам понадобится постоянная времени компиляции, чтобы упомянуть размер массива в области видимости файла.
Вы можете использовать #define
заявления для этой цели.