Cum se determină lungimea unui tablou în C?


Cel mai bun răspuns

Este puțin clar ce întrebați, dar presupun că întrebarea este aceea că dat un tablou , cum îi determinați lungimea.

C are mai multe tipuri de tablouri: tablouri de dimensiuni necunoscute, tablouri cu dimensiuni constante cunoscute și tablouri cu lungime variabilă.

Pentru o matrice de dimensiunea constantă, dimensiunea face parte din tipul său: lungimea unui tablou al cărui tip este int[10] este chiar 10. C nu are mecanism pentru extragerea acestuia direct din tip (spre deosebire de C ++ ), dar o puteți face indirect prin 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);

Dimensiunea unui tablou cu lungime variabilă poate fi calculată și cu sizeof, cu cod identic. În acest caz, se execută la runtime:

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

int a[x];

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

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

În cele din urmă, matricile de legături necunoscute au, prin definiție, dimensiune necunoscută. Ar trebui să îl obțineți prin logica programului

extern int a[];

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

O avertisment, desigur, matricile goale din C nu pot fi transmise funcțiilor, astfel încât dimensiunile trebuie calculate din partea apelantului și transmise 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);

matricile de membri pot fi desigur transmise în funcții după valoare:

struct a10 {int a[10];};

void f(struct a10 s) {

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

}

Răspuns

O întrebare majoră este că veți căuta de mai multe ori? Dacă da, atunci construiți o tabelă hash sau alt index pentru a găsi lucrurile rapid. Un tabel hash ar putea fi generat în același timp în care datele sunt citite de pe disc (dacă de aici provin).

Dacă acesta este un lucru unic și datele sunt încărcate de pe disc, faceți căutarea s-a suprapus cu IO. Ar putea fi folosite 2 sau mai multe buffere.

O altă întrebare este că sunteți doar interesat să știți dacă este prezent ceva sau există date asociate pe care doriți să le recuperați? Dacă doriți doar să știți dacă este prezent un număr, ar putea fi utilizată o matrice de biți pentru o reprezentare mai compactă.

În afară de aceasta, codul C inline care utilizează cea mai rapidă comparație este cel mai bun; Utilizați toate opțiunile de optimizare oferite de compilator. Unele compilatoare pot genera același cod rapid, indiferent dacă utilizați pointeri, contoare sau indexare:

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

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

sau

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

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

sau

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

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

S-ar putea să considerați înșelător să cereți compilatorului să producă sursa de asamblare pentru a-și face o idee despre ceea ce face, dar compilatoarele mai mici ar putea să o solicite dacă sunteți cu adevărat îngrijorat de performanță - doar pentru a vedea ce formă de cod C generează cel mai bun rezultat.

Apoi există și alte lucruri pe care le puteți face, cum ar fi utilizarea mai multor fire: Dacă aveți 8 nuclee disponibile, puteți împărți matricea în 8 secțiuni și puteți lansa un fir pentru fiecare secțiune. Dar costul pornirii firelor poate fi prea mare dacă costul comparației este mic.

Matricea ar putea fi mare, astfel încât schimbarea memoriei virtuale ar putea încetini lucrurile. Folosirea propriului suport de fișiere cartografiate de memorie vă poate permite să controlați cartografierea și dezactivarea cartografiei pentru a menține utilizarea fizică a memoriei scăzută. Puteți anula harta unei secțiuni pe care tocmai ați terminat de căutat, astfel încât memoria să poată fi folosită pentru secțiunile ulterioare.

Doar câteva idei. Mult noroc.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *