Biorąc pod uwagę deklaracje
char *s0 = "hello world";
char s1[] = "hello world";
przyjmij następującą hipotetyczną mapę pamięci:
0x01 0x02 0x03 0x04
0x00008000: „h” „e” „l” „l”
0x00008004: „o” „w” „o”
0x00008008: „r” „l” „d” 0x00
...
s0: 0x00010000: 0x00 0x00 0x80 0x00
s1: 0x00010004: „h” „e” „l” „l”
0x00010008: „o” „w” „o”
0x0001000C: „r” „l” „d” 0x00
Dosłowny ciąg znaków "hello world"to 12-elementowa tablica char( const charw języku C ++) ze statycznym czasem przechowywania, co oznacza, że pamięć jest przydzielana podczas uruchamiania programu i pozostaje przydzielona do czasu zakończenia programu. Próba modyfikacji zawartości literału łańcuchowego wywołuje niezdefiniowane zachowanie.
Linia
char *s0 = "hello world";
definiuje s0jako wskaźnik charz automatycznym czasem przechowywania (co oznacza, że zmienna s0istnieje tylko dla zakresu, w którym została zadeklarowana) i kopiuje do niej adres literału łańcucha ( 0x00008000w tym przykładzie). Należy zauważyć, że ponieważ s0wskazuje na ciągiem znaków, nie powinno być wykorzystywane jako argument do dowolnej funkcji, które starają się je modyfikować (np strtok(), strcat(), strcpy()itd.)
Linia
char s1[] = "hello world";
definiuje s1jako 12-elementową tablicę char(długość jest pobierana z literału łańcucha) z automatycznym czasem przechowywania i kopiuje zawartość literału do tablicy. Jak widać z mapy pamięci, mamy dwie kopie ciągu "hello world"; Różnica polega na tym, że możesz zmodyfikować ciąg znaków zawarty w s1.
s0i s1są wymienne w większości kontekstów; oto wyjątki:
sizeof s0 == sizeof (char*)
sizeof s1 == 12
type of &s0 == char **
type of &s1 == char (*)[12] // pointer to a 12-element array of char
Możesz ponownie przypisać zmienną, s0aby wskazywała inny literał łańcuchowy lub inną zmienną. Nie można ponownie przypisać zmiennej, s1aby wskazywała inną tablicę.