2012-04-25 11 views
7

chciałbym wiedzieć, czy istnieje różnica pomiędzy:Jaka jest różnica między {0} a ""?

char s[32] = ""; 

oraz:

char s[32] = {0}; 

Dzięki.

+0

Odpowiedź została udzielona. Ale na wszelki wypadek powinieneś pomyśleć teraz, że nie ma różnicy między '{0}' i '" "', spróbuj tego z innymi typami, na przykład, tablice 'int' zamiast tablic' char'. Wtedy zobaczysz różnicę. –

Odpowiedz

18

No nie ma różnicy między obu deklaracji:

char bla[32] = {0}; 

and 

char bla[32] = ""; 

Patrz odpowiedni ustęp Standard C (podkreślenie moje):

(C99 6.7.8p21) „jeżeli istnieją mniej inicjalizatorów na liście zamkniętej niż elementy lub elementy agregatu, lub mniej znaków w ciągu literowym użytych do zainicjowania tablicy o znanym rozmiarze niż są elementy w tablicy, pozostała część agregatu będzie zainicjalizowany domyślnie s ame jako obiekty, które mają statyczny czas przechowywania. "

+0

OK, wielkie dzięki! – md5

+1

To znaczy tak długo, jak '\ 0 '== 0'. – Philip

+2

@Philip Nie mam cytatu ze Standardu, ale tutaj jest to, co K & R 2nd mówi * "Stała znakowa" \ 0 "reprezentuje znak o wartości zero, znak null." \ 0 "jest często zapisywane zamiast 0 aby podkreślić charakter charakteru jakiegoś wyrażenia, ale wartość liczbowa wynosi zaledwie 0. "* – ouah

10

W tym przypadku, nie ma żadnej różnicy, jak zainicjować wszystkie otwory układu 0. Ogólnie "" działa tylko char macierzy (z lub bez modyfikacji, takich jak const lub unsigned), lecz {0} działa dla tablic wszystkie numeryczne typy.

W punkcie 6.7.9 normy (n1570), punkt 21 czyta

Jeśli istnieje mniej inicjalizatory na liście Brace-zamknięty niż istnieją elementy lub członkowie agregatu lub mniej znaków w ciągu literałowym, który jest używany do zainicjowania tablicy o znanym rozmiarze niż są elementy w tablicy, reszta agregatu musi być zainicjalizowana tak samo jak obiekty mające statyczny czas przechowywania.

Tak więc nawet "" inicjuje całą tablicę.

+0

+1 '{0}' działa dla dowolnego typu danych, który może mieć inicjator. Z drugiej strony * nie jest * dozwolone dla wszystkich tablic, a mianowicie dla VLA, ponieważ nie mogą one zawierać inicjalizatorów. –

2

Wynik obu wyrażeń jest taki sam: pusty ciąg. Jednak pierwsza jest bardziej jednoznaczna, a zatem bardziej czytelna.

2

Nie ma różnicy. Możesz także sam zobaczyć! To najbardziej wiarygodna odpowiedź, jaką możesz uzyskać. Po prostu użyj debuggera. Wykonaj dwie linie i porównaj wynik. Ale powinieneś zmienić nazwy tablic. Używam gcc/gdb i skompilować następujący kod

int main(int argc, char* argv[]) 
{ 
    char s[5] = {0}; 
    char t[5] = ""; 
    return 0; 
} 

poprzez gcc -g test.c a następnie powołać gdb a.out. W gdb wejdę

break 5 
run 
print s 

ostatnie stwierdzenie jest odbierane przez gdb z następującym wyjścia:

$1 = "\000\000\000\000" 

będę kontynuował i Enter "Print T" i uzyskać odpowiednio

$2 = "\000\000\000\000" 

który mówi mnie, że z mojego kompilatora wyboru oba oświadczenia dają ten sam wynik.

+3

Matthias: nie jest to najbardziej niezawodna metoda, ponieważ wszelkie niezdefiniowane zachowania mogą się różnić w zależności od implementacji kompilatora lub z powodu różnic w niezainicjowanej zawartości pamięci ... –

+0

@ tony-delroy wyjaśniłem i mam nadzieję, że mój punkt był jaśniejszy (i didn Naprawdę dostaję twoje chociaż ...) – Matthias

+1

moim celem jest to, że wiedza o tym, co twój program robi w konkretnym przebiegu, nie dowodzi, że standard C++ wymaga jakiegokolwiek pliku wykonywalnego wygenerowanego z tego kodu źródłowego przez dowolny kompilator C++. Jeśli potrzebujesz niezawodnego kodu, trzymaj się tego, co gwarantuje Standard, ponieważ zachowanie obserwowalnego programu może się różnić. Na przykład, jeśli czytasz z niezainicjowanej zmiennej - 'int x; std :: cout << x << '\ n'; '- możesz zobaczyć liczbę, której spodziewasz się przez przypadek (szczególnie jeśli spodziewasz się 0), ale ponownie uruchom program lub przekompiluj go, i możesz uzyskać inną wydajność ... –

2

Poza tym, co już powiedział:

char s[32] = ""; 

=

char s[32] = {'\0'}; 

=

char s[32] = {0}; 

=

char s[32] = {0, 0, 0, /* ...32 zeroes here*/ ,0 }; 

Wszystko to spowoduje, że dokładnie ten sam kod maszyny: tablica 32-bajtowa wypełniona wszystkimi zerami.

Powiązane problemy