Domanda

Come posso determinare la dimensione del mio array in C?

Cioè, quanti elementi può contenere l'array?

È stato utile?

Soluzione

Sintesi:

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

Risposta completa:

Per determinare la dimensione del tuo array in byte, puoi utilizzare il file sizeofoperatore:

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

Sul mio computer, gli int sono lunghi 4 byte, quindi n è 68.

Per determinare il numero di elementi nell'array, possiamo dividere la dimensione totale dell'array per la dimensione dell'elemento array.Potresti farlo con il tipo, in questo modo:

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

e ottieni la risposta corretta (68/4 = 17), ma se il tipo dia cambiato avresti un brutto bug se dimenticassi di cambiare il sizeof(int) anche.

Quindi il divisore preferito è sizeof(a[0]), la dimensione dell'elemento zeroeth dell'array.

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

Un altro vantaggio è che ora puoi facilmente parametrizzare il nome dell'array in una macro e ottenere:

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

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

Altri suggerimenti

IL sizeof il modo è quello giusto eff hai a che fare con array non ricevuti come parametri.Un array inviato come parametro a una funzione viene trattato come un puntatore, quindi sizeof restituirà la dimensione del puntatore, anziché quella dell'array.

Pertanto, all'interno delle funzioni questo metodo non funziona.Passare invece sempre un parametro aggiuntivo size_t size indicando il numero di elementi dell'array.

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]) ));
}

Output (in un sistema operativo Linux a 64 bit):

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

Output (in un sistema operativo Windows a 32 bit):

sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1

Vale la pena notare che sizeof non aiuta quando si ha a che fare con un valore di array che è decaduto in un puntatore:anche se punta all'inizio di un array, per il compilatore è uguale a un puntatore a un singolo elemento di quell'array.Un puntatore non "ricorda" nient'altro dell'array utilizzato per inizializzarlo.

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

assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));

La dimensione di "trucco" è il modo migliore che conosco, con un piccolo ma (per me, essendo questo un grosso problema) importante cambiamento nell'uso delle parentesi.

Come chiarisce la voce di Wikipedia, C's sizeof non è una funzione;è un operatore.Pertanto, non richiede parentesi attorno al suo argomento, a meno che l'argomento non sia un nome di tipo.Questo è facile da ricordare, poiché fa sembrare l'argomento un'espressione cast, che utilizza anche le parentesi.

COSÌ:Se hai quanto segue:

int myArray[10];

Puoi trovare il numero di elementi con codice come questo:

size_t n = sizeof myArray / sizeof *myArray;

Questo, per me, è molto più semplice dell'alternativa con parentesi.Sono inoltre favorevole all'uso dell'asterisco nella parte destra della divisione, poiché è più conciso dell'indicizzazione.

Naturalmente, anche questo è tutto in fase di compilazione, quindi non è necessario preoccuparsi che la divisione influenzi le prestazioni del programma.Quindi usa questo modulo ovunque puoi.

È sempre meglio usare sizeof su un oggetto reale quando ne hai uno, piuttosto che su un tipo, poiché in quel caso non devi preoccuparti di commettere un errore e di indicare il tipo sbagliato.

Ad esempio, supponiamo di avere una funzione che restituisce alcuni dati come flusso di byte, ad esempio attraverso una rete.Chiamiamo la funzione send(), e prendi come argomenti un puntatore all'oggetto da inviare e il numero di byte nell'oggetto.Quindi il prototipo diventa:

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

E poi devi inviare un numero intero, quindi codificalo in questo modo:

int foo = 4711;
send(&foo, sizeof (int));

Ora, hai introdotto un modo sottile di darti la zappa sui piedi, specificando il tipo di foo in due posti.Se uno cambia ma l'altro no, il codice si rompe.Quindi, fai sempre così:

send(&foo, sizeof foo);

Ora sei protetto.Certo, duplichi il nome della variabile, ma ha un'alta probabilità di rompersi in un modo che il compilatore può rilevare, se lo cambi.

int size = (&arr)[1] - arr;

Guardare questo link per spiegazione

È possibile utilizzare l'operatore sizeof ma non funzionerà per le funzioni perché richiederà il riferimento del puntatore puoi fare quanto segue per trovare la lunghezza di un array:

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

Codice originariamente trovato qui:Programma C per trovare il numero di elementi in un array

Se conosci il tipo di dati dell'array, puoi usare qualcosa come:

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

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

Oppure se non conosci il tipo di dati dell'array, puoi usare qualcosa come:

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

Nota:Questa cosa funziona solo se l'array non è definito in fase di esecuzione (come malloc) e l'array non viene passato in una funzione.In entrambi i casi, arr (nome dell'array) è un puntatore.

La macro ARRAYELEMENTCOUNT(x) che tutti utilizzano le valutazioni in modo errato.Questa, realisticamente, è solo una questione delicata, perché non è possibile avere espressioni che diano come risultato un tipo 'array'.

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

ARRAYELEMENTCOUNT(p + 1);

In realtà valuta come:

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

Mentre

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

ARRAYELEMENTCOUNT(p + 1);

Valuta correttamente:

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

Questo in realtà non ha molto a che fare esplicitamente con la dimensione degli array.Ho appena notato molti errori derivanti dal non osservare veramente come funziona il preprocessore C.Avvolgi sempre il parametro macro, in cui non potrebbe essere coinvolta un'espressione.


Questo è corretto;il mio esempio era pessimo.Ma in realtà è esattamente ciò che dovrebbe accadere.Come ho già detto in precedenza p + 1 finirà come tipo puntatore e invaliderà l'intera macro (proprio come se tentassi di utilizzare la macro in una funzione con un parametro puntatore).

In fin dei conti, in questo particolare ad esempio, la colpa non ha molta importanza (quindi sto solo facendo perdere tempo a tutti;huzzah!), perché non hai espressioni con un tipo di 'array'.Ma in realtà penso che il punto sottile sulla valutazione del preprocessore sia importante.

Per array multidimensionali è un po' più complicato.Spesso le persone definiscono costanti macro esplicite, ad es.

#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",        " " },
};

