komische Ausgabe obwohl Funktion identisch



  • Copy and past, da mir zeiger noch unbekannt sind.^^



  • #include <iostream>
    
    using namespace std;
    
    void sort_a(int *begin, int *end);
    
    int main()
    {
    	int values[10] = { 23,11,67,3,9,0,28,30,21,15 };
    
    	cout << "old array: ";
    	for (int i = 0; i<10; i++)
    	{
    		cout << values[i] << " | ";
    	}
    
    	cout << endl << "new array: ";
    	sort_a(&values[0], &values[9]);
    
    	cin.get();
    	return 0;
    }
    
    void sort_a(int *begin, int *end)
    {
    	int temp;
    
    	for (int i = 0; i<10; i++)
    	{
    		for (int j = i + 1; j<10; j++)
    		{
    			if (*(begin + i) > *(begin + j))
    			{
    				temp = *(begin + i);
    				*(begin + i) = *(begin + j);
    				*(begin + j) = temp;
    			}
    		}
    		cout << *(begin + i) << " | ";
    	}
    }
    

    So würde ich das dann vermutlich machen.
    Aber wieso wird so eine Aufgabe von dir verlangt, wenn noch gar keine Zeiger behandelt wurden?

    Edit: vergessen int *end zu verwenden.
    So ist das eigentlich genau das gleiche wie oben.



  • Aber wieso wird so eine Aufgabe von dir verlangt, wenn noch gar keine Zeiger behandelt wurden?

    Das ist die Aufgabe.. Write a program that detects if a list is sorted or not, and if it is not sorted, sort it.



  • Das mit den Zeigern ist mir noch total unbekannt. Das übernächste Kapitel behandelt es aber.



  • Mir ist erst jetzt SeppJs Beitrag aufgefallen. Ich habe mich die ganze Zeit gefragt woher du dann das mit int *begin und int *end hast.
    Aber würde man wenn dann nicht eher die 10 als Konstante anlegen und die dann als Parameter mitgeben?
    Ansonsten halt so:

    void sort_a(int *begin, int *end)
    {
    	int temp;
    
    	int size = end - begin;
    
    	for (int i = 0; i <= size; i++)
    	{
    		for (int j = i + 1; j <= size; j++)
    		{
    			if (*(begin + i) > *(begin + j))
    			{
    				temp = *(begin + i);
    				*(begin + i) = *(begin + j);
    				*(begin + j) = temp;
    			}
    		}
    		cout << *(begin + i) << " | ";
    	}
    
    }
    

    Oder wie meinst du das, SeppJ?

    Edit: dann nimm jetzt erstmal wahlweise einen globalen Array oder nimm schon einmal die Informationen über Zeiger, die du jetzt hier gelesen hast.
    Das mit dem int *begin und int *end vergisst du bis zu dem entsprechenden Kapitel.
    Was du machen kannst, ist, dass du einen Integer anlegst mit der Arraygröße, bei dir also 10. Den übergibst du dann als zweiten Parameter.

    void sort_a(int *values, int arraysize)
    

    Wenn du schon Konstanten hast, dann kannst du den Integer von arraysize auch als Konstante nehmen.



  • Ich persönlich habe es zudem noch immer lieber, wenn die Funktionsdefinition erst unterhalb der main-Funktion stattfindet, aber das ist vermutlich Geschmackssache (?).

    Das geht aber nur, wenn die Deklaration schon vorher stattfindet.

    saveit schrieb:

    Das ist die Aufgabe.. Write a program that detects if a list is sorted or not, and if it is not sorted, sort it.

    Dann fehlt ja noch der Teil in dem du prüfst ob die Liste bereits sortiert ist.

    Wenn man sich die *begin, *end Notation angewöhnt, hat das den großen Vorteil, dass einem hinterher Iteratoren nicht mehr so schwer fallen, als wenn man am Anfang immer Startpunkt + größe übergibt.
    Aber das Lehrbuch auf den Kopf zu stellen wird auch nicht zielführend sein, da hat sich hoffentlich jemand was bei gedacht.


  • Mod

    Das begin/end-Schema ist später nützlich, wenn man sich mal nicht auf Arrays und Zeiger einschränken möchte:

    #include <iostream>
    using namespace std;
    
    void sort_a(int *begin, int *end)
    {
        for (int *i = begin; i != end; ++i)
        {
            for (int *j = i; j != end; ++j)
            {
                if (*i > *j)
                {
                    int temp = *i;
                    *i = *j;
                    *j = temp;
                }
            }
        }
    }
    
    int main() {
    	int values[10] = { 23,11,67,3,9,0,28,30,21,15 };
    	sort_a(begin(values), end(values));
    	for (auto i: values)
    		cout << i << '\n';
    }
    

    So habe ich als einzige Eigenschaft benutzt, dass man ++, =, != und * auf begin und end anwenden kann. Das ist aber etwas, das nicht exklusiv auf Zeiger beschränkt ist. Da könnte man nun ein Template draus machen, dass statt int* beliebige Typen zulässt, die ++, =, != und * können. Solche Objekte nennt man unter Programmierern "output iterator". Ein Zeiger ist ein output iterator, aber jede Menge andere Objekte auch, beispielsweise die Elemente einer verketteten Liste. Das heißt, man bekommt hier quasi geschenkt, dass man nun so ziemlich beliebige Container sortieren kann, die nur irgendwie ein Konzept von "von vorne nach hinten durchgehen" haben. Was so ziemlich alles ist, was man überhaupt sortieren kann.

    Warum nicht Anfang und Größe? Das ginge im Prinzip auch, aber man müsste irgendwann einmal begin + N berechnen, das heißt, begin müsste auch + können. Das ist eine Einschränkung, die nicht nötig ist, wie man oben sieht. Ein Objekt, das ++, =, !=, * und + kann, nennt man einen "random access iterator". Zeiger sind auch random access Iteratoren und alle random access Iteratoren sind auch output Iteratoren, aber nicht alle output Iteratoren sind auch random access Iteratoren. Beispielsweise sind die Elemente einer verketteten Liste keine random access Iteratoren. Man könnte dann also unnötigerweise keine verketteten Listen mehr sortieren.

    #include <iostream>
    #include <list>
    using namespace std;
    
    template<typename Iterator> void sort_a(Iterator begin, Iterator end)
    {
        for (Iterator i = begin; i != end; ++i)
        {
            for (Iterator j = i; j != end; ++j)
            {
                if (*i > *j)
                {
                    auto temp = *i;
                    *i = *j;
                    *j = temp;
                }
            }
        }
    }
    
    int main() {
    	// Geht mit Arrays:
    	int values[10] = { 23,11,67,3,9,0,28,30,21,15 };
    	sort_a(begin(values), end(values));
    	for (auto i: values)
    		cout << i << '\n';
    
    	// Geht mit list:
    	list<int> my_list = { 23,11,67,3,9,0,28,30,21,15 };
    	sort_a(begin(my_list), end(my_list));
    	for (auto i: my_list)
    		cout << i << '\n';
    }
    


  • Klingt gut und logisch, danke für die Erläuterung.



  • Danke, für die ausführlichen Antworten, mit sowas habe ich überhaupt nicht gerechnet. An sich sieht es ziehmlich simpel aus, aber der Teufel steckt meist im Detail, wie man so schön sagt. Daher werde ich mich erstmal damit explizit auseinander setzten und versuche es zu verstehen.

    Ich dachte das wäre die Prüfung, aber anscheinend hast du recht. Er würde ja trotzdem jedes Element durchsuchen, unabhängig davon ob es sortiert ist oder nicht.



  • Skylac06 schrieb:

    unskilled schrieb:

    Deshalb muss auch die einen Wert zurückliefern, das ist normalerweise 0.
    Also einfach ein
    return 0;

    no need. stört nur

    Dann habe ich das falsch gelernt. Danke für die Korrektur. 🙂
    Aber sollte man dann nicht auch eher eine void main() benutzen?

    nein



  • for (auto i: values)

    Was bedeutet diese Zeile SeppJ?



  • Das ist eine Range-For-Schleife, die alle Elemente von value nacheinander durchläuft und in die Variable i füllt. Mit i kann dann stellvertretend für das Element innerhalb der Schleife gearbeitet werden.
    Das Schlüsselwort auto bestimmt hierbei automatisch den benötigten Datentyp.



  • Versuch schon die ganze Zeit, damit der code funktioniert nur klappt es nicht.
    Problem liegt einmal beim auto wert und einmal in der Zeile.

    sort_a(begin(values), end(values));

    hier sagt er nur end was not declared in this scope.
    und begin was not declared in this scope.



  • Welchen Compiler benutzt du denn?
    Das Schlüsselwort auto wird glaube ich erst ab C++11 (?) unterstützt.
    Du kannst hier auch einfach auto durch int ersetzen.

    Und wie kommst du auf begin(values) und end(values)?
    Der Compiler sucht hier vermutlich nach Funktionen mit dem Namen, die in der Form natürlich nicht existieren.
    Da begin und end in der main-Funktion gar nicht existieren kannst du sie natürlich auch nicht an die Funktion übergeben. Hier musst du die Adressen von values[0] und values[9] übergeben. Die bekommst du über den Adressen-Operator &.
    Bist du inzwischen bereits bei dem Thema Zeiger in deinem Buch angekommen?
    Davor solltest du sie vermutlich erstmal meiden.


  • Mod

    Du musst C++11 oder höher bei deinem Compiler aktivieren. Deiner läuft wahrscheinlich auf C++98 (wie in 1998, also guck mal auf den Kalender).



  • CodeBlocks, GNU GCC Compiler.
    Hattes das vor einiger Zeit mal eingerichtet, was wie ein Spaß das doch war.



  • HiHi,
    ich bräuchte nochmal eure Hilfe.
    Ich habe versucht den Test der Aufgabe durchzuführen mit Hilfe einer zusätzlichen Funktion. Sie funktioniert auch, nur gibt sie mir nicht den gewünschten Wert wieder, sodass ich sie in der main()benutzen kann.
    Die Function soll testen ob values[0] immer kleiner ist als alle anderen Zahlen innerhalb der Array. Wenn dies nicht so ist, soll er x+1 rechnen, um diese Zahl dann später in der Main für die IF Anweisung zu nutzen.
    Die cout<< lass ich jetzt einfach mal drin, da sie mir helfen.

    #include <iostream>
    
    using namespace std;
    
    void check_sort(int x);
    
    void sort_a(int *begin, int *end)
        {
        for(int *i = begin; i !=end ; i++)
            {
            for(int *j = begin; j != end; j++)
                {
                if(*i<*j)
                    {
                    int temp = *i;
                    *i = *j;
                    *j = temp;
                    }
                }
            }
        }
    
    void check_sort(int x)
        {
    
        int values[10]={23,11,67,3,9,0,28,30,21,15};
        for(int i = 0; i<1; i++)
            {
                cout<<values[i]<<" first for\n";
                for( int j = 0+1;j<10;j++)
            {
            cout<<values[j]<<" second for\n" ;
            if(values[i]>values[j])
                {
                    cout <<values[i]<< " i  j "<<values[j]<< " ist es größer\n";
                    int x =x+ 1;
                }
            }
    
            }
        cout << x <<" x";
    
        }
    
    int main()
        {
    
        int values[10]={23,11,67,3,9,0,28,30,21,15};
        check_sort(x);
        cout<<"\n"<<x<< " nnormal hier\n";
    
         if(x!=0)
            {
            cout <<"Old Array: ";
            for(int i = 0; i <10-1; i++)
                {
                    cout<< values[i]<<" | ";
                }
    
            sort_a(&values[0], &values[10]);
            cout<<"\n\nNew Array: ";
                for(auto i : values)
                    {
                   cout <<""<< i << " | ";
                    }
           }
    
     }
    


  • Was prüft die Funktion? Wirklich? Schau noch mal genau hin.
    In die Funktion geht ein Wert rein, aber keiner raus. Stichworte: return, call byte value, call byte reference.



  • Es stellen sich noch mehr Fragen. Zum Beispiel, wo das "x" denn herkommt. Das kann doch so gar nicht kompilieren!

    Dann frage ich mich noch:
    - warum hast du 2 Arrays values[10] im Programm?
    - was soll for(int i = 0; i<1; i++) tun?
    - deine Einrückungen sind merkwürdig, gehen sie doch manchmal auch nach links?!
    - versuche außerdem mal, überall auf die "10" zu verzichten und lieber eine Konstante oder (noch besser) eine automatisch berechnete Größe einzusetzen



  • was soll for(int i = 0; i<1; i++) tun?

    Er soll heir nur die erste Zahl des Arrays mit den anderen danach vergleichen, sodass die 23 fix ist und alle danach getestet werden.
    Funktioniert jetzt zwar, aber es wird bestimmt falsch sein. Also bitte verbessern. Unter der automatisch berechneten größe kann ich mir noch nichts vorstellen. Auch ist mir unklar wie ich auf eine Array verzichten kann, vielleicht weil mir die Übergaben noch nicht so ganz einleuchten.

    #include <iostream>
    
    using namespace std;
    
    void check_sort();
    int x;
    
    void sort_a(int *begin, int *end)
        {
        for(int *i = begin; i !=end ; i++)
            {
            for(int *j = begin; j != end; j++)
                {
                if(*i<*j)
                    {
                    int temp = *i;
                    *i = *j;
                    *j = temp;
                    }
                }
            }
        }
    
    void check_sort()
        {
    
        int values[10]={23,11,67,3,9,0,28,30,21,15};
        for(int i = 0; i<1; i++)
            {
            cout<<values[i]<<" first for\n";
                for( int j = 0+1;j<10;j++)
                    {
                    cout<<values[j]<<" second for\n" ;
                        if(values[i]>values[j])
                            {
                            cout <<values[i]<< " i  j "<<values[j]<< " ist es größer\n";
                            x=  x+ 1;
                            }
                    }
            }
            cout << x;
        }
    
    int main()
        {
        int values[10]={23,11,67,3,9,0,28,30,21,15};
        check_sort();
        cout<<"\n"<<x<< " nnormal hier\n";
         if(x!=0)
            {
            cout <<"Old Array: ";
                for(int i = 0; i <10; i++)
                    {
                    cout<< values[i]<<" | ";
                    }
                    sort_a(&values[0], &values[10]);
                    cout<<"\n\nNew Array: ";
                        for(auto i : values)
                            {
                            cout <<""<< i << " | ";
                            }
            }
        }
    

Anmelden zum Antworten