Есть ли способ жестко закодировать двумерный целочисленный массив без необходимости упоминания какого-либо измерения в C? - PullRequest
0 голосов
/ 12 октября 2019

Я легко могу жестко закодировать 2D char массивы, избегая указания последнего измерения, как показано ниже.

char *mobile_games[] = { "DISTRAINT", "BombSquad" }

Хотя я не могу этого сделать ...

char *pc_games[] = { { 'F', 'E', 'Z' }, { 'L', 'I', 'M', 'B', 'O' } }

То же самое предупреждение появляется, когда я пытаюсь что-то вроде ...

int *rotation[] = { { 1, 0 }, { 0, 1 } }

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

Ответы [ 2 ]

1 голос
/ 12 октября 2019

6.7.9 стандарта вполне понятны:

Инициализатор для скаляра ... Начальное значение объекта - это значение выражения (после преобразования); ...

и объясняет ваши предупреждения:

мне дали список инициализаторов из двух списков инициализаторов:

main.c:4:26: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int' [-Wint-conversion]
  char *pc_games[] = { { 'F', 'E', 'Z' }, { 'L', 'I', 'M', 'B', 'O' } };
                         ^~~

первый из которых содержит целочисленные константы символов,что ты сказал мне засунуть указатель, это не хорошо ...

main.c:4:31: warning: excess elements in scalar initializer
  char *pc_games[] = { { 'F', 'E', 'Z' }, { 'L', 'I', 'M', 'B', 'O' } };
                              ^~~

... но я попробовал с первым, а потом я нашел другую целочисленную символьную константу, которую я ничего не могу сделатьс, поскольку указанный вами тип (char *) подразумевает скаляр, вы имели в виду массив указателей? или, что еще лучше, массив целых чисел?

main.c:4:45: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int' [-Wint-conversion]
  char *pc_games[] = { { 'F', 'E', 'Z' }, { 'L', 'I', 'M', 'B', 'O' } };
                                            ^~~

... и затем я перешел ко второму указанному вами списку инициализаторов и попытался снова выполнить то же преобразование ...

main.c:4:50: warning: excess elements in scalar initializer
  char *pc_games[] = { { 'F', 'E', 'Z' }, { 'L', 'I', 'M', 'B', 'O' } };

... а потом я нашел больше случайных констант в списке инициализатора. В чем дело? Вы имели в виду char pc_games[2][5]?


Q: Я принял char * за char []. Могу ли я сделать char s[] = {'f', 'e', 'z'};? A: Да. 6.7.9p14 также позволяет

Массив символьного типа может быть инициализирован строковым литералом или строковым литералом UTF-8, необязательно заключенным в фигурные скобки. Последовательные байты строкового литерала (включая завершающий нулевой символ, если есть место или массив неизвестного размера) инициализируют элементы массива.

, поэтому char s[] = {"fez"}; также возможно.

1 голос
/ 12 октября 2019

Это не относится к 2D массивам. Вы также не можете инициализировать указатель следующим образом:

int *int_array = {1, 2};

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

Чтобы делать то, что вы хотите, вам нужно объявить его как 2D-массив, а не как массивуказатели.

int rotation[][2] = { { 1, 0 }, {0, 1} };

Если вы действительно хотите массив указателей, вам нужно будет объявить значения строк отдельно.

int rot0[] = {1, 0};
int rot1[] = {0, 1};
int *rotation[] = {rot0, rot1};
...