Zauważ, że GCC ma rozszerzenie wskazanej notacji inicjalizującej, co jest bardzo przydatne w kontekście. Jest to również dozwolone clang
bez komentarza (po części dlatego, że stara się być kompatybilny z GCC).
Notacja rozszerzenia umożliwia ...
wyznaczenie zakresu elementów do zainicjowania z następującą wartością. Na przykład:
#include <stdio.h>
enum { ROW = 5, COLUMN = 10 };
int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = 1 } };
int main(void)
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COLUMN; j++)
printf("%2d", array[i][j]);
putchar('\n');
}
return 0;
}
Wynik jest, jak można się spodziewać,:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
Należy zauważyć, że Fortran 66 (Fortran IV) miał liczbę powtórzeń dla inicjatorów dla tablic; zawsze wydawało mi się dziwne, że C nie dostał ich po dodaniu wyznaczonych inicjatorów do języka. Pascal używa 0..9
notacji do oznaczenia zakresu od 0 do 9 włącznie, ale C nie używa ..
jako tokena, więc nie jest zaskakujące, że nie został użyty.
Zauważ, że spacje wokół ...
notacji są zasadniczo obowiązkowe; jeśli są dołączone do liczb, to liczba jest interpretowana jako liczba zmiennoprzecinkowa. Na przykład, 0...9
byłoby tokenized jak 0.
, .
, .9
i liczb zmiennoprzecinkowych nie są akceptowane jako indeksami macierzy. Z wymienionymi stałymi ...ROW-1
nie sprawi kłopotów, ale lepiej jest wyrobić sobie bezpieczne nawyki.
Uzupełnienia:
Zwracam uwagę na to, że GCC 7.3.0 odrzuca:
int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = { 1 } } };
gdzie jest dodatkowy zestaw nawiasów klamrowych wokół skalarnego inicjatora 1
( error: braces around scalar initializer [-Werror]
). Nie jestem pewien, czy to prawda, biorąc pod uwagę, że normalnie można określić nawiasy klamrowe wokół wartości skalarnej w int a = { 1 };
, co jest wyraźnie dozwolone w standardzie. Nie jestem też pewien, czy jest to nieprawidłowe.
Zastanawiam się również, czy nie byłaby lepsza notacja [0]...[9]
- to jest jednoznaczne, nie można jej pomylić z żadną inną prawidłową składnią i unika pomyłki z liczbami zmiennoprzecinkowymi.
int array[ROW][COLUMN] = { [0]...[4] = { [0]...[9] = 1 } };
Może komisja normalizacyjna to rozważy?