Как инициализировать матрицу в C

Мне нужно инициализировать матрицу h x h в C пробелами.

Как правильно это сделать без циклов?

int h = 8;
char arr[h][h] = {{' '}}; // does not work.... 

У вас не может быть частичного инициализатора здесь. Придется предоставить полный инициализатор. Частичные инициализаторы принимают нули для отсутствующих частей.

Eugene Sh. 10.12.2020 19:17

Это массив переменной длины (VLA), где размерность является переменной. Вы не можете инициализировать VLA. Если вы сделаете h константой (например, перечисляемым значением), вы можете ее инициализировать.

M Oehm 10.12.2020 19:18

@MOehm, если постоянно, как это сделать?

serge 10.12.2020 19:18

Пробовали memset()?

tadman 10.12.2020 19:18

Или это?

Robert Harvey 10.12.2020 19:19
enum { h = 8 }; или #define DIM 8, например.
M Oehm 10.12.2020 19:19

Не будет работать с vla, но это работает в gcc и clang: char arr[8][8] = { [0 ... 7] = {[0 ... 7] = ' '}};. Почти уверен, что это нестандартное расширение в обоих компиляторах.

William Pursell 10.12.2020 19:24

Смотрите этот ответ

Basile Starynkevitch 10.12.2020 19:24
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
8
1 354
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Эти декларации

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) тоже должно работать
tstanisl 10.12.2020 23:53

С сайта 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.

Vlad from Moscow 10.12.2020 19:29

Пожалуйста, посетите этот сайт:gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

Krishna Kanth Yenumula 10.12.2020 19:33

Где вы нашли такой инициализатор [0 ... 7] = ' ' в вопросе по ссылке?

Vlad from Moscow 10.12.2020 19:34

Вы проверяли это? Назначенные инициализаторы или нет, вы все равно пытаетесь инициализировать VLA...

Dmitri 10.12.2020 19:34

«Чтобы инициализировать диапазон элементов одним и тем же значением, напишите« [first ... last] = value ». Это расширение GNU». Из этой ссылки

Krishna Kanth Yenumula 10.12.2020 19:36

Да, назначенные инициализаторы хороши... но они не обходят тот факт, что вы инициализируете VLA. Если бы вы сделали размеры постоянными, это сработало бы... но как есть?

Dmitri 10.12.2020 19:37

@Dmitri OP упомянул, что h = 8 . ОП не упомянул о массиве переменной длины.

Krishna Kanth Yenumula 10.12.2020 19:41

Это VLA, потому что размеры указываются с помощью переменной, а не константы.

Dmitri 10.12.2020 19:41

То, что вы действительно хотите сделать, это: { [0 ... h] = ' '}, но я не уверен, что вы можете, потому что h это int h = 8;. Даже если мы сделаем: #define h 8, есть проблема. Если мы изменим значение (например, на 9), последовательность прерывается [недостаточно повторений]. Назначенные инициализаторы хороши [я их часто использую], но выполнение memset или некоторых for циклов на самом деле является лучшим решением для данной проблемы.

Craig Estey 10.12.2020 19:43

@CraigEstey Хорошо. Я понял теперь. Спасибо!

Krishna Kanth Yenumula 10.12.2020 19:44

@Dmitri Спасибо за обсуждение. Я понял.

Krishna Kanth Yenumula 10.12.2020 19:51

Другие вопросы по теме