Gå til innhold

Funksjon som skriver ut vilkårlig langt array


Anbefalte innlegg

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 av codemonkey
Lenke til kommentar
Videoannonse
Annonse

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 av einaros
Lenke til kommentar

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

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 && ./a

We 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 :D

Endret av lnostdal
Lenke til kommentar

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...