Hoe wordt de lengte van een array in C bepaald?


Beste antwoord

Het is enigszins onduidelijk wat je vraagt, maar ik neem aan dat de vraag is dat gegeven een array , hoe bepaal je de lengte.

C heeft verschillende soorten arrays: arrays van onbekende grootte, arrays met bekende constante grootte en arrays met variabele lengte.

Voor een array van constante grootte, de grootte maakt deel uit van het type: de lengte van een array waarvan het type int[10] is, is precies die 10. C heeft geen mechanisme om dat rechtstreeks uit het type te extraheren (in tegenstelling tot C ++ ), maar je kunt het indirect doen via sizeof:

int a[] = {1,2,3,4,5,6,7,8,9,0};

size\_t sz = sizeof a / sizeof *a; // or .../sizeof a[0], same thing

printf("size = \%zu\n", sz);

De grootte van een array met variabele lengte kan ook worden berekend met sizeof, met identieke code. In dat geval wordt het uitgevoerd tijdens runtime:

scanf("\%d", &x);

int a[x];

size\_t sz = sizeof a / sizeof *a;

printf("size = \%zu\n", sz);

Ten slotte hebben arrays met onbekende gebonden, per definitie onbekende grootte. Je zou het door de programmalogica moeten halen.

extern int a[];

size\_t sz = something\_from\_the\_module\_that\_defines\_a();

Een voorbehoud is natuurlijk dat naakte arrays in C niet kunnen worden doorgegeven aan functies, en daarom moeten de maten worden berekend aan de kant van de beller en afzonderlijk worden doorgegeven:

void f(int *a, size\_t sz);

int a[] = {1,2,3,4,5,6,7,8,9,0};

f(a, sizeof a / sizeof *a);

lidarrays kunnen natuurlijk op waarde in functies worden doorgegeven:

struct a10 {int a[10];};

void f(struct a10 s) {

size\_t sz = sizeof s.a / sizeof *s.a;

}

Antwoord

Een belangrijke vraag is: zult u meerdere keren zoeken? Als dat het geval is, bouw dan een keer een hashtabel of andere index om dingen snel te vinden. Een hashtabel kan worden gegenereerd op hetzelfde moment dat de gegevens van de schijf worden gelezen (als dat is waar ze vandaan komen).

Als dit een eenmalig iets is en gegevens van schijf worden geladen, doe dit dan het zoeken overlapt met de IO. Er kunnen 2 of meer buffers worden gebruikt.

Een andere vraag is: ben je alleen geïnteresseerd om te weten of er iets aanwezig is, of zijn er bijbehorende gegevens die je wilt ophalen? Als je alleen wilt weten of een getal aanwezig is, kan een bit-array worden gebruikt voor een compactere weergave.

Afgezien daarvan is inline C-code met de snelste vergelijking het beste; Gebruik alle optimalisatie-opties die de compiler biedt. Sommige compilers kunnen dezelfde snelle code genereren, ongeacht of u pointers, counters of indexering gebruikt:

int * first = ..., * last = ...;

for ( ; first <= last; ++first ) if ( *first == target ) ...

of

int * first = ..., count = ...;

for ( ; count-- > 0; ++first ) if ( *first == target ) ...

of

int * first = ..., count = ..., index = ...;

for ( ; index < count; ++index ) if ( first[index] == target ) ...

Je zou het als vals kunnen beschouwen om de compiler te vragen de assemblerbron uit te voeren om een ​​idee te krijgen wat het doet, maar kleinere compilers hebben het misschien nodig als je je echt zorgen maakt over de prestaties - gewoon om te zien welke vorm van C-code genereert het beste resultaat.

Dan zijn er nog andere dingen die u kunt doen, zoals het gebruik van meerdere threads: Als u 8 cores beschikbaar heeft, kunt u de array in 8 secties splitsen en voor elke sectie een thread starten. Maar de kosten voor het starten van de threads kunnen te hoog zijn als de vergelijkingskosten laag zijn.

De array kan groot zijn, dus het wisselen van virtueel geheugen kan de zaken vertragen. Als u uw eigen geheugen toegewezen bestandsback-up gebruikt, kunt u het in kaart brengen en de toewijzing zelf ongedaan maken om het fysieke geheugengebruik laag te houden. U kunt de map van een sectie die u zojuist hebt doorzocht ongedaan maken, zodat het geheugen kan worden gebruikt voor latere secties.

Slechts enkele ideeën. Veel succes.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *