Arrays als Funktionsargumente übergeben...
-
Hi.
Hatte bereits eine ähnliche Frage, da ging es jedoch um Vektoren.
Deswegen stelle ich eine leicht andere Frage hier nochmals.
Ich hoffe das ist ok, und es fühlt sich niemand auf die Füsse getreten.Ich habe einfach noch Probleme mit 'komplexeren Datenstrukturen' wie z.B. einem Array.
So möchte ich eine Funktion schreiben, welche folgendes tut, wobei ich gleich einwenden muss das ich nicht weiss wie das Funktionsargument korrekt formatiert sein muss, genau das ist nämlich meine Frage:
int get_size_of_array(int the_array[]) { return (sizeof(the_array)/sizeof(the_array[0])); }Jetzt ist es ja so, dass wenn ich ein Array erstelle, der Name des Arrays nur ein konstanter Zeiger auf das erste Element des Arrays ist.
Wenn ich also diese Funktion mit folgendemint field[256];Array aufrufe, gibt mir get_size_of_stack(field); als return Wert eine 1, was ja auch richtig ist, da ich ja den Namen der Variable, sprich also den Pointer auf das ERSTE Element übergebe.
Mich würde also interessieren wie übergebe ich das gesamte Array?
Geht das nur als Referenz(Wenn das der Fall sein sollte, wie sieht das aus?)? Dass müsste doch auch irgendwie als Zeiger gehen oder nicht? Oder geht das vielleicht GANZ anders?
Geht es überhaupt?Ich blicks leider nicht so ganz.
Wäre für eine ausführliche Erläuterung oder einen guten Link sehr dankbar!
-
int get_size_of_array(int the_array[]) { return (sizeof(the_array)/sizeof(the_array[0])); }Du kannst leider nicht mit sizeof() arbeiten, da ja für den Array ein beliebiger Pointer auf ein Array aus Integern angegeben werden kann. sizeof lässt sich nur verwenden, wenn die Größe des Arrays schon zur Kompilierzeit bekannt ist.
Wenn Du vorher die Größe des Arrays schont kennst, dann schreibe Dir lieber ein kleines Makro - damit sparst Du Dir eine Menge Ärger.
Zudem besteht das Array ja aus integern. Die Größe vom ersten Element ist also sizeof(int) = 4 (Bei 32-bit-Integern).Also könntest Du auch eigentlich nur Folgendes schreiben:
int mein_array[256]; int numArrayElements = sizeof(mein_array) / sizeof(int);Oder eben fix als Makro:
#define num_array_elements(array, type) sizeof(array)/sizeof(type) . . . int mein_array[256]; int count = num_array_elements(mein_array, int); //count = 256HTH, kann aber sein, dass ich Deine Frage falsch verstanden habe...
-
wenn du ein array hast
int arr[100];und das array verwendest, dann wird in wirklichkeit das array zuerst ausgewertet und umgewandelt in den zeiger auf's erste element. und die größeninformation ist damit verloren. nur wenige ausnahmen, wie sizeof() machen das nicht.
deswegen muss man normalerweise für funktionsaufrufe immer die arraygröße mitgeben.
also
void printAll(int *arr,int count){ for(int i=0;i<count;++i) cout<<arr[i]<<' '; }es ändert nichts daran, wenn man
void printAll(int arr[],int count){ for(int i=0;i<count;++i) cout<<arr[i]<<' '; }schreibt.
falls man nur bestimmte größen zulassen mag, darf man tricksen.
void printAll(int arr[100]){ for(int i=0;i<100;++i) cout<<arr[i]<<' '; }ok, das geht schonmal. leider nur für die größe 100.
ich will man schnell für die größen von 1 bis 100 diese funktionen schreiben.
void printAll(int arr[1]){ for(int i=0;i<1;++i) cout<<arr[i]<<' '; } void printAll(int arr[2]){ for(int i=0;i<2;++i) cout<<arr[i]<<' '; } void printAll(int arr[3]){ for(int i=0;i<3;++i) cout<<arr[i]<<' '; } ... void printAll(int arr[99]){ for(int i=0;i<99;++i) cout<<arr[i]<<' '; } void printAll(int arr[100]){ for(int i=0;i<100;++i) cout<<arr[i]<<' '; }ok, das war leicht.
nun kann ich in der main() gut statt
int a[100]; ... printAll(a,sizeof(a)/sizeof(a[0]));lieber
int a[100]; ... printAll(a);schreiben.
ein kleines probleme noch:
- ich kann damit nicht mehr dynaische arrays, also arrays, deren größe nicht zur compilezeit bekannt ist, machen.also doch dafür noch zusätzlich die version mit zwei parametern.
void printAll(int* arr,int count){ for(int i=0;i<count;++i) cout<<arr[i]<<' '; } void printAll(int arr[1]){ for(int i=0;i<1;++i) cout<<arr[i]<<' '; } void printAll(int arr[2]){ for(int i=0;i<2;++i) cout<<arr[i]<<' '; } void printAll(int arr[3]){ for(int i=0;i<3;++i) cout<<arr[i]<<' '; } ... void printAll(int arr[99]){ for(int i=0;i<99;++i) cout<<arr[i]<<' '; } void printAll(int arr[100]){ for(int i=0;i<100;++i) cout<<arr[i]<<' '; }und noch ein problem. die codegröße ist ja immens geworden. soo viele funktionen. das ist nicht ideal.
aber da kenne ich auch einen trick
void printAll(int* arr,int count){ for(int i=0;i<count;++i) cout<<arr[i]<<' '; } inline void printAll(int arr[1]){ printAll(arr,1); } inline void printAll(int arr[2]){ printAll(arr,2); } inline void printAll(int arr[3]){ printAll(arr,3); } ... inline void printAll(int arr[99]){ printAll(arr,99); } inline void printAll(int arr[100]){ printAll(arr,100); }so, das ist fein. die inline-funktionen erzeugen keinen code. sie füllen für mich nur den zweiten parameter aus, den ich nicht selber angeben mag.
hab ich eigentlich schon erwähnt, wie man ein array per referenz übergibt?
das geht so:inline void printAll(int (&arr)[100]){ printAll(arr,100); }das braucht man aber natürlich normalerweise nicht, da arrays beim übergeben ja einfach in einen zeiger auf's erste element umgewandelt werden, was genauso billig oder teuer wie eine refewrenz ist.
aber mein unterirdisches labor hat da einen trick entwickelt. man kann array-referenzen fein mit templates verbinden, um sich die 100 inline-funktionen und noch viel mehr von alleine bauen zu lassen.
void printAll(int* arr,int count){ for(int i=0;i<count;++i) cout<<arr[i]<<' '; } template<int size> inline void printAll(int (&arr)[size]){ printAll(arr,size); }und wieder kann ich
int a[100]; ... printAll(a);schreiben, und diesmal ganz ohne schlechtes gewissen. und falls der compiler die größe des arrays nicht ermitteln kann, nimmt man einfach die version mit zwei parametern.
-
Amen!

-
Daannkkeee...

Dann werde ich mich also doch mit Templates befassen müssen, ok wird jetzt gemacht!