codemonkey Skrevet 28. august 2006 Del Skrevet 28. august 2006 (endret) Hei! Jeg ønsker å lage en funksjon i C som kan skrive ut et vilkårlig langt array av en type. I den forbindelse har jeg noen spørsmål om passing av arrays, sizeof() og slikt. Pseudo-kode for hva jeg ønsker å oppnå: void print_array(double a[]) { int i; for (i = 0; i < length(a); i++) printf("%f ", a[i]); } Problemet her er å finne ut hvor lang a[] er. Jeg vet man kan gjøre double a[] = {1,2,3,4}; int length = sizeof(a)/sizeof(double) Men når jeg sender a inn til print_array er det ikke lenger mulig å gjøre sizeof(a) ser det ut til. Dette betyr vel at informasjon om lengden av a forsvinner når man sender referansen inn i en funksjon. Betyr dette at jeg er nødt til å lage grensesnittet til funksjonen slik? void print_array(double a[], int length); Håper noen kan svare meg på dette. På forhånd takk! Endret 28. august 2006 av codemonkey Lenke til kommentar
einaros Skrevet 28. august 2006 Del Skrevet 28. august 2006 (endret) Sizeof vurderes compiletime, ikke runtime. Det betyr at dersom kompilatoren ikke er i stand til å finne frem til størrelsen på arrayet, i det funksjonen din genereres til maskinkode, vil den ikke være til særlig hjelp. I dette tilfellet kan print_array kjøres på en hel del arrays, som ikke nødvendigvis deler størrelse, eller hvis størrelse avgjøres runtime. Det betyr at du må sende med størrelsen på arrayet inn til funksjonen, som du selv trekker frem som eksempel i bunnen. Endret 28. august 2006 av einaros Lenke til kommentar
codemonkey Skrevet 28. august 2006 Forfatter Del Skrevet 28. august 2006 Sizeof vurderes compiletime. Det var det jeg var redd for. Og det finnes ingen ande måter å finne ut slikt runtime? Takk for utrolig rask hjelp forresten! Lenke til kommentar
einaros Skrevet 28. august 2006 Del Skrevet 28. august 2006 Hvis dette hadde vært C++, og ikke ren C, kunne du benyttet deg av f.eks. vector, list eller deque fra STL. Dette er klasser som abstraherer standard-arrays, og tilbyr ekstra funksjonalitet som dynamisk størrelse (arrayet vokser dersom flere elementer legger til) og metoder for innsetting/uthenting/søking. Det samme kan i prinsippet gjøres i C, med de begrensninger man der har pga. manglende objektorientering, men jeg kjenner desverre ikke til noen spesifikke bibliotek. Alternativene dine koker egentlig ned til å 1. Vite størrelse for alle array funksjonen kjøres mot, og sende denne med som parameter. 2. Abstrahere arrayet, enten vha. STL i C++, eller lignende alternativer i C. 3. Innføre en termineringssekvens i alle array som funksjonen kalles på, f.eks. {0.1, 0.2, 0.3}, og stoppe utprinting når denne støtes på. Nummer 3 er en forferdelig dårlig løsning, så det er sagt. Det fører til overhead i printingen, ekstra minne allokert for hvert array, og er på ingen måte idiotsikkert -- siden stopp-sekvensen kan finnes på vilkårlig sted i hvilket som helst "naturlig" array også. Lenke til kommentar
codemonkey Skrevet 28. august 2006 Forfatter Del Skrevet 28. august 2006 1. Vite størrelse for alle array funksjonen kjøres mot, og sende denne med som parameter. Jeg får vel fortsette med denne løsningen. 2. Abstrahere arrayet, enten vha. STL i C++, eller lignende alternativer i C. Jeg kjenner til STL i C++, som er mer behagelig å jobbe med, men nå er det ren C som gjelder, og da blir det uaktuelt. Jeg vet heller ikke om liknende alternativer for C. 3. Innføre en termineringssekvens i alle array som funksjonen kalles på, f.eks. {0.1, 0.2, 0.3}, og stoppe utprinting når denne støtes på. Som du sier er dette ikke særlig trygt, da jeg ikke aner noe om hva slags verdier som kan dukke opp. Da fortsetter jeg å bruke alternativ 1, og takker så mye for hjelpen. Lenke til kommentar
lnostdal Skrevet 28. august 2006 Del Skrevet 28. august 2006 (endret) Om du absolutt - av en eller annen grunn - ikke ønsker å sende antall elementer inn som et eget argument til funksjonen, kan du gjøre det slik: #include <stdio.h> #include <stdlib.h> typedef unsigned int uint; typedef struct { int x, y; } Stuff; void printStuff(Stuff* stuff){ uint const n_stuff = *(uint*)stuff; printf("We now know that the number of items is: %d\n", n_stuff); stuff++; for(uint i = 0; i < n_stuff; i++) printf("%d %d\n", stuff[i].x, stuff[i].y);} int main(){ uint const n_stuff = 5; Stuff stuff[n_stuff + 1]; *(uint*)stuff = n_stuff; // yay - we "cheat" for(uint i = 1; i < n_stuff + 1; i++){ stuff[i].x = i * i; stuff[i].y = i + i;} printStuff(stuff); return 0;} lars@ibmr52:~/programming/c$ gcc -std=c99 -g -Wall a.c -o a && ./aWe now know that the number of items is: 5 1 2 4 4 9 6 16 8 25 10 ..men ville helt klart holdt meg til den noe (lol) mer tradisjonelle løsningen der man sender inn antall elementer som et eget argument ja. Denne ble kun satt sammen for morro; einaros kommer til å grine når han ser dette - hehe Endret 29. august 2006 av lnostdal Lenke til kommentar
lnostdal Skrevet 29. august 2006 Del Skrevet 29. august 2006 (endret) øhh .. men dere? .. jeg kom akkurat på at C99 - som ironisk nok er det jeg bruker her for å få til det stuffet i `for' har støtte for run-time sizeof-stasj, slik: edit: nope; GCC støtter ikke dette helt ennå [*] gir en advarsel om det i det minste .. sjekk http://www.informit.com/guides/content.asp...seqNum=215&rl=1 Endret 29. august 2006 av lnostdal Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå