Hoe bepaal ik de grootte van mijn array in C?

Hoe bepaal ik de grootte van mijn array in C?

Dat wil zeggen, het aantal elementen dat de array kan bevatten?


Antwoord 1, autoriteit 100%

Samenvatting:

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

Volledig antwoord:

Om de grootte van uw array in bytes te bepalen, kunt u de sizeof . gebruiken
operator:

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

Op mijn computer zijn ints 4 bytes lang, dus n is 68.

Om het aantal elementen in de array te bepalen, kunnen we delen
de totale grootte van de array door de grootte van het array-element.
Je zou dit kunnen doen met het type, zoals dit:

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

en krijg het juiste antwoord (68 / 4 = 17), maar als het type
a gewijzigd u zou een vervelende bug krijgen als u vergat te wijzigen
ook de sizeof(int).

De voorkeursdeler is dus sizeof(a[0]) of de equivalente sizeof(*a), de grootte van het eerste element van de array.

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

Een ander voordeel is dat u nu gemakkelijk parameters kunt instellen
de arraynaam in een macro en krijg:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))
int a[17];
size_t n = NELEMS(a);

Antwoord 2, autoriteit 63%

De sizeof manier is de juiste manier iff je hebt te maken met arrays die niet als parameters worden ontvangen. Een array die als parameter naar een functie wordt verzonden, wordt behandeld als een aanwijzer, dus sizeof retourneert de grootte van de aanwijzer in plaats van die van de array.

Dus binnen functies werkt deze methode niet. Geef in plaats daarvan altijd een extra parameter size_t size door die het aantal elementen in de array aangeeft.

Testen:

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

Uitvoer (in een 64-bits Linux-besturingssysteem):

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

Uitvoer (in een 32-bits Windows-besturingssysteem):

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

Antwoord 3, autoriteit 10%

Het is vermeldenswaard dat sizeof niet helpt bij het omgaan met een arraywaarde die is vervallen tot een pointer: hoewel deze naar het begin van een array verwijst, is het voor de compiler de hetzelfde als een aanwijzer naar een enkel element van die array. Een aanwijzer “onthoudt” niets anders over de array die werd gebruikt om hem te initialiseren.

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

Antwoord 4, autoriteit 4%

De sizeof "truc" is de beste manier die ik ken, met één kleine maar (voor mij is dit een grote ergernis) belangrijke verandering in het gebruik van haakjes.

Zoals het Wikipedia-item duidelijk maakt, is de sizeof van C geen functie; het is een operator. Het vereist dus geen haakjes rond het argument, tenzij het argument een typenaam is. Dit is gemakkelijk te onthouden, omdat het argument er dan uitziet als een cast-uitdrukking, die ook haakjes gebruikt.

Dus: als je het volgende hebt:

int myArray[10];

Je kunt het aantal elementen met code als volgt vinden:

size_t n = sizeof myArray / sizeof *myArray;

Dat leest voor mij een stuk makkelijker dan het alternatief met haakjes. Ik ben ook voorstander van het gebruik van de asterisk in het rechterdeel van de divisie, omdat het beknopter is dan indexeren.

Natuurlijk is dit ook allemaal compileertijd, dus je hoeft je geen zorgen te maken over de verdeling die de prestaties van het programma beïnvloedt. Gebruik dit formulier dus waar je maar kunt.

Het is altijd het beste om sizeof te gebruiken op een echt object als je er een hebt, in plaats van op een type, omdat je je dan geen zorgen hoeft te maken over het maken van een fout en het vermelden van het verkeerde type .

Stel bijvoorbeeld dat u een functie hebt die bepaalde gegevens als een stroom van bytes uitvoert, bijvoorbeeld via een netwerk. Laten we de functie send() aanroepen, en als argumenten een pointer naar het te verzenden object en het aantal bytes in het object als argumenten gebruiken. Het prototype wordt dus:

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

En dan moet je een geheel getal verzenden, dus je codeert het als volgt:

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

Je hebt nu een subtiele manier geïntroduceerd om jezelf in de voet te schieten, door het type foo op twee plaatsen te specificeren. Als de ene verandert, maar de andere niet, breekt de code. Doe het dus altijd als volgt:

send(&foo, sizeof foo);

Nu ben je beschermd. Natuurlijk dupliceer je de naam van de variabele, maar de kans is groot dat deze kapot gaat op een manier die de compiler kan detecteren, als je deze wijzigt.


Antwoord 5, autoriteit 3%

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

Bekijk deze link voor uitleg


Antwoord 6, autoriteit 2%

Ik zou adviseren om nooit sizeof te gebruiken (zelfs als het kan worden gebruikt) om een ​​van de twee verschillende groottes van een array te krijgen, hetzij in aantal elementen of in bytes, wat zijn de laatste twee gevallen die ik hier laat zien. Voor elk van de twee maten kunnen de onderstaande macro’s worden gebruikt om het veiliger te maken. De reden is om de bedoeling van de code duidelijk te maken aan beheerders, en het verschil sizeof(ptr) van sizeof(arr) op het eerste gezicht (wat op deze manier geschreven is niet duidelijk), zodat bugs dan duidelijk zijn voor iedereen die de code leest.


TL;DR:

#define ARRAY_SIZE(arr)     (sizeof(arr) / sizeof((arr)[0]) + must_be_array(arr))
#define ARRAY_SSIZE(arr)    ((ptrdiff_t)ARRAY_SIZE(arr))
#define ARRAY_BYTES(arr)    (sizeof(arr) + must_be_array(arr))
#define ARRAY_SBYTES(arr)   ((ssize_t)ARRAY_BYTES(arr))

must_be_array(arr) (hieronder gedefinieerd) IS nodig als -Wsizeof-pointer-div bevat fouten (per april/2020):

#define is_same_type(a, b)  __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr)       (!is_same_type((arr), &(arr)[0]))
#define must_be(e, ...)     (                               \
        0 * (int)sizeof(                                                \
                struct {                                                \
                        _Static_assert((e)  __VA_OPT__(,)  __VA_ARGS__);\
                        char ISO_C_forbids_a_struct_with_no_members__;  \
                }                                                       \
        )                                                               \
)
#define must_be_array(arr)  must_be(is_array(arr), "Not a `[]` !")

Er zijn belangrijke bugs opgetreden met betrekking tot dit onderwerp: https://lkml.org/lkml /2015/9/3/428

Ik ben het niet eens met de oplossing die Linus biedt, namelijk om nooit array-notatie te gebruiken voor parameters van functies.

Ik hou van array-notatie als documentatie dat een pointer als array wordt gebruikt. Maar dat betekent dat er een onfeilbare oplossing moet worden toegepast, zodat het onmogelijk is om buggy-code te schrijven.

Van een array hebben we drie formaten die we misschien willen weten:

  • De grootte van de elementen van de array
  • Het aantal elementen in de array
  • De grootte in bytes die de array in het geheugen gebruikt

De grootte van de elementen van de array

De eerste is heel eenvoudig, en het maakt niet uit of we te maken hebben met een array of een pointer, omdat het op dezelfde manier wordt gedaan.

Voorbeeld van gebruik:

void foo(ptrdiff_t nmemb, int arr[static nmemb])
{
        qsort(arr, nmemb, sizeof(arr[0]), cmp);
}

qsort() heeft deze waarde nodig als derde argument.


Voor de andere twee formaten, die het onderwerp van de vraag zijn, willen we er zeker van zijn dat we te maken hebben met een array, en de compilatie breken als dat niet het geval is, want als we te maken hebben met een aanwijzer, zullen we verkeerde waarden krijgen. Als de compilatie kapot is, kunnen we gemakkelijk zien dat we niet met een array te maken hadden, maar met een aanwijzer, en hoeven we alleen de code te schrijven met een variabele of een macro die de grootte van de array achter de aanwijzer.


Het aantal elementen in de array

Dit is de meest voorkomende, en veel antwoorden hebben je de typische macro ARRAY_SIZE opgeleverd:

#define ARRAY_SIZE(arr)     (sizeof(arr) / sizeof((arr)[0]))

Aangezien het resultaat van ARRAY_SIZE vaak wordt gebruikt met ondertekende variabelen van het type ptrdiff_t, is het goed om een ​​ondertekende variant van deze macro te definiëren:

#define ARRAY_SSIZE(arr)    ((ptrdiff_t)ARRAY_SIZE(arr))

Arrays met meer dan PTRDIFF_MAX leden zullen ongeldige waarden geven voor deze ondertekende versie van de macro, maar na het lezen van C17::6.5.6.9 spelen dergelijke arrays al met vuur. Alleen ARRAY_SIZE en size_t mogen in die gevallen worden gebruikt.

Recente versies van compilers, zoals GCC 8, zullen u waarschuwen wanneer u deze macro toepast op een aanwijzer, dus het is veilig (er zijn andere methoden om het veilig te maken met oudere compilers).

Het werkt door de grootte in bytes van de hele array te delen door de grootte van elk element.

Voorbeelden van gebruik:

void foo(ptrdiff_t nmemb)
{
        char buf[nmemb];
        fgets(buf, ARRAY_SIZE(buf), stdin);
}
void bar(ptrdiff_t nmemb)
{
        int arr[nmemb];
        for (ptrdiff_t i = 0; i < ARRAY_SSIZE(arr); i++)
                arr[i] = i;
}

Als deze functies geen arrays gebruikten, maar ze in plaats daarvan als parameters kregen, zou de vorige code niet compileren, dus het zou onmogelijk zijn om een ​​bug te hebben (aangezien er een recente compilerversie wordt gebruikt, of een andere truc wordt gebruikt), en we moeten de macro-aanroep vervangen door de waarde:

void foo(ptrdiff_t nmemb, char buf[nmemb])
{
        fgets(buf, nmemb, stdin);
}
void bar(ptrdiff_t nmemb, int arr[nmemb])
{
        for (ptrdiff_t i = 0; i < nmemb; i++)
                arr[i] = i;
}

De grootte in bytes die de array in het geheugen gebruikt

ARRAY_SIZE wordt vaak gebruikt als oplossing voor het vorige geval, maar dit geval wordt zelden veilig geschreven, misschien omdat het minder vaak voorkomt.

De gebruikelijke manier om deze waarde te verkrijgen is door sizeof(arr) te gebruiken. Het probleem: hetzelfde als bij de vorige; als je een pointer hebt in plaats van een array, wordt je programma gek.

De oplossing voor het probleem is het gebruik van dezelfde macro als voorheen, waarvan we weten dat het veilig is (het verbreekt de compilatie als het op een aanwijzer wordt toegepast):

#define ARRAY_BYTES(arr)        (sizeof((arr)[0]) * ARRAY_SIZE(arr))

Aangezien het resultaat van ARRAY_BYTES soms wordt vergeleken met de uitvoer van functies die ssize_t retourneren, is het goed om een ​​ondertekende variant van deze macro te definiëren:

#define ARRAY_SBYTES(arr)   ((ssize_t)ARRAY_BYTES(arr))

Hoe het werkt is heel eenvoudig: het maakt de verdeling ongedaan die ARRAY_SIZE doet, dus na wiskundige annuleringen heb je slechts één sizeof(arr), maar met de extra veiligheid van de ARRAY_SIZE constructie.

Voorbeeld van gebruik:

void foo(ptrdiff_t nmemb)
{
        int arr[nmemb];
        memset(arr, 0, ARRAY_BYTES(arr));
}

memset() heeft deze waarde nodig als derde argument.

Zoals eerder, als de array wordt ontvangen als een parameter (een pointer), wordt deze niet gecompileerd en moeten we de macro-aanroep vervangen door de waarde:

void foo(ptrdiff_t nmemb, int arr[nmemb])
{
        memset(arr, 0, sizeof(arr[0]) * nmemb);
}

Update (23/apr/2020): -Wsizeof-pointer-div heeft fouten:

