Frage zu Array in Funktionen
-
Hallo, wie kann ich in der Funktion ermitteln wie viele Elemente der Parameter hat ?
main() { char ar[200]; t ( ar ); return 0; } int t ( char v[] ) { char a[200]; cout<<sizeof(v)<<endl; // Gibt immer 4 aus cout<<"a: " << sizeof(a)<<endl; // Gibt 200 aus return 0; }
-
array schrieb:
Hallo, wie kann ich in der Funktion ermitteln wie viele Elemente der Parameter hat ?
Garnicht. Arrays "zerfallen" bei der Übergabe an Funktionen zu Pointern auf das erste Element. Deshalb auch sizeof(v) == 4, weil Pointer auf deinem System immer die Größe 4 haben. Alle Info, wieviele Elemente da tatsächlich hinter hängen, geht verloren.
Benutze Container an Stelle der Arrays, dann klappts auch
-
Geht nicht. Entweder du übergibst die Größe als Parameter, oder du benutzt:
* std::array / boost::array wenn die Größe zur Compilezeit bekannt ist.
* std::vector, wenn die Größe dynamisch ist.Dein Code mit std::array :
template<std::size_t Size> void t(std::array<char, Size>& arr) { std::cout << arr.size() << "\n"; } int main(int argc, char** argv) { std::array<char, 200> arr; t(arr); }
Mit std::vector:
void t(std::vector<char>& vec) { std::cout << vec.size() << "\n"; } int main(int argc, char** argv) { std::vector<char> vec(200); t(vec); }
-
Bei Array-Typen gibt es eine nicht-intuitive Sonderbehandlung an diversen Stellen. Schnapp Dir am besten ein richtiges Buch und lerne damit.
Eine dieser Sonderbehandlungen ist zB, dass der Compiler jeden Parametertypen T[] oder T[N] in der Parameterliste einer Funktion durch T* ersetzt. v ist also nur ein dummer Zeiger. Die Initialisierung, die hier stattfindet, nennt sich "copy initialization":
void foo(char *v); char a[200]; char *ptr = a; // hier wird ptr genauso foo(a); // wie v initialisiert.
Wenn Du eine Zeigervariable so wie hier mit einem Array-Ausdruck initialisierst, dann zeigt der Zeiger einfach auf das erste Array-Element.
Ob Du also als Parametertypen char v[] oder char*v hinschreibst, ist Jacke wie Hose.
Trotzdem: Zeiger sind Zeiger und keine Arrays. Arrays sind Arrays und keine Zeiger. Du kannst aber mit einem Zeiger und dem []-Oprator auf Array-Elemente zufgreifen. Das funktioniert deswegen, weil zeiger[index] als Abkürzung für *(zeiger+index) definiert wurde und weil Array-Elemente hintereinander im Speicher liegen.
-
Du kannst statt direkt das Array zu übergeben auch eine Adresse darauf übergeben, damit kann der Compiler die sizeof Information ermitteln:
typedef char MeinTyp[200]; void f(MeinTyp *a) { cout << sizeof(*a) << endl << *a << endl; } int main() { MeinTyp a = { "bla fasel" }; f(&a); return 0; }
-
Das fiese ist aber, die Funktion funktioniert dann nur mit 200er Arrays. Wie in Pascal.
-
Kapierst du wahrscheinlich nicht aber so geht es mit C-Arrays:
#include <iostream> #include <cstddef> template<class T, std::size_t Size> std::size_t CArraySize(T(&)[Size]) { return Size; } int main() { int Foo[123]; std::cout << CArraySize(Foo); }
-
EOutOfResources schrieb:
Kapierst du wahrscheinlich nicht aber so geht es mit C-Arrays:
#include <iostream> #include <cstddef> template<class T, std::size_t Size> std::size_t CArraySize(T(&)[Size]) { return Size; } int main() { int Foo[123]; std::cout << CArraySize(Foo); }
Da ist doch wohl meine Lösing mit std::array eleganter.
-
Ethon schrieb:
Da ist doch wohl meine Lösing mit std::array eleganter.
Klar, aber meine Antwort passt auf seine Frage, deine nicht
.
-
krümelkacker schrieb:
Bei Array-Typen gibt es eine nicht-intuitive Sonderbehandlung an diversen Stellen. (...)
Eine dieser Sonderbehandlungen ist zB, dass der Compiler jeden Parametertypen T[] oder T[N] in der Parameterliste einer Funktion durch T ersetzt.*
Ich wollte nur nochmal die IMO wichtigste Info hier hervorheben, da das etwas ist, wo vermutlich fast jeder Anfänger drüberstolpert.