Jak określić rozmiar tablicy w C?

Jak określić rozmiar tablicy w C?

Czyli ile elementów może pomieścić tablica?

Author: Peter Mortensen, 2008-09-01

21 answers

Streszczenie:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

Aby określić rozmiar tablicy w bajtach, możesz użyć sizeof operator:

int a[17];
size_t n = sizeof(a);

Na moim komputerze, ints mają 4 bajty, więc N wynosi 68.

Aby określić liczbę elementów w tablicy, możemy podzielić Całkowity rozmiar tablicy przez Rozmiar elementu tablicy. Można to zrobić z typem, w ten sposób:

int a[17];
size_t n = sizeof(a) / sizeof(int);

I uzyskać prawidłową odpowiedź (68 / 4 = 17), Ale jeśli Typ a zmieniony miałbyś paskudny błąd, gdyby zapomniałeś zmienić sizeof(int) również.

Więc preferowanym dzielnikiem jest sizeof(a[0]), wielkość zeruje element tablicy.

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

Kolejną zaletą jest to, że możesz teraz łatwo parametryzować nazwa tablicy w makrze I get:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);
 940
Author: Mark Harrison,
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-09-09 00:31:17

The sizeof way is the right way MFF masz do czynienia z tablicami, które nie są odbierane jako parametry. Tablica wysłana jako parametr do funkcji jest traktowana jako wskaźnik, więc sizeof zwróci rozmiar wskaźnika zamiast tablicy.

Tak więc wewnątrz funkcji ta metoda nie działa. Zamiast tego zawsze podaj dodatkowy parametr size_t size wskazujący liczbę elementów w tablicy.

Test:

#include <stdio.h>
#include <stdlib.h>

void printSizeOf(int intArray[]);
void printLength(int intArray[]);

int main(int argc, char* argv[])
{
    int array[] = { 0, 1, 2, 3, 4, 5, 6 };

    printf("sizeof of array: %d\n", (int) sizeof(array));
    printSizeOf(array);

    printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
    printLength(array);
}

void printSizeOf(int intArray[])
{
    printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}

void printLength(int intArray[])
{
    printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}

Wyjście (W 64-bitowym Linuksie OS):

sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2

Wyjście (w 32-bitowym systemie operacyjnym windows):

sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1
 640
Author: Elideb,
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
2015-06-25 22:00:46

Warto zauwaĺźyä‡, Ĺźe sizeof nie pomaga w radzeniu sobie z wartoĹ "ciÄ ... tablicy, ktĂłra zostaĹ' a zamieniona na wskaĺşnik: choÄ ‡ wskazuje na poczÄ ... tek tablicy, dla kompilatora jest ona taka sama jak wskaĺşnik na pojedynczy element tej tablicy. Wskaźnik nie "zapamiętuje" niczego innego na temat tablicy, która została użyta do jej zainicjowania.

int a[10];
int* p = a;

assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));
 106
Author: Magnus Hoff,
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-06 06:44:37

Rozmiar "sztuczki" jest najlepszym sposobem, jaki znam, z jedną małą, ale (dla mnie, to jest głównym pet peeve) ważną zmianą w użyciu nawiasu.

Jak wynika z wpisu w Wikipedii, C {[5] } nie jest funkcją; jest operatorem . W związku z tym nie wymaga nawiasu wokół swojego argumentu, chyba że argument jest nazwą typu. Jest to łatwe do zapamiętania, ponieważ sprawia, że argument wygląda jak wyrażenie cast, które również używa nawiasu.

Więc: jeśli masz po:

int myArray[10];

Możesz znaleźć liczbę elementów z kodem w następujący sposób:

size_t n = sizeof myArray / sizeof *myArray;

To, dla mnie, czyta się o wiele łatwiej niż alternatywa z nawiasem. Popieram również użycie gwiazdki w prawej części podziału, ponieważ jest bardziej zwięzła niż indeksowanie.

Oczywiście, to także czas kompilacji, więc nie ma potrzeby martwić się o podział wpływający na wydajność programu. Więc użyj tego formularza, gdzie tylko możesz.

Zawsze najlepiej używać sizeof na rzeczywistym obiekcie, gdy masz go, a nie na typie, od tego czasu nie musisz się martwić o popełnienie błędu i podanie niewłaściwego typu.