Ma queste costanti possono essere valutate anche in fase di compilazione con taglia di:

#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);

Tieni presente che questo codice funziona in C e C++.Per gli array con più di due dimensioni utilizzare

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

ecc., all'infinito.

Dimensione di un array in 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
sizeof(array) / sizeof(array[0])
#define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))

"hai introdotto un modo sottile di darti la zappa sui piedi"

Gli array C 'nativi' non memorizzano la loro dimensione.Si consiglia quindi di salvare la lunghezza dell'array in una variabile/const separata e di passarla ogni volta che si passa l'array, ovvero:

#define MY_ARRAY_LENGTH   15
int myArray[MY_ARRAY_LENGTH];

Dovresti sempre evitare gli array nativi (a meno che tu non possa, nel qual caso, fai attenzione al tuo piede).Se stai scrivendo C++, usa il file STLcontenitore 'vettore' di ."Rispetto agli array, forniscono quasi le stesse prestazioni" e sono molto più utili!

// 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();

Vedere:http://www.cplusplus.com/reference/stl/vettore/

@ Magnus:Lo standard definisce sizeof come il numero di byte nell'oggetto e che sizeof (char) è sempre uno.Il numero di bit in un byte dipende dall'implementazione.

Modificare:Standard ANSI C++ sezione 5.3.3 Dimensioni di:

L'operatore sizeof restituisce il numero di byte nella rappresentazione dell'oggetto del suo operando.[...] sizeof (char), sizeof (signed char) e sizeof (unsigned char) sono 1;il risultato di sizeof applicato a qualsiasi altro tipo fondamentale è definito dall'implementazione.

Sezione 1.6 Il modello di memoria C++:

L'unità di archiviazione fondamentale nel modello di memoria C++ è il byte.Un byte è abbastanza grande da contenere qualsiasi membro del set di caratteri di esecuzione di base ed è composto da una sequenza contigua di bit, il cui numero è definito dall'implementazione.

@Skizz:Sono abbastanza sicuro di avere ragione, anche se la migliore "fonte" che posso darti al momento è Wikipedia, dall'articolo su sizeof:

Wikipedia ha torto, Skizz ha ragione.sizeof(char) è 1, per definizione.

Intendo, basta leggere attentamente la voce di Wikipedia per vedere che è sbagliato."multipli di carattere". sizeof(char) non può mai essere niente altro diverso da "1".Se fosse, diciamo, 2, significherebbe quello sizeof(char) era due volte più grande del salmerino!

Se vuoi davvero farlo per passare il tuo array, ti suggerisco di implementare una struttura per memorizzare un puntatore al tipo di cui desideri un array e un numero intero che rappresenta la dimensione dell'array.Quindi puoi passarlo alle tue funzioni.Basta assegnare il valore della variabile dell'array (puntatore al primo elemento) a quel puntatore.Allora puoi andare Array.arr[i] per ottenere l'i-esimo elemento e utilizzarlo Array.size per ottenere il numero di elementi nell'array.

Ho incluso del codice per te.Non è molto utile ma potresti estenderlo con più funzionalità.Ad essere onesti, però, se queste sono le cose che desideri dovresti smettere di usare C e usare un altro linguaggio con queste funzionalità integrate.

/* 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;
}

Il modo migliore è salvare queste informazioni, ad esempio, in una struttura:

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

Implementa tutte le funzioni necessarie come creare, distruggere, verificare l'uguaglianza e tutto ciò di cui hai bisogno.È più semplice passarlo come parametro.

La funzione sizeof restituisce il numero di byte utilizzati dall'array in memoria.Se vuoi calcolare il numero di elementi nel tuo array, dovresti dividere quel numero per sizeof tipo di variabile dell'array.Diciamo int array[10];, se il tipo di variabile intero nel tuo computer è 32 bit (o 4 byte), per ottenere la dimensione del tuo array, dovresti fare quanto segue:

int array[10];
int sizeOfArray = sizeof(array)/sizeof(int);

Puoi usare il & operatore.Ecco il codice sorgente:

#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;
};

Ecco l'output di esempio

1549216672
1549216712
---- diff----
4
The size of array a is 10
int a[10];
int size = (*(&a+1)-a) ;

Per maggiori dettagli vedereQuie anche Qui.

Esempio

#include <stdio.h>

int main() {
    int size;
    scanf("%d", &size);
    int array[size];
    printf("%d\n", (int) (sizeof(array) / sizeof(int)));
    printf("%d\n", (int) (sizeof(array) / sizeof(array[0])));
    return 0;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top