Dlaczego rozmiar parametru array nie jest taki sam jak w main?

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));
}
Author: Lundin, 2009-12-29

13 answers

Typ tablicy jest domyślnie zamieniany na typ wskaźnika, gdy przekazujesz go do funkcji.

Więc,

void PrintSize(int p_someArray[10]) {
    printf("%zu\n", sizeof(p_someArray));
}

I

void PrintSize(int *p_someArray) {
    printf("%zu\n", sizeof(p_someArray));
}

Są równoważne. Więc to, co dostajesz, to wartość sizeof(int*)

 105
Author: Prasoon Saurav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-07 14:14:10

Jest wskaźnikiem, dlatego jest powszechną implementacją, która przekazuje rozmiar tablicy jako drugi parametr do funkcji

 20
Author: user240312,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-31 04:48:19

Jak stwierdzili 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 twój parametr nie jest w ogóle używany, więc możesz równie dobrze napisać sizeof z typem, a nie wartością.

#include <stdio.h>

void PrintSize1 ( int someArray[][10] );
void PrintSize2 ( int someArray[10] );

int main ()
{
    int myArray[10];
    printf ( "%d\n", sizeof myArray ); /* as expected 40 */
    printf ( "%d\n", sizeof ( int[10] ) ); /* requires parens */
    PrintSize1 ( 0 ); /* prints 40, does not evaluate 0[0] */
    PrintSize2 ( 0 ); /* prints 40, someArray unused */
}

void PrintSize1 ( int someArray[][10] )
{
    printf ( "%d\n", sizeof someArray[0] );
}

void PrintSize2 ( int someArray[10] )
{
    printf ( "%d\n", sizeof ( int[10] ) );
}
 16
Author: Pete Kirkham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 17:21:31

Więc będziesz musiał podać długość tablicy jako drugi parametr. Podczas pisania kodu, w którym zarówno deklarujesz tablicę o stałym rozmiarze, jak i przekazujesz ją do funkcji, trudno jest, aby stała długości tablicy wyświetlała się w kilku miejscach w kodzie...

K&R na ratunek:

#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0])) 

Więc teraz możesz zrobić np:

int a[10];
...
myfunction(a, N_ELEMENTS(a));
 12
Author: S.C. Madsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 20:09:56

Ponieważ tablice rozpadają się na wskaźniki, gdy są przekazywane jako parametry. Tak działa C, chociaż można przekazać "tablice" w C++ przez odniesienie i rozwiązać ten problem. Zauważ, że możesz przekazać tablice o różnych rozmiarach do tej funkcji:

 // 10 is superfluous here! You can pass an array of different size!
void PrintSize(int p_someArray[10]);
 5
Author: AraK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 15:15:21

W c++ można przekazać tablicę przez odniesienie do tego właśnie celu:

void foo(int (&array)[10])
{
    std::cout << sizeof(array) << "\n";
}
 5
Author: Alexandre C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-23 09:34:41

Zachowanie, które znalazłeś, jest w rzeczywistości wielką brodawką w języku C. Za każdym razem, gdy deklarujesz funkcję, która pobiera parametr tablicy, kompilator ignoruje cię i zmienia parametr na wskaźnik. Tak więc wszystkie te deklaracje zachowują się jak pierwsze:

void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)

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 pierwszego elementu. (W systemie 64-bitowym wskaźnik 64-bitowy jest dwa razy większy niż 32-bitowy int, więc rozmiar ratio zwraca 2.)

Jedynym celem tej reguły jest zachowanie wstecznej zgodności z historycznymi kompilatorami, które nie wspierały przekazywania wartości zagregowanych jako argumentów funkcji.

Nie oznacza to, że przekazanie tablicy do funkcji jest niemożliwe. Można obejść tę brodawkę, osadzając tablicę w strukturze (jest to w zasadzie cel std::array C++11):

struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0]));  /* prints 5 */
}

Lub przekazując wskaźnik do tablicy:

void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints 5 */
}

W przypadku, gdy rozmiar tablicy nie jest stałą czasu kompilacji, możesz użyć techniki pointer-to-array z tablicami o zmiennej długości C99:

void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints n */
}
 5
Author: Walter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-05 10:15:49

W języku C nie ma metody wyznaczania wielkości nieznanej tablicy, więc ilość musi być przekazywane, jak również wskaźnik do pierwszego elementu.

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 15:16:56

Nie można przekazywać tablic do funkcji.

Jeśli naprawdę chcesz wydrukować rozmiar, możesz przekazać wskaźnik do tablicy, ale nie będzie on w ogóle ogólny, ponieważ musisz również zdefiniować rozmiar tablicy dla funkcji.

#include <stdio.h>

void PrintSize(int (*p_anArray)[10]);

int main(void) {
    int myArray[10];
    printf("%d\n", sizeof(myArray)); /* as expected 40 */
    PrintSize(&myArray);/* prints 40 */
}

void PrintSize(int (*p_anArray)[10]){
    printf("%d\n", (int) sizeof(*p_anArray));
}
 3
Author: MR.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 15:44:45

Zachowanie jest projektowane.

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.

 0
Author: Pavel Radzivilovsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 15:17:23

W języku C kiedy przekazujesz tablicę jako argument do funkcji, jest ona automatycznie konwertowana na wskaźnik, tablica przechodząca z jednej funkcji inna funkcja jest znana jako wywołanie przez odniesienie . To jest powód, dla którego wywołana funkcja otrzymuje tylko wskaźnik, który wskazuje na pierwszy element funkcji to jest powód

Fun (int a[]) jest podobny do fun (int * a);

Więc po wydrukowaniu rozmiaru tablicy zostanie wydrukowany Rozmiar pierwszego elementu.

 0
Author: dagrawal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-18 09:32:31

W języku programowania' C 'operatorem jest' sizeof ()', który zwraca rozmiar obiektu w bajtach.Argument operatora' sizeof ()' musi być typu left-value(integer,float number,struct, array). więc jeśli chcesz znać rozmiar tablicy w bajtach, możesz to zrobić bardzo prosto.Wystarczy użyć operatora 'sizeof ()' i dla jego argumentu użyć nazwy tablicy.Na przykład:

#include <stdio.h>

main(){

 int n[10];
 printf("Size of n is: %d \n", sizeof(n)); 

}

Wyjście w systemie 32-bitowym będzie: Rozmiar n wynosi: 40.Bo ineteger na 32 systemie to 4bajty.Na 64x jest 8bytes.In w tym przypadku mamy 10 liczb całkowitych zadeklarowanych w jednym array.So wynikiem jest ' 10 * sizeof (int)'.

Kilka porad:

Jeśli mamy tablicę zadeklarowaną jak ta 'int N[]={1, 2, 3, ...155..};'. Chcemy więc wiedzieć ile elementów jest przechowywanych w tej tablicy. Użyj tej alghoritm:

Sizeof(name_of_the_array) / sizeof (array_type)

Kod: # include

Main () {

int n[] = { 1, 2, 3, 44, 6, 7 };
printf("Number of elements: %d \n", sizeof(n) / sizeof(int));
return 0;

}

 -1
Author: RichardGeerify,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-11 00:17:46

Tablice mają tylko luźne rozmiary. W większości przypadków tablica jest wskaźnikiem do pamięci. Rozmiar w deklaracji mówi tylko kompilatorowi, ile pamięci ma przeznaczyć na tablicę - nie jest ona powiązana z typem, więc sizeof() nie ma nic do dodania.

 -3
Author: plinth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-29 15:15:19