Na przykład, powiedzmy, że masz funkcję, która wysyła niektóre dane jako strumień bajtów, na przykład przez sieć. Wywołajmy funkcję send() i Sprawmy, aby jako argumenty przyjmowała wskaźnik do obiektu do wysłania oraz liczbę bajtów w obiekcie. Tak więc prototyp staje się:

void send(const void *object, size_t size);

A następnie trzeba wysłać liczbę całkowitą, więc kodujesz to tak:

int foo = 4711;
send(&foo, sizeof (int));
Wprowadziłeś subtelny sposób strzelania sobie w stopę, określając rodzaj foo w dwóch miejscach. Jeśli jedna się zmieni, a druga Nie, Kod się łamie. Tak więc zawsze rób to tak:
send(&foo, sizeof foo);
Teraz jesteś chroniony. Oczywiście, powielasz nazwę zmiennej, ale to ma duże prawdopodobieństwo złamania w sposób, który kompilator może wykryć, jeśli ją zmienisz.
 38
Author: unwind,
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
2008-10-15 10:11:57
int size = (&arr)[1] - arr;

Sprawdź TEN link {[3] } dla wyjaśnienia

 33
Author: Arjun Sreedharan,
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-01-10 08:50:34

Możesz użyć operatora sizeof, ale nie będzie on działał dla funkcji, ponieważ będzie pobierał odniesienie do wskaźnika możesz wykonać następujące czynności, aby znaleźć długość tablicy:

len = sizeof(arr)/sizeof(arr[0])

Kod pierwotnie znaleziony tutaj: C program do znajdowania liczby elementów w tablicy

 21
Author: Mohd Shibli,
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
2017-11-18 11:55:46

Jeśli znasz typ danych tablicy, możesz użyć czegoś w stylu:

int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22};

int noofele = sizeof(arr)/sizeof(int);

Lub jeśli nie znasz typu danych tablicy, możesz użyć czegoś w stylu:

noofele = sizeof(arr)/sizeof(arr[0]);

Notatka: to działa tylko wtedy, gdy tablica nie jest zdefiniowana w czasie wykonywania (jak malloc) i tablica nie jest przekazywana w funkcji. W obu przypadkach, arr (Nazwa tablicy) jest wskaźnikiem.

 19
Author: Abhitesh khatri,
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-09-08 09:32:49

Makro ARRAYELEMENTCOUNT(x), z którego korzysta każdy, błędnie ocenia . To, realistycznie, jest tylko delikatna sprawa, ponieważ nie można mieć wyrażeń, które skutkują typem 'array'.

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0]))

ARRAYELEMENTCOUNT(p + 1);

aktualnie ocenia jako:

(sizeof (p + 1) / sizeof (p + 1[0]));

]}

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0])

ARRAYELEMENTCOUNT(p + 1);

Poprawnie ocenia do:

(sizeof (p + 1) / sizeof (p + 1)[0]);

To naprawdę nie ma wiele wspólnego z wielkością tablic wprost. Właśnie zauważyłem wiele błędów z nie do końca obserwując jak C preprocesor działa. Zawsze zawijasz parametr makra, w którym nie może być zaangażowane wyrażenie.


To jest poprawne; mój przykład był zły. Ale tak właśnie powinno być. Jak już wcześniej wspomniałem p + 1 zakończy się jako typ wskaźnika i unieważni całe makro (tak jak w przypadku próby użycia makra w funkcji z parametrem wskaźnika).

Na koniec dnia, w tym konkretnym przypadku, wina naprawdę nie ma znaczenia (więc marnuję czas wszystkich; huzzah!), ponieważ nie masz wyrażeń o typie 'array'. Ale tak naprawdę punkt o ocenie preprocesora myślę, że jest ważny.

 15
Author: Peter Mortensen,
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
2017-03-09 04:31:14

Dla wielowymiarowych tablic jest to nieco bardziej skomplikowane. Często ludzie definiują jawne stałe makr, tzn.

#define g_rgDialogRows   2
#define g_rgDialogCols   7

static char const* g_rgDialog[g_rgDialogRows][g_rgDialogCols] =
{
    { " ",  " ",    " ",    " 494", " 210", " Generic Sample Dialog", " " },
    { " 1", " 330", " 174", " 88",  " ",    " OK",        " " },
};

Ale te stałe mogą być również oceniane w czasie kompilacji z sizeof :

#define rows_of_array(name)       \
    (sizeof(name   ) / sizeof(name[0][0]) / columns_of_array(name))
