Hur bestäms längden på en matris i C?


Bästa svaret

Det är lite oklart vad du frågar, men jag antar att frågan är den som ges en matris , hur bestämmer du dess längd.

C har flera typer av matriser: matriser av okänd storlek, matriser med känd konstant storlek och matriser med variabel längd.

För en matris med konstant storlek är storleken en del av sin typ: längden på en matris vars typ är int[10] är den mycket 10. C har ingen mekanism för att extrahera det direkt från typen (till skillnad från C ++ ), men du kan göra det indirekt genom storlek:

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

Storleken på en array med variabel längd kan också beräknas med sizeof med identisk kod. I så fall körs det vid körning:

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

int a[x];

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

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

Slutligen har matriser med okänd gräns, per definition okänd storlek. Du måste få det genom programlogiken

extern int a[];

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

En varning, naturligtvis, nakna matriser i C kan inte överföras till funktioner, och därför måste storlekar beräknas på den som ringer och skickas separat:

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

medlemsarrayer kan naturligtvis skickas till funktioner efter värde:

struct a10 {int a[10];};

void f(struct a10 s) {

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

}

Svar

En stor fråga är om du ska söka flera gånger? Bygg i så fall en hashtabell eller annat index en gång för att hitta saker snabbt. En hash-tabell kan genereras samtidigt som data läses från disk (om det är där de kommer ifrån).

Om det här är en engångs sak och data laddas från disk, gör sökningen överlappade med IO. Två eller fler buffertar kan användas.

En annan fråga är om du bara är intresserad av att veta om något finns, eller finns det tillhörande data du vill hämta? Om du bara vill veta om ett nummer finns kan en bitmatris användas för en mer kompakt representation.

Bortsett från det är inline C-kod som använder den snabbaste jämförelsen bäst; Använd alla optimeringsalternativ som kompilatorn erbjuder. Vissa kompilatorer kan generera samma snabbkod oavsett om du använder pekare, räknare eller indexering:

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

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

eller

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

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

eller

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

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

Du kanske tycker att det är fusk att be kompilatorn att mata ut källan för samlare för att få en uppfattning om vad den gör, men mindre kompilatorer kan kräva det om du verkligen är orolig för prestanda - bara för att se vilken form av C-kod som genereras det bästa resultatet.

Sedan finns det andra saker du kan göra som att använda flera trådar: Om du har 8 kärnor tillgängliga kan du dela upp matrisen i åtta sektioner och starta en tråd för varje sektion. Men kostnaden för att starta trådarna kan bli för hög om jämförelsekostnaden är låg.

Matrisen kan vara stor, så byte av virtuellt minne kan sakta ner. Genom att använda din egen minneskartade filbaksida kan du styra mappning och avmappning för att hålla den fysiska minnesanvändningen låg. Du kan avbilda ett avsnitt som du just avslutat sökningen så att minnet kan användas för senare avsnitt.

Bara några idéer. Lycka till.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *