2010-02-16 6 views
5

Nie rozumiem dlaczego poniższy przykład kompiluje i działa:Dlaczego można określić rozmiar tablicy w parametrze funkcji?

void printValues(int nums[3], int length) { 
    for(int i = 0; i < length; i++) 
     std::cout << nums[i] << " "; 
    std::cout << '\n'; 
} 

Wydaje się, że rozmiar 3 jest całkowicie ignorowany, ale kładąc nieprawidłowych wyników rozmiarze w błąd kompilacji. Co tu się dzieje?

+2

przez nieprawidłowy rozmiar, masz na myśli ujemny? – Potatoswatter

+0

@Potatoswatter: tak, i zero – defectivehalt

+0

Po prostu ciekawy, co się dzieje, jeśli robisz sizeof (nums)? –

Odpowiedz

10

W C++ (a także w C), parametry zadeklarowane z typem tablicy zawsze natychmiast zanikują do typu wskaźnika. Następujące trzy deklaracje są równoważne

void printValues(int nums[3], int length); 
void printValues(int nums[], int length); 
void printValues(int *nums, int length); 

tj. rozmiar nie ma znaczenia. Jednak nadal nie oznacza to, że można tam użyć nieważnej deklaracji tablicy, tzn. Nie można na przykład określić ujemnego lub zerowego rozmiaru.

(BTW, to samo odnosi się do parametrów typu funkcji - to natychmiast rozpada się wskaźnik do funkcji typ.)

Jeśli chcesz wymusić dopasowanie rozmiaru tablicy między argumentów i parametrów, należy pointer- lub odniesienie typy -to-tablicy w deklaracji parametrów

void printValues(int (&nums)[3]); 
void printValues(int (*nums)[3]); 

oczywiście, w tym przypadku rozmiar staną się w czasie kompilacji stała i nie ma sensu przechodzenia length więcej.

+0

Przyjemny połów o wartości ujemnej lub zerowej w deklaracji, nie pomyślałbym o zrobieniu tego w pierwszej kolejności. –

+0

Czysty, nie wiedziałem, że możesz wymusić rozmiar tablicy. '(* nums) [3]' nie działa przy okazji. – defectivehalt

+0

@Kavon, robi to - rozważ "void f (int (* a) [3]);" vs. 'int a [2]; f (&a); '. –

-1

Rozmiar tablicy nie jest ignorowany, jest częścią typu argumentu. Powinieneś otrzymać błąd kompilatora, jeśli spróbujesz przekazać tablicę o dowolnym innym rozmiarze do tej funkcji.

Z drugiej strony C i C++ nie sprawdzają granic dostępu do tablicy, więc są ignorowane jako. Ale tak samo jest w każdym innym kontekście, nie tylko w przypadku parametrów funkcji.

+3

Nieprawda. W powyższej deklaracji rozmiar tablicy jest częścią składni, ale nie ma efektu semantycznego. Deklaracja parametru jest równoważna "int nums []" i "int * nums". Rozmiar jest rzeczywiście ignorowany. – AnT

+0

@AndreyT: Naprawdę? Naucz się czegoś nowego każdego dnia - muszę kiedyś spróbować tego, by przekonać się o tym. –

+0

Miałem wrażenie, że parametry wielkości tablicy miały znaczenie w przypadku wielowymiarowych macierzy. –

2

nie widzę co skompilować błąd którego się odnosimy - tablice przekazywane do funkcji rozpadu do wskazówek i tracisz informacje typu array. Mogłeś również stosowane:

void printValues(int* nums, int length); 

Można uniknąć próchnicy do wskaźników za pomocą odwołań:

void printValues(int (&nums)[3], int length); 

Albo po prostu użyć wskaźników, jeśli nie chcą stałej wielkości tablic.

+0

Przynajmniej z kompilatorem Visual C++, spowoduje to błąd, jeśli rozmiar tablicy jest <= 0, nawet jeśli wartość i tak zostanie całkowicie zignorowana. – defectivehalt

Powiązane problemy