Vandaag kwam ik erachter dat de nieuwe waarschuwing in GCC alleen werkt als de macro is gedefinieerd in een header die geen systeemheader is. Als u de macro definieert in een header die in uw systeem is geïnstalleerd (meestal /usr/local/include/ of /usr/include/) (#include <foo.h>), zal de compiler GEEN waarschuwing geven (ik heb GCC 9.3.0 geprobeerd).

Dus we hebben #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) en willen het veilig maken. We hebben C11 _Static_assert() en enkele GCC-extensies nodig: Verklaringen en verklaringen in uitdrukkingen, __builtin_types_compatible_p :

#define is_same_type(a, b)      __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr)           (!is_same_type((arr), &(arr)[0]))
#define Static_assert_array(arr) _Static_assert(is_array(arr), "Not a `[]` !")
#define ARRAY_SIZE(arr)         (                                       \
{                                                                       \
        Static_assert_array(arr);                                       \
        sizeof(arr) / sizeof((arr)[0]);                                 \
}                                                                       \
)

Nu is ARRAY_SIZE() volkomen veilig, en daarom zijn al zijn afgeleiden veilig.


Update: libbsd biedt __arraycount():

Libbsd levert de macro __arraycount() in <sys/cdefs.h>, wat onveilig omdat het een paar haakjes mist, maar we kunnen die haakjes zelf toevoegen, en daarom hoeven we niet eens de divisie in onze koptekst te schrijven (waarom zouden we code dupliceren die al bestaat?). Die macro is gedefinieerd in een systeemkop, dus als we hem gebruiken, zijn we genoodzaakt de bovenstaande macro’s te gebruiken.

#include <stddef.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#define is_same_type(a, b)      __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr)           (!is_same_type((arr), &(arr)[0]))
#define Static_assert_array(arr) _Static_assert(is_array(arr), "Not a `[]` !")
#define ARRAY_SIZE(arr)         (                                       \
{                                                                       \
        Static_assert_array(arr);                                       \
        __arraycount((arr));                                            \
}                                                                       \
)
#define ARRAY_SSIZE(arr)        ((ptrdiff_t)ARRAY_SIZE(arr))
#define ARRAY_BYTES(arr)        (sizeof((arr)[0]) * ARRAY_SIZE(arr))
#define ARRAY_SBYTES(arr)       ((ssize_t)ARRAY_BYTES(arr))

Sommige systemen bieden nitems() in <sys/param.h>, en sommige systemen bieden beide. U moet uw systeem controleren en het systeem gebruiken dat u heeft, en misschien enkele preprocessor-voorwaarden gebruiken voor draagbaarheid en beide ondersteunen.


Update: Sta toe dat de macro wordt gebruikt op bestandsbereik:

Helaas kan de gcc-extensie ({}) niet worden gebruikt in het bestandsbereik.
Om de macro op bestandsbereik te kunnen gebruiken, moet de statische bewering:
binnen sizeof(struct {}). Vermenigvuldig het vervolgens met 0 om geen invloed te hebben
het resultaat. Een cast naar (int) kan goed zijn om een ​​functie te simuleren
dat geeft (int)0 terug (in dit geval is het niet nodig, maar dan wel
is herbruikbaar voor andere dingen).

Bovendien kan de definitie van ARRAY_BYTES() een beetje worden vereenvoudigd.

#include <stddef.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#define is_same_type(a, b)     __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr)          (!is_same_type((arr), &(arr)[0]))
#define must_be(e, ...)        (                                        \
        0 * (int)sizeof(                                                \
                struct {                                                \
                        _Static_assert((e)  __VA_OPT__(,)  __VA_ARGS__);\
                        char ISO_C_forbids_a_struct_with_no_members__;  \
                }                                                       \
        )                                                               \
)
#define must_be_array(arr)      must_be(is_array(arr), "Not a `[]` !")
#define ARRAY_SIZE(arr)         (__arraycount((arr)) + must_be_array(arr))
#define ARRAY_SSIZE(arr)        ((ptrdiff_t)ARRAY_SIZE(arr))
#define ARRAY_BYTES(arr)        (sizeof(arr) + must_be_array(arr))
#define ARRAY_SBYTES(arr)       ((ssize_t)ARRAY_BYTES(arr))

