Dlaczego rozmiar tablicy wysyłanej jako parametr nie jest taki sam jak w main?
#include <stdio.h>
void PrintSize(int p_someArray[10]);
int main () {
int myArray[10];
printf("%d\n", sizeof(myArray)); /* As expected, 40 */
PrintSize(myArray);/* Prints 4, not 40 */
}
void PrintSize(int p_someArray[10]){
printf("%d\n", sizeof(p_someArray));
}
sizeof
operator nit: zwraca obiekt typusize_t
, więc powinieneś wydrukować go za pomocą%zu
(C99) lub rzutować na,int
jeśli używasz tego%d
jak powyżej w swoichprintf
wywołaniach.void PrintSize(int (*p_someArray)[10])
. Wewnątrz funkcji można uzyskać dostęp do tablicy za pomocą operatora wyłuskiwania*
:sizeof(*p_someArray)
. Będzie to miało taki sam efekt, jak używanie odwołań w C ++.Jest to wskaźnik, dlatego powszechną implementacją jest przekazywanie rozmiaru tablicy jako drugiego parametru do funkcji
źródło
Jak powiedzieli inni, tablice rozpadają się na wskaźniki do pierwszego elementu, gdy są używane jako parametry funkcji. Warto również zauważyć, że sizeof nie ocenia wyrażenia i nie wymaga nawiasów, gdy jest używany z wyrażeniem, więc parametr w rzeczywistości nie jest w ogóle używany, więc równie dobrze możesz napisać sizeof z typem, a nie z wartością.
źródło
Tak więc będziesz musiał przekazać długość tablicy jako drugi parametr. Kiedy piszesz kod, w którym zarówno deklarujesz tablicę o stałym rozmiarze, a później przekazujesz tę tablicę do funkcji, trudno jest mieć stałą długości tablicy, która pojawia się w kilku miejscach w kodzie ...
K&R na ratunek:
Teraz możesz np .:
źródło
Ponieważ tablice rozpadają się na wskaźniki, gdy są przekazywane jako parametry. Tak działa C, chociaż możesz przekazywać „tablice” w C ++ przez referencje i przezwyciężyć ten problem. Zauważ, że możesz przekazywać tablice o różnych rozmiarach do tej funkcji:
źródło
W C ++ możesz przekazać tablicę przez referencję w tym właśnie celu:
źródło
Znalezione zachowanie jest w rzeczywistości wielką brodawką w języku C. Za każdym razem, gdy deklarujesz funkcję, która przyjmuje parametr tablicy, kompilator ignoruje Cię i zmienia parametr na wskaźnik. Zatem wszystkie te deklaracje zachowują się jak pierwsza:
a będzie wskaźnikiem do int we wszystkich czterech przypadkach. Jeśli przekażesz tablicę do func, natychmiast rozpadnie się ona na wskaźnik do jej pierwszego elementu. (W systemie 64-bitowym 64-bitowy wskaźnik jest dwa razy większy niż 32-bitowy int, więc współczynnik sizeof zwraca 2.)
Jedynym celem tej reguły jest zachowanie wstecznej kompatybilności z kompilatorami historycznymi, które nie obsługiwały przekazywania wartości zagregowanych jako argumentów funkcji.
Nie oznacza to, że niemożliwe jest przekazanie tablicy do funkcji. Możesz obejść tę brodawkę, osadzając tablicę w strukturze (jest to w zasadzie celem std :: array w C ++ 11):
lub przekazując wskaźnik do tablicy:
W przypadku, gdy rozmiar tablicy nie jest stałą czasu kompilacji, możesz użyć techniki wskaźnika do tablicy z tablicami o zmiennej długości C99:
źródło
W języku C nie ma metody określania rozmiaru nieznanej tablicy, dlatego należy przekazać ilość oraz wskaźnik do pierwszego elementu.
źródło
char[]
tablicy ciągów).Nie możesz przekazywać tablic do funkcji.
Jeśli naprawdę chcesz wydrukować rozmiar, możesz przekazać wskaźnik do tablicy, ale nie będzie on wcale ogólny, ponieważ musisz również zdefiniować rozmiar tablicy dla funkcji.
źródło
Zachowanie jest zgodne z projektem.
Ta sama składnia w deklaracji parametrów funkcji oznacza zupełnie inną rzecz niż w definicji zmiennej lokalnej.
Powód jest opisany w innych odpowiedziach.
źródło
W języku C, gdy przekazujesz tablicę jako argument do funkcji, jest ona automatycznie konwertowana na wskaźnik, tablica przekazująca z jednej funkcji inna funkcja jest nazywana wywołaniem przez odniesienie. To jest powód, dla którego wywołana funkcja otrzymuje tylko wskaźnik wskazujący na pierwszy element funkcji. To jest powód
fun (int a []) jest podobne do fun (int * a);
więc kiedy wypiszesz rozmiar tablicy, wypisze rozmiar pierwszego elementu.
źródło
W języku programowania 'C' 'sizeof ()' jest operatorem i zwraca rozmiar obiektu w bajtach.Argument operatora 'sizeof ()' musi być lewostronnym typem (liczba całkowita, liczba zmiennoprzecinkowa, struktura, tablica Więc jeśli chcesz poznać rozmiar tablicy w bajtach, możesz to zrobić bardzo prosto, po prostu użyj operatora `` sizeof () '', a jako argumentu użyj nazwy tablicy, na przykład:
Wynik w systemie 32-bitowym będzie wyglądał następująco: Rozmiar n wynosi: 40, ponieważ ineteger w systemie 32 to 4 bajty, w przypadku 64x jest to 8 bajtów, w tym przypadku mamy 10 liczb całkowitych zadeklarowanych w jednej tablicy. int) ”.
Kilka porad:
Jeśli mamy zadeklarowaną tablicę taką jak ta 'int n [] = {1, 2, 3, ... 155 ..};'. Chcemy więc wiedzieć, ile elementów jest przechowywanych w tej tablicy. Użyj tego algorytmu:
sizeof (name_of_the_array) / sizeof (array_type)
Kod: #include
Główny(){
}
źródło
sizeof(n)
zmienną lokalną asizeof(arg)
argumentem funkcji, mimo że oba wydają się być typuint[10]
.Tablice mają tylko luźne rozmiary. W większości przypadków tablica jest wskaźnikiem do pamięci. Rozmiar w deklaracji mówi kompilatorowi tylko, ile pamięci należy przeznaczyć na tablicę - nie jest powiązany z typem, więc sizeof () nie ma nic do roboty.
źródło