Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (GNU/Linux, *NIX, *BSD und Co) » Problem mit Arrays, bin c++-anfänger

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
03.10.2008, 09:18 Uhr
~timstre
Gast


Hallo,
ich bin medieninformatik student, und habe bisher nur fleissig in java programmiert. da wir jetzt (im 2. semester) in algorithmen uns entscheiden konnten, ob wir die übungen in java, c++ oder c# abgeben wollen, dachte ich mir ich betrete mal neuland und eigne mir nebenbei noch ein bisschen c++ an. es ist die erste übung, zum gnomesort.


C++:
#include <iostream>
using namespace std;

void gnomeSort(int intarray[]) {
  int i = 0;
  int length = sizeof(intarray)/sizeof(int);    //<-- hier liegt irgendwie das problem
                                                                     //die länge stimmt immer nicht
  while (i != length){
    if (intarray[i] > intarray[i+1]){
      swap(intarray[i], intarray[i+1]);
      if (i != 0) i--;
    }
    else i++;
  }
}

int main()
{
  int i1[5]; //Array wird initialisiert    
    
  const int i1length = sizeof(i1)/sizeof(int); //i1length enthält
                                               //Länge des Arrays
    
  srand(time(NULL));                           //Array wird mit
  for(int i = 0; i < i1length; i++){                                          //Zufallswerten
    i1[i]=rand() % 100;                        //gefüllt
  }
    
  for(int i = 0; i < i1length; i++)            //Werte des Arrays
    cout << i1[i] <<" ";                       //werden ausgegeben
  cout << endl;

  gnomeSort(i1);                               //Array wird sortiert

  for(int i = 0; i < i1length; i++)            //Sortiertes Array
    cout << i1[i] <<" ";                       //wird ausgegeben
    
  return 0;
}




Bearbeitung von 0xdeadbeef:

code- durch cpp-tags ersetzt, Einrückung verkürzt (siehe post 001)


Dieser Post wurde am 03.10.2008 um 11:30 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
03.10.2008, 09:20 Uhr
~timstre
Gast


Sorry, irgendwie gabs wohl probleme mit den tabs, kanns leider nicht editieren, weil noch nicht registriert, hoffe das ist kein allzu großes problem...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
03.10.2008, 10:38 Uhr
TOSHMAX



Hi,
es stimmt der Fehler liegt genau da wo du vermutet hast.
Statt

C++:
int intarray[]

könntest du genauso schreiben

C++:
int* intarray


Und die Größe von einem Zeiger auf int ist 4, du hättest also immer nur ein Element.
Du musst in deinen Parameter noch die Größe des Arrays mit übergeben damit das funktioniert.

C++:
void gnomeSort(int intarray[],int size)
gnomeSort(i1,sizeof(i1));
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
03.10.2008, 11:46 Uhr
0xdeadbeef
Gott
(Operator)



C++:
int intarray[]


bezeichnet einen unvollständigen Typen, dementsprechend darfst du sizeof darauf gar nicht anwenden (5.3.3 im Standard). Dass dein Compiler das akzeptiert ist seltsam, und mehr oder weniger zufällig; jedenfalls kann dir das jeder andere Compiler (oder spätere Version des Compilers, den du benutzt) um die Ohren hauen.

Jetzt wo das aus dem Weg ist, ein Array in C++ (und auch in C, da kommt das her) ist kein komplexer Datentyp, wie du das aus Java kennst. Es ist einfach ein flacher Speicherbereich, in dem die Objekte, die den Inhalt des Arrays darstellen, stumpf hintereinander liegen. Das bedeutet insbesondere, dass ein Array seine eigene Größe nicht kennt. Außerdem ist wichtig zu wissen, dass sizeof keine Funktion ist, und zur Compilezeit aufgelöst wird. Das bedeutet, zur Laufzeit, wenn die Funktion aufgerufen wird, steht da schon nichts mehr von sizeof, sondern schlicht eine Zahl.

Wie löst man das also? Man kann, wie TOSHMAX das beschreibt, die Größe von Hand mitgeben, allerdings ist das auf die Art eher in C üblich. In C++ benutzt man typischerweise std::vector:

C++:
#include <iostream>
#include <vector>

void print_vector(std::vector<int> const &v) {
  std::cout << "Vektor der Länge " << v.size() << " enthält: ";
  for(int i = 0; i < vec.size(); ++i) {
    std::cout << vec[i] << ' ';
  }
  std::cout << std::endl;
}

int main() {
  std::vector<int> vec(20); // Mit anfänglich zwanzig Elementen bauen

  vec.resize(10); // Ach ne, wir brauchen doch nur 10

  for(int i = 0; i < vec.size(); ++i) {
    vec[i] = i;
  }

  print_vector(vec);
}


Das ist jetzt natürlich nur ein kleiner Ausschnitt dessen, was std::vector kann, aber die Grundidee sollte klar werden. Es ist ein Array dynamischer Länge und bildet dessen Interface plus nützliches anderes Zeug ab - genaueres dazu findest du mit Sicherheit in deinem C++-Buch.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.10.2008, 11:54 Uhr
~timstre
Gast


so sieht das ganze jetzt aus, mit zwei testausgaben des arrays und von i vorher:

Code:
void gnomeSort(int intarray[], int length) {
    int i = 0;

    while (i < length){

        if (intarray[i] > intarray[i+1]){
            cout<<endl<<i<<endl<<intarray[0]<<" "<<intarray[1]<<" "<<intarray[2]<<" "<<intarray[3]<<" "<<intarray[4]<<" "<<endl;
            swap(intarray[i], intarray[i+1]);
            cout<<intarray[0]<<" "<<intarray[1]<<" "<<intarray[2]<<" "<<intarray[3]<<" "<<intarray[4]<<" "<<endl;
            if (i != 0){ i--;}
            }
        else i++;
        }
    }


66 98 91 67 93

1
66 98 91 67 93
66 91 98 67 93

2
66 91 98 67 93
66 91 67 98 93

1
66 91 67 98 93
66 67 91 98 93

3
66 67 91 98 93
66 67 91 93 98

4
66 67 91 93 98
66 67 91 93 5

3
66 67 91 93 5
66 67 91 5 93

2
66 67 91 5 93
66 67 5 91 93

1
66 67 5 91 93
66 5 67 91 93

0
66 5 67 91 93
5 66 67 91 93
5 66 67 91 93
[/code]
woher kommt da die 5 bei i=4?? zumal ja die bedingung gar nicht erfüllt ist... habs auch schon mit arrays verschiedener länge versucht, es landet immer die länge im array, und das immer wenn i eins kleiner als die länge ist... woran liegt das?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
03.10.2008, 11:57 Uhr
~timstre
Gast


okay mein letzter beitrag kam bevor ich deinen gelesen hab, 0xdeadbeef
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
03.10.2008, 12:22 Uhr
0xdeadbeef
Gott
(Operator)


Aus dem Speicherbereich direkt hinter dem Array. Wenn i == 4 ist, vergleichst und vertauschst du ggf. intarray[4] und intarray[5] - und da der Index nur von 0 bis 4 läuft, fliegt dir das halt um die Ohren. (Fachchinesisch dafür ist "undefiniertes Verhalten," der C++-Standard definiert hier keine Semantik)

Nachtrag: Wenn du std::vector benutzt, kannst du Laufzeitprüfungen gegen Pufferüberläufe benutzen. Im Grunde sieht das aus wie oben, nur statt [] .at() benutzen, also

C++:
std::vector<int> vec(20);

vec.at(0) = 1; // macht das selbe wie vec[0] = 1;
vec.at(20) = 20; // schmeißt eine exception


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 03.10.2008 um 12:24 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
03.10.2008, 13:26 Uhr
~timstre
Gast


aaaaaaaaaaaaarrrgh...
na gut, vielen dank 0xdeadbeef, da ärger ich mich allerdings, dass ich darauf nicht von selber gekommen bin, na gut, jetzt läufts alles..
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (GNU/Linux, *NIX, *BSD und Co) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: