2009-08-29 16 views

Odpowiedz

18
int foo[10] = {0}; 

to bardzo dobrze :)


Należy pamiętać, że w przypadku wykonania następujących czynności:

int foo[10] = {1}; 

Tylko pierwszy element tablicy zostanie zainicjowany z niezerową liczbą, podczas gdy reszta zostanie zainicjowana zerami.

+1

@digitalross Jeśli w ogóle nie zainicjujesz autoagregatu, to tak, będzie zawierać śmieci. Pytanie brzmi, co jeśli zainicjujesz agregację z {0}, albo jest to auto, albo nie jest. – AraK

27

w C/C++, jeśli zainicjować tylko pierwszy element tablicy o znanej wielkości, o wartości, reszta będzie zero wypełnione, więc:

int foo[10] = {0}; 

zrobi dokładnie to, co chcesz.

To działa również na elemencie:

struct bar { 
    int x; 
    int y; 
    char c; 
} myBar = {0}; 

zainicjuje wszystkich członków 0.

standardowej (C99 - 6.7.8/12 - Inicjalizacja) mówi tak:

Jeśli mniej inicjalizatorów znajduje się na liście zamkniętej w brasie niż elementy lub elementy agregatu, lub mniej znaków w literałach łańcuchowych używanych do zainicjowania tablicy o znanym rozmiarze niż są elementy w tablicy, to pozostała część r agregatu inicjuje się w sposób niejawny tak samo jak obiekty mające statyczny czas przechowywania.

W języku C gramatura wymaga, aby w nawiasach klamrowych było co najmniej jedno "wyrażenie przypisania". "Wyrażenie przypisania" może być wiele rzeczy od stałej lub identyfikatora do dużo bardziej złożonych wyrażeń. Jednak pusty ciąg nie kwalifikuje się jako "wyrażenie przypisania", więc musi istnieć coś pomiędzy nawiasami klamrowymi.

W C++, gramatyka specjalnie umożliwia „{}” inicjator, więc następujący również zerowej inicjalizacji tablicy:

int foo[10] = {}; 

to chyba warto również zauważyć, że w C++ wpisów, które NIE ma określoną wartość inicjalizacyjną na liście inicjalizacyjnej będzie "zainicjowana wartość" lub "domyślnie zainicjowana", która może być inna niż inicjalizowana od zera w zależności od tego, jakie konstruktory mają typ zmiennej i czy kompilator podąża za C + Standard +98 lub C++ 03 (prawdopodobnie jest to jedyna różnica między C++ 98 i C++ 03). Cała sytuacja z wartością vs. domyślna inicjalizacja jest dość skomplikowana, więc jeśli jesteś zainteresowany, zobacz tę odpowiedź: Do the parentheses after the type name make a difference with new?.

Na szczęście różnica nie wydaje się powodować wielu problemów w praktyce, chociaż jeśli się na nią natknie, prawdopodobnie spowoduje to pewne drapanie głowy przez chwilę, próbując dowiedzieć się, jakie zachowanie powinno być naprawdę. Zwykle nie myślę o tym zbyt wiele - boli mnie głowa.

+0

Z tej reguły powinno wynikać, że nawet int foo [10] = {}; wystarcza dla tablicy złożonej z 10 zer. – UncleBens

+1

@UncleBens - w języku C gramatyka wymaga co najmniej jednego "wyrażenia przypisania", które może być wiele rzeczy od stałej lub identyfikatora aż do bardziej złożonego wyrażenia. Jednak pusty ciąg nie kwalifikuje się jako "wyrażenie przypisania", więc musi istnieć coś pomiędzy nawiasami klamrowymi. Gramatyka C++ w szczególności umożliwia inicjator "{}". –

+1

@digitalross: jest to objęte paragrafem "Jeśli jest mniej inicjalizatorów ... pozostała część agregatu jest inicjowana w sposób niejawny tak samo jak obiekty mające statyczny czas przechowywania." –

0

wszystkie elementy niewymienione w inicjalizatorze zostaną zainicjowane na ten typ zerowy, o ile ma to zastosowanie.

Tak int foo [10] = {0}; jest w porządku, pozostałe niewymienione elementy będą również 0

0

Wow, rodzaj C wydaje się być prosty, ale nawet po latach cytowania specyfikacji, to niesamowite, jak coś nowego może się jeszcze pojawić.

Po prostu sprawdziłem w specyfikacji pierwszej wersji (ANSI/ISO 9899-1990) i, z całą pewnością, podano pozostałą część agregatu auto (6.5.7) "Jeśli jest mniej ... zainicjalizowanych domyślnie ... ".

Tak: Wszystko inne niż automatyczne. Zawsze 0 (lub, jak zainicjowano), niezależnie od tego, czy zostało zainicjalizowane czy nie. Auto: całkowicie zainicjalizowane, jeśli w ogóle zainicjalizowano jakiekolwiek elementy, w przeciwnym razie nie zainicjowano.

+2

@digitalross: Mylisz się. Jeśli pozostawisz mieszkańców całkowicie niezainicjowanych, nie będzie ich zainicjować. Jeśli użyjesz inicjalizatora i zainicjujesz dowolny z pól, każde pole zostanie zainicjowane. –

+0

+1 za poprawienie odpowiedzi :) – AraK

+0

Heh, dziękuję! – DigitalRoss

Powiązane problemy