W każdym razie złą praktyką jest inicjałowanie tablicy znaków literałem łańcuchowym.
Autor tego komentarza tak naprawdę nigdy go nie usprawiedliwia, a stwierdzenie to mnie zastanawia.
W C (i oznaczyłeś to jako C), jest to prawie jedyny sposób na zainicjowanie tablicy char
z wartością ciągu (inicjalizacja różni się od przypisania). Możesz napisać albo
char string[] = "october";
lub
char string[8] = "october";
lub
char string[MAX_MONTH_LENGTH] = "october";
W pierwszym przypadku rozmiar tablicy jest pobierany z rozmiaru inicjatora. Literały łańcuchowe są przechowywane jako tablice char
z końcowym bajtem 0, więc rozmiar tablicy wynosi 8 („o”, „c”, „t”, „o”, „b”, „e”, „r”, 0). W dwóch pozostałych przypadkach rozmiar tablicy jest określony jako część deklaracji (8 i MAX_MONTH_LENGTH
, cokolwiek by się nie zdarzyło).
Czego nie może zrobić, to napisać coś
char string[];
string = "october";
lub
char string[8];
string = "october";
itd. W pierwszym przypadku deklaracja string
jest niekompletna, ponieważ nie określono rozmiaru tablicy i nie ma inicjatora, z którego można by pobrać rozmiar. W obu przypadkach =
nie zadziała, ponieważ a) wyrażenie tablicowe, które string
może nie być celem zadania ib) =
operator nie jest zdefiniowany tak, aby kopiować zawartość jednej tablicy do drugiej.
Z tego samego powodu nie możesz pisać
char string[] = foo;
gdzie foo
jest kolejna tablica char
. Ta forma inicjalizacji będzie działać tylko z literałami łańcuchowymi.
EDYTOWAĆ
Powinienem to zmienić, aby powiedzieć, że możesz także inicjować tablice, aby przechowywać ciąg znaków za pomocą inicjatora w stylu tablicowym
char string[] = {'o', 'c', 't', 'o', 'b', 'e', 'r', 0};
lub
char string[] = {111, 99, 116, 111, 98, 101, 114, 0}; // assumes ASCII
ale łatwiej jest oczom używać literałów łańcuchowych.
EDYCJA 2
Aby przypisać zawartość tablicy poza deklaracją, musisz użyć albo strcpy/strncpy
(dla łańcuchów zakończonych 0) lub memcpy
(dla dowolnego innego typu tablicy):
if (sizeof string > strlen("october"))
strcpy(string, "october");
lub
strncpy(string, "october", sizeof string); // only copies as many characters as will
// fit in the target buffer; 0 terminator
// may not be copied, but the buffer is
// uselessly completely zeroed if the
// string is shorter!