Problem beim übergeben eines Arrays an eine Funktion



  • Hallo,
    mein Ziel ist es ein Array an eine Funktion zu übergeben und dort ausgeben zu lassen, leider funktioniert mein Ansatz noch nicht ganz.

    Die Funktion sizeof scheint nicht ordnungsgemäß zu funktionieren, denn in der Funktion gibt sizeof(Array)/4 die Zahl 1 aus, wohingegen ich im Hauptprogramm 9 ermittel. Wenn ich die Bedingung in der For-Schleife manuell anpasse und auf 9 setze, dann wird das Array auch ordnungsgemäß ausgegeben, ergo wurde es korrekt übergeben, wo liegt also das Problem?

    #include<iostream>
    using namespace std;
    
    void ArrayAusgabeChar(char);
    void ArrayAusgabeInt(int a[]);
    
    void main()
    {
    	char cA[9] = 
    	{
    		'a','b','c','d','e','f','g','h','i'
    	};
    
    	int iA[9] =
    	{
    		1,2,3,4,5,6,7,8,9
    	};
    
    	ArrayAusgabeInt(iA);
    
    	cin.get(); cin.get();
    }
    
    void ArrayAusgabeInt(int Array[])
    {
    	int max = sizeof(Array)/4;	//geteilt durch 4, weil Integer 4 Byte platz einnimmt
    
    	cout<< "Max = "<< max <<endl;
    
    	for (int i = 0; i < max; i++)
    	{
    		cout<<Array[i];
    	}
    }
    
    void ArrayAusgabeChar(char Array[])
    {
    	int max = sizeof(Array);	//Da chars 1 Byte groß sind, muss ich hier nicht teilen
    
    	for (int i = 0; i < max; i++)
    	{
    		cout<<Array[i];
    	}
    }
    

    Vielen Dank im Voraus für jede Hilfe!
    Gruß Edd



  • Das Problem liegt darin, dass die Funktionen nicht wissen können, wie groß das Array ist. Ein C-Array enthält keine Information über seine Größe, technisch ist es de facto ein Zeiger auf den Anfang des Speicherbereichs ohne Ende oder Größe.

    Du musst also einen zweiten Parameter für die Arraygröße benutzen, oder viel besser und weniger fehleranfällig: std::vector



  • EdwardBlack schrieb:

    //geteilt durch 4, weil Integer 4 Byte platz einnimmt
    

    Es können 4 Byte sein. Müssen es aber nicht.

    Darum

    int max = sizeof(Array)/sizeof(Array[0]);
    

    Und dann passt es für jede Art Array. (Aber auch nur in dem Kontext, in dem auch das Array definiert wurde)



  • Jodocus schrieb:

    Das Problem liegt darin, dass die Funktionen nicht wissen können, wie groß das Array ist. Ein C-Array enthält keine Information über seine Größe, technisch ist es de facto ein Zeiger auf den Anfang des Speicherbereichs ohne Ende oder Größe.

    Das ist nur halb richtig. Arrays enthalten die Größeninformation im Typ:

    int array[20];
    sizeof(array) // 20 * sizeof(int)
    

    Das Problem ist, dass Arraytypen in Funktionsparametern (und nur da) automatisch Zeigertypen sind. Da ist nichts mit "zerfallen" oder "umwandeln", es *sind* Zeiger. Deshalb:

    void f(int array[20]) {
      sizeof(array) // => sizeof(int*)
    }
    

    Je mehr ich drüber nachdenke, desto fragwürdiger erscheint mir dieses Design, man hätte Arraytypen als Funktionsparameter einfach verbieten können 😕

    Referenz: 8.3.5p5, "After determining the type of each parameter, any parameter of type 'array of T' [...] is adjusted to be 'pointer to T' [...]."

    Nur ein kleiner Nitpick, die praktischen Konsequenzen bleiben gleich.



  • Sehr gut, danke für eure Tipps und Hilfestellungen! Das Problem hat sich damit gelöst, da hätte ich auch selber draufkommen müssen 😕 Code:

    #include<iostream>
    using namespace std;
    
    void ArrayAusgabeInt(int a[], int max);
    
    void main()
    {
    	int iA[9] =
    	{
    		1,2,3,4,5,6,7,8,9
    	};
    
    	int max = sizeof(iA)/sizeof(iA[0]);
    	ArrayAusgabeInt(iA, max);
    
    	cin.get(); cin.get();
    }
    
    void ArrayAusgabeInt(int Array[], int max)
    {
    	for (int i = 0; i < max; i++)
    	{
    		cout<<Array[i];
    	}
    }
    


  • Das ganze mit dem sizof wird erst dann richtig sinnvoll, wenn du bei der Definiton vom Array die Größe weglässt. (sonst weißt du ja das es 9 ist)

    int iA[] = { 1,2,3,4,5,6,7,8,9 };
    


  • template<size_t size>
    void ArrayAusgabeInt(int (&Array)[size]){
        for (int i = 0; i < size; i++){
            cout << Array[i];
        }
        //oder
        for (const auto &i : Array)
            cout << i;
    }
    




  • Da du an die größe der in in C++ genannten Arrays nur wärend der Compilezeit ran kommst, sprich mit sizeof, ist es in C++ üblich, die Länge des Arrays als Parameter mit an die Funktion zu geben. Denn du kannst nie zu 100% sicher stellen, dass der Anwender deiner Klassen eine statisch erstellte Array mit an die Funktion übergibt.
    Wenn du trotzdem an die länge von dynamisch erzeugten Arrays kommen willst, kannst du das so machen 🙂

    template<typename T>
    int getDynamicArraySize(const T* arr)
    {
        return *(((int*)arr) - 4) / sizeof(T);
    }
    

    mit Visual Studio 2013, habe ich allerdings noch nie gesehen und hängt von gewissen Implementationen ab.



  • oenone schrieb:

    http://www.c-plusplus.net/forum/39346

    So haben wir es jedoch in der Ausbildung zum technischen Assistenten für Informatik beigebracht bekommen und es gab noch nie Probleme mit dieser Methode.



  • EdwardBlack schrieb:

    oenone schrieb:

    http://www.c-plusplus.net/forum/39346

    So haben wir es jedoch in der Ausbildung zum technischen Assistenten für Informatik beigebracht bekommen und es gab noch nie Probleme mit dieser Methode.

    Gottverdammi: kompililert nicht: http://ideone.com/7r2sjS



  • das sizeof(array) funktioniert nicht da sizeof die größe des arrays in bit wiedergibt, um dies umzurechnen einfach den "datentyp" mit einbeziehen...

    int array[]={1,2,3,4,5,6,7,8,9};
    
    sizeof(array)/sizeof(int);
    

    dann müsstest du die richtige größe bekommen...

    also so mach ich das ... falls man das mal braucht 🙂 ...
    ansonsten kannst vll auch container nutzen die bringen meistens funktionen mit die direkt die "größe/länge" auswerfen... 😉


Anmelden zum Antworten