Мне нужно инициализировать матрицу h x h
в C пробелами.
Как правильно это сделать без циклов?
int h = 8;
char arr[h][h] = {{' '}}; // does not work....
Это массив переменной длины (VLA), где размерность является переменной. Вы не можете инициализировать VLA. Если вы сделаете h
константой (например, перечисляемым значением), вы можете ее инициализировать.
@MOehm, если постоянно, как это сделать?
Пробовали memset()
?
Или это?
enum { h = 8 };
или #define DIM 8
, например.
Не будет работать с vla, но это работает в gcc и clang: char arr[8][8] = { [0 ... 7] = {[0 ... 7] = ' '}};
. Почти уверен, что это нестандартное расширение в обоих компиляторах.
Смотрите этот ответ
Эти декларации
int h = 8;
char arr[h][h] = {{' '}};
объявить массив переменной длины. Массивы переменной длины могут быть объявлены только внутри функций (например, внутри main), потому что они должны иметь автоматическую продолжительность хранения и не могут быть инициализированы в объявлениях.
Так что вы можете написать, например
#include <string.h>
//...
int main( void )
{
int h = 8;
char arr[h][h];
memset( arr, ' ', h * h );
//...
}
То есть вы можете применить стандартную функцию memset
, которая устанавливает все символы массива с пробелом ' '
.
Даже если у вас есть массив постоянной длины, тем не менее для инициализации всех его элементов символом пробела лучше использовать функцию memset
.
#include <string.h>
//...
int main( void )
{
enum { h = 8 };
char arr[h][h];
memset( arr, ' ', h * h );
//...
}
memset(arr, ' ', sizeof arr)
тоже должно работать
С сайта GNU:
Чтобы инициализировать диапазон элементов одним и тем же значением, напишите «[first ... последний] = значение’. Это расширение GNU
Вы можете использовать назначенные инициализаторы. Но этот тип инициализации работает, только для constant number of rows and columns
.
char arr[8][8] = { { [0 ... 7] = ' '}, { [0 ... 7] = ' '}, { [0 ... 7] = ' '}, { [0 ... 7] = ' '}, { [0 ... 7] = ' '}, { [0 ... 7] = ' '}, { [0 ... 7] = ' '}, { [0 ... 7] = ' '} };
Это не стандартная функция C. Кроме того, он использует магическое число 7.
Пожалуйста, посетите этот сайт:gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
Где вы нашли такой инициализатор [0 ... 7] = ' ' в вопросе по ссылке?
Вы проверяли это? Назначенные инициализаторы или нет, вы все равно пытаетесь инициализировать VLA...
«Чтобы инициализировать диапазон элементов одним и тем же значением, напишите« [first ... last] = value ». Это расширение GNU». Из этой ссылки
Да, назначенные инициализаторы хороши... но они не обходят тот факт, что вы инициализируете VLA. Если бы вы сделали размеры постоянными, это сработало бы... но как есть?
@Dmitri OP упомянул, что h = 8
. ОП не упомянул о массиве переменной длины.
Это VLA, потому что размеры указываются с помощью переменной, а не константы.
То, что вы действительно хотите сделать, это: { [0 ... h] = ' '},
но я не уверен, что вы можете, потому что h
это int h = 8;
. Даже если мы сделаем: #define h 8
, есть проблема. Если мы изменим значение (например, на 9
), последовательность прерывается [недостаточно повторений]. Назначенные инициализаторы хороши [я их часто использую], но выполнение memset
или некоторых for
циклов на самом деле является лучшим решением для данной проблемы.
@CraigEstey Хорошо. Я понял теперь. Спасибо!
@Dmitri Спасибо за обсуждение. Я понял.
У вас не может быть частичного инициализатора здесь. Придется предоставить полный инициализатор. Частичные инициализаторы принимают нули для отсутствующих частей.