#define columns_of_array(name)    \
    (sizeof(name[0]) / sizeof(name[0][0]))

static char* g_rgDialog[][7] = { /* ... */ };

assert(   rows_of_array(g_rgDialog) == 2);
assert(columns_of_array(g_rgDialog) == 7);

Zauważ, że ten kod działa w C i C++. Dla tablic o więcej niż dwóch wymiarach użyj

sizeof(name[0][0][0])
sizeof(name[0][0][0][0])

Itd., ad infinitum.

 14
Author: Andreas Spindler,
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-09-08 10:25:52

Rozmiar tablicy w C:

int a[10];
size_t size_of_array = sizeof(a);      // Size of array a
int n = sizeof (a) / sizeof (a[0]);    // Number of elements in array a
size_t size_of_element = sizeof(a[0]); // Size of each element in array a                                          
                                       // Size of each element = size of type
 13
Author: Yogeesh H T,
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
2017-03-09 04:34:26
sizeof(array) / sizeof(array[0])
 11
Author: Ted Percival,
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
2008-09-01 06:50:31
#define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))
 10
Author: Andy Nugent,
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-09-12 14:54:31

"wprowadziłeś subtelny sposób strzelania sobie w stopę"

C 'natywne' tablice nie przechowują swoich rozmiarów. Dlatego zaleca się zapisanie długości tablicy w oddzielnej zmiennej / const i przekazywanie jej za każdym razem, gdy przekazujesz tablicę, czyli:

#define MY_ARRAY_LENGTH   15
int myArray[MY_ARRAY_LENGTH];

Powinieneś zawsze unikać natywnych tablic(chyba że nie możesz, w takim przypadku, uważać na stopę). Jeśli piszesz C++, użyj kontenera STL'S 'vector'. "W porównaniu do tablic, zapewniają one prawie takie same wydajność", a są one znacznie bardziej przydatne!

// vector is a template, the <int> means it is a vector of ints
vector<int> numbers;  

// push_back() puts a new value at the end (or back) of the vector
for (int i = 0; i < 10; i++)
    numbers.push_back(i);

// Determine the size of the array
cout << numbers.size();

Zobacz: http://www.cplusplus.com/reference/stl/vector/

 8
Author: Ohad,
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-09-08 09:29:56

@ Magnus: standard definiuje sizeof jako liczbę bajtów w obiekcie i że sizeof (char) jest zawsze jeden. Liczba bitów w bajcie jest specyficzna dla implementacji.

Edit: ANSI C++ standard section 5.3.3 Sizeof:

Operator sizeof otrzymuje liczbę bajtów w reprezentacji obiektu jego operandu. [...] sizeof (char), sizeof (signed char) i sizeof (unsigned char) to 1; wynik sizeof zastosowany do dowolnego innego podstawowego typu to implementacja-zdefiniowana.

Sekcja 1.6 model pamięci C++:

Podstawową jednostką pamięci w modelu pamięci C++ jest bajt. Bajt jest co najmniej wystarczająco duży, aby zawierał dowolny element podstawowego zestawu znaków wykonawczych i składa się z ciągów bitów, których liczba jest zdefiniowana w implementacji.

 5
Author: Skizz,
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
2012-07-03 14:32:40

@Skizz: jestem prawie pewien, że mam rację, chociaż najlepszym "źródłem" , jakie mogę ci w tej chwili podać, jest Wikipedia, z artykułu o sizeof:

Wikipedia się myli, Skizz ma rację. sizeof (char) z definicji wynosi 1.

Mam na myśli, po prostu przeczytaj wpis Wikipedii naprawdę uważnie , aby zobaczyć, że jest źle. "multiples of char". sizeof(char) nigdy nie może być niczym innym niż "1". Gdyby było, powiedzmy, 2, oznaczałoby to, że sizeof(char) był dwukrotnie większy od char!

 4
Author: DrPizza,
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
2013-02-28 15:05:17

Jeśli naprawdę chcesz to zrobić, aby przekazać tablicę, sugeruję zaimplementowanie struktury do przechowywania wskaźnika do typu tablicy i liczby całkowitej reprezentującej rozmiar tablicy. Następnie możesz przekazać to do swoich funkcji. Wystarczy przypisać zmienną array wartość (wskaźnik do pierwszego elementu) do tego wskaźnika. Następnie możesz przejść Array.arr[i], Aby uzyskać i-ten element i użyć Array.size, aby uzyskać liczbę elementów w tablicy.

Dodałem Ci kod. To nie jest zbyt przydatne ale możesz go rozszerzyć o więcej funkcji. Szczerze mówiąc, jeśli są to rzeczy, które chcesz, powinieneś przestać używać C i użyć innego języka z tymi funkcjami wbudowanymi.
/* Absolutely no one should use this...
   By the time you're done implementing it you'll wish you just passed around
   an array and size to your functions */
/* This is a static implementation. You can get a dynamic implementation and 
   cut out the array in main by using the stdlib memory allocation methods,
   but it will work much slower since it will store your array on the heap */

#include <stdio.h>
#include <string.h>
/*
#include "MyTypeArray.h"
*/
/* MyTypeArray.h 
#ifndef MYTYPE_ARRAY
#define MYTYPE_ARRAY
*/
typedef struct MyType
{
   int age;
   char name[20];
} MyType;
typedef struct MyTypeArray
{
   int size;
   MyType *arr;
} MyTypeArray;

MyType new_MyType(int age, char *name);
MyTypeArray newMyTypeArray(int size, MyType *first);
/*
#endif
End MyTypeArray.h */

/* MyTypeArray.c */
MyType new_MyType(int age, char *name)
{
   MyType d;
   d.age = age;
   strcpy(d.name, name);
   return d;
}

MyTypeArray new_MyTypeArray(int size, MyType *first)
{
   MyTypeArray d;
   d.size = size;
   d.arr = first;
   return d;
}
/* End MyTypeArray.c */


void print_MyType_names(MyTypeArray d)
{
   int i;
   for (i = 0; i < d.size; i++)
   {
      printf("Name: %s, Age: %d\n", d.arr[i].name, d.arr[i].age);
   }
}

int main()
{
   /* First create an array on the stack to store our elements in.
      Note we could create an empty array with a size instead and
      set the elements later. */
   MyType arr[] = {new_MyType(10, "Sam"), new_MyType(3, "Baxter")};
   /* Now create a "MyTypeArray" which will use the array we just
      created internally. Really it will just store the value of the pointer
      "arr". Here we are manually setting the size. You can use the sizeof
      trick here instead if you're sure it will work with your compiler. */
   MyTypeArray array = new_MyTypeArray(2, arr);
   /* MyTypeArray array = new_MyTypeArray(sizeof(arr)/sizeof(arr[0]), arr); */
   print_MyType_names(array);
   return 0;
}
 4
Author: Joel Dentici,
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
2013-06-13 14:37:17

Najlepszym sposobem jest zapisanie tych informacji, na przykład w strukturze:

typedef struct {
     int *array;
     int elements;
} list_s;

Zaimplementuj wszystkie niezbędne funkcje, takie jak tworzenie, niszczenie, sprawdzanie równości i wszystko inne, czego potrzebujesz. Łatwiej jest przekazać jako parametr.

 3
Author: Paulo Pinheiro,
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-02-17 14:35:27

Funkcja sizeof Zwraca liczbę bajtów używanych przez tablicę w pamięci. Jeśli chcesz obliczyć liczbę elementów w tablicy, powinieneś podzielić tę liczbę za pomocą zmiennej typu sizeof tablicy. Załóżmy, że int array[10];, jeśli zmienna typu integer w Twoim komputerze ma 32 bit (lub 4 bajty), aby uzyskać rozmiar tablicy, powinieneś wykonać następujące czynności:

int array[10];
int sizeOfArray = sizeof(array)/sizeof(int);
 3
Author: Keivan,
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-08-20 15:25:43

Możesz użyć operatora &. Oto kod źródłowy:

#include<stdio.h>
#include<stdlib.h>
int main(){

    int a[10];

    int *p; 

    printf("%p\n", (void *)a); 
    printf("%p\n", (void *)(&a+1));
    printf("---- diff----\n");
    printf("%zu\n", sizeof(a[0]));
    printf("The size of array a is %zu\n", ((char *)(&a+1)-(char *)a)/(sizeof(a[0])));


    return 0;
};

Oto Przykładowe wyjście

1549216672
1549216712
---- diff----
4
The size of array a is 10
 1
Author: Shih-En Chou,
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-06 02:42:38
 -1
Author: Pygirl,
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-07-18 01:40:23
 int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
 int len = (int) sizeof(arr) / sizeof(*arr);
 printf("%d\n", len);
 -1
Author: LinconFive,
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-09-29 06:45:26