Opmerkingen:

Deze code maakt gebruik van de volgende extensies, die absoluut noodzakelijk zijn en hun aanwezigheid absoluut noodzakelijk is om veiligheid te bereiken. Als uw compiler ze niet heeft, of soortgelijke, kunt u dit veiligheidsniveau niet bereiken.

Ik maak ook gebruik van de volgende C11-functie. Het ontbreken ervan kan echter worden verholpen door een oudere standaard te gebruiken met behulp van enkele vuile trucs (zie bijvoorbeeld: Wat is :-!! in C-code?).

Ik gebruik ook de volgende extensie, maar er is een standaard C-manier om hetzelfde te doen.


Antwoord 7, autoriteit 2%

Je kunt de operator sizeof gebruiken, maar het werkt niet voor functies omdat het de referentie van de aanwijzer nodig heeft
je kunt het volgende doen om de lengte van een array te vinden:

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

Code oorspronkelijk hier gevonden:
C-programma om het aantal elementen in een array te vinden


Antwoord 8, autoriteit 2%

Als u het gegevenstype van de array weet, kunt u zoiets gebruiken als:

int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22};
int noofele = sizeof(arr)/sizeof(int);

Of als u het gegevenstype van de array niet weet, kunt u zoiets gebruiken als:

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

Opmerking: dit werkt alleen als de array niet tijdens runtime is gedefinieerd (zoals malloc) en als de array niet in een functie wordt doorgegeven. In beide gevallen is arr (arraynaam) een pointer.


Antwoord 9

De macro ARRAYELEMENTCOUNT(x) die iedereen gebruikt, evalueert onjuist. Dit is, realistisch gezien, slechts een gevoelige kwestie, omdat je geen uitdrukkingen kunt hebben die resulteren in een ‘array’-type.

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

Eigenlijk evalueert als:

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

Terwijl

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

Het evalueert correct naar:

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

Dit heeft echt niet veel te maken met de grootte van arrays expliciet. Ik heb zojuist veel fouten opgemerkt door niet echt te observeren hoe de C-preprocessor werkt. U wikkelt altijd de macroparameter in, er kan geen uitdrukking in betrokken zijn.


Dit klopt; mijn voorbeeld was een slecht voorbeeld. Maar dat is eigenlijk precies wat er zou moeten gebeuren. Zoals ik eerder al zei, zal p + 1 eindigen als een aanwijzertype en de hele macro ongeldig maken (net zoals wanneer je zou proberen de macro te gebruiken in een functie met een aanwijzerparameter).

Uiteindelijk, in dit specifieke geval, doet de fout er niet echt toe (dus ik verspil gewoon ieders tijd; huzzah!), omdat je geen uitdrukkingen hebt met een soort ‘array’. Maar ik denk dat het punt over de subtiele preprocessor-evaluatie een belangrijk punt is.


Antwoord 10

Voor multidimensionale arrays is het iets ingewikkelder. Vaak definiëren mensen expliciete macroconstanten, bijv.

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

Maar deze constanten kunnen ook tijdens het compileren worden geëvalueerd met 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);

Merk op dat deze code werkt in C en C++. Gebruik voor arrays met meer dan twee dimensies

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

enz., tot in het oneindige.


Antwoord 11

Grootte van een 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

Antwoord 12

sizeof(array) / sizeof(array[0])

Antwoord 13

“je hebt een subtiele manier geïntroduceerd om jezelf in de voet te schieten”

C ‘native’ arrays slaan hun grootte niet op. Het wordt daarom aanbevolen om de lengte van de array op te slaan in een aparte variabele/const, en deze door te geven wanneer je de array passeert, dat wil zeggen:

#define MY_ARRAY_LENGTH   15
int myArray[MY_ARRAY_LENGTH];

Je MOET altijd native arrays vermijden (tenzij je dat niet kunt, in welk geval, let op je voet). Als je C++ schrijft, gebruik dan de STL‘s ‘vector’ container. “Vergeleken met arrays bieden ze bijna dezelfde prestaties”, en ze zijn veel nuttiger!

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

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


Antwoord 14

#define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))

Antwoord 15

Als je dit echt wilt doen om je array door te geven, raad ik aan een structuur te implementeren om een ​​aanwijzer op te slaan naar het type waarvan je een array wilt en een geheel getal dat de grootte van de array vertegenwoordigt. Dan kunt u dat doorgeven aan uw functies. Wijs de waarde van de arrayvariabele (aanwijzer naar eerste element) toe aan die aanwijzer. Dan kun je naar Array.arr[i] gaan om het i-th element te krijgen en Array.size gebruiken om het aantal elementen in de array te krijgen.

Ik heb wat code voor je toegevoegd. Het is niet erg handig, maar je zou het kunnen uitbreiden met meer functies. Maar om eerlijk te zijn, als dit de dingen zijn die je wilt, moet je stoppen met het gebruik van C en een andere taal gebruiken met deze ingebouwde functies.

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

Antwoord 16

De beste manier is om deze informatie op te slaan, bijvoorbeeld in een structuur:

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

Implementeer alle noodzakelijke functies zoals creëren, vernietigen, gelijkheid controleren en al het andere dat u nodig hebt. Het is gemakkelijker om als parameter door te geven.


Antwoord 17

De functie sizeof retourneert het aantal bytes dat door uw array in het geheugen wordt gebruikt. Als je het aantal elementen in je array wilt berekenen, moet je dat aantal delen door het variabele type sizeof van de array. Laten we zeggen int array[10];, als het variabele type integer in uw computer 32 bit (of 4 bytes) is, om de grootte van uw array te krijgen, moet u het volgende doen:

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

Antwoord 18

U kunt de operator & gebruiken. Hier is de broncode:

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

Hier is de voorbeelduitvoer

1549216672
1549216712
---- diff----
4
The size of array a is 10

Antwoord 19

Het eenvoudigste antwoord:

#include <stdio.h>
int main(void) {
    int a[] = {2,3,4,5,4,5,6,78,9,91,435,4,5,76,7,34};//for Example only
    int size;
    size = sizeof(a)/sizeof(a[0]);//Method
    printf ("size = %d",size);
    return 0;
}

Antwoord 20

Een elegantere oplossing zal zijn

size_t size = sizeof(a) / sizeof(*a);

Antwoord 21

voor vooraf gedefinieerde array:

 int a[]={1,2,3,4,5,6};

aantal elementen in array berekenen:

 element _count =sizeof(a) / sizeof(a[0]);

Antwoord 22

Naast de reeds gegeven antwoorden, wil ik op een speciaal geval wijzen door het gebruik van

sizeof(a) / sizeof (a[0])

Als a een array is van char, unsigned char of signed char hoeft u dit niet te doen gebruik sizeof twee keer aangezien een sizeof-expressie met één operand van dit type altijd resulteert in 1.

Citaat uit C18,6.5.3.4/4:

Als sizeof wordt toegepast op een operand van het type char, unsigned char of signed char, (of een gekwalificeerde versie daarvan) het resultaat is 1.”

Dus, sizeof(a) / sizeof (a[0]) zou gelijk zijn aan NUMBER OF ARRAY ELEMENTS / 1 als a is een array van het type char, unsigned char of signed char. De deling door 1 is overbodig.

In dit geval kun je gewoon afkorten en het volgende doen:

sizeof(a)

Bijvoorbeeld:

char a[10];
size_t length = sizeof(a);

Als u een bewijs wilt, hier is een link naar GodBolt .


Desalniettemin handhaaft de divisie de veiligheid, als het type aanzienlijk verandert (hoewel deze gevallen zeldzaam zijn).


Antwoord 23

Opmerking: deze kan je ongedefinieerd gedrag geven, zoals aangegeven door M.M in de opmerking.

int a[10];
int size = (*(&a+1)-a) ;

Voor meer details zie
hier
en ook hier .

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes