betriebsblind: Fehler bei Array-Operationen

hello again :wink:
ich bin momentan betriebsblind: ich bekomme Fehler bei Array-Operationen und kapier nicht, was falsch ist:

void bubblesort(long &array[], int length)
{
   int i, j;
     
   for (i = 0; i < length -1; ++i)   { 
     for (j = 0; j < length - i - 1; ++j) {
       if (array[j] > array[j + 1])  {
 	  long tmp = array[j];
          array[j] = array[j + 1];
 	  array[j + 1] = tmp;
       }
     }
   }
}


inline long medianI(int len, long &src[])
{
  long temp[len];
  memcpy ( temp, src, sizeof(src) );
  bubblesort( temp, len );
  return temp[len/2];
}


//--------------------------------------------

inline void fifopushI3(long &src[], long _new)
{
  src[2]=src[1];
  src[1]=src[0];
  src[0]= _new;  
}

muxer1033:51: error: declaration of ‘array’ as array of references
muxer1033:52: error: declaration of ‘src’ as array of references
muxer1033:53: error: declaration of ‘src’ as array of references
muxer1033:181: error: declaration of ‘array’ as array of references
muxer1033.ino: In function ‘void bubblesort(int)’:
muxer1033:187: error: ‘array’ was not declared in this scope
muxer1033.ino: At global scope:
muxer1033:197: error: declaration of ‘src’ as array of references
muxer1033.ino: In function ‘long int medianI(int)’:
muxer1033:200: error: ‘src’ was not declared in this scope
muxer1033:201: error: invalid conversion from ‘long int*’ to ‘int’
muxer1033:181: error: too many arguments to function ‘void bubblesort(int)’
muxer1033:201: error: at this point in file
muxer1033.ino: At global scope:
muxer1033:208: error: declaration of ‘src’ as array of references
muxer1033.ino: In function ‘void fifopushI3(long int)’:

wer hat die zündende Idee ?

habs jetzt so versucht - keine Fehlermeldung mehr, bin aber unsicher, ob er jetzt auch macht was er solll … :roll_eyes:

void bubblesort(long *array, int length)
{
   int i, j;
     
   for (i = 0; i < length -1; ++i)   { 
     for (j = 0; j < length - i - 1; ++j) {
       if (array[j] > array[j + 1])  {
 	  long tmp = array[j];
          array[j] = array[j + 1];
 	  array[j + 1] = tmp;
       }
     }
   }
}

//--------------------------------------------

inline long medianI(int len, long *src)
{
  long temp[len];
  memcpy ( temp, src, sizeof(src) );
  bubblesort( temp, len );
  return temp[len/2];
}


//--------------------------------------------

inline void fifopushI3(long *src, long _new)
{
  src[2]=src[1];
  src[1]=src[0];
  src[0]= _new;  
}

In medianI:
sizeof(src) liefert 2 ( die Größe eines Pointers )
Du meinst len*sizeof(long)

Erstaunlich, dass bei avr-gcc
long temp[len];
kompiliert.
Gibt bei VisualStudio einen Fehler ("expected constant expression")

dankeschön! das hätte ich nie gefunden :astonished:

Du hattest anscheinend ein Array auf Referenzen auf long deklariert. Funktionieren tut entweder "long array" oder "long* array". Weil Arrays eben nur Zeiger auf das erste Element sind. Letzteres ist dabei üblicher. Da Array-Variablen schon Zeiger sind, braucht man da nicht den "adress of" Operator wie sonst bei Zeigern.

Dazu kommt dann dass der & Operator auch noch für Referenzparameter verwendet wird. Die sind zwar mit Zeigern verwandt, aber was anderes

Bei so winzigen Arrays ist es zwar egal, aber der Standard Sortier-Algorithmus für kleinere Arrays ist Insertion Sort. Das lässt sich ähnlich einfach wie Bubble Sort programmieren, aber ist zig mal besser. Aber wie gesagt spielt es bei einer handvoll von Elementen keine so große Rolle.

mit der allerersten array-Deklaration hast du Recht :wink:
Bubblesort habe ich nur genommen, weil es bei nur 3-5 Elementen sehr kurz und schnell ist.
Ansonsten nehme ich oft Shellsort oder Quicksort, aber das wäre hier oversized :sunglasses:

danke aber für die Hinweise - mit dem * und dem & werde ich noch öfter ins Schleudern kommen, denke ich - und besonders für mehrdimensionale Arrays, aber das ist momentan nicht das Thema :slight_smile:

Quicksort hat bei kleinen Arrays auch zu viel Overhead und kann seinen Geschwindigkeitsvorteil erst später ausspielen. Das ist der Grund weshalb viele Libs erst aber einer gewissen Größe zu Quicksort wechseln.

& brauchst du bei Arrays eigentlich nicht. Hier ist eine Anwendung dafür:
http://de.wikibooks.org/wiki/C++-Programmierung/_Weitere_Grundelemente/_Referenzen#Selbstdefinierte_Referenzen

Für call by reference mit elementaren Datentypen gibt es zwei Optionen.

Zeiger:

void func(int* value)
{
     *value = 1;          //Variable muss vor Zuweisung dereferenziert wird
}

int value;
func(&value);          //& übergibt die Adresse von value

Referenzen:

void func(int& value)          //value ist eine Referenz auf int
{
     value = 1;         //keine Dereferenzierung mit dem Indirektions-Operator * nötig
}

int value;
func(value);        //kein Adress-of Operator & bei Übergabe nötig

Mit Referenzen kann man wenig machen als mit Zeigern, aber wenn man nur einen Wert an eine Funktion übergeben will, reicht es oft. Das große Vorteil ist, dass sich die Syntax nicht ändert. Man braucht z.B. auch kein -> bei structs oder Objekten. Dinge wie Referenzen aufeinander zuweisen oder inkrementieren wie bei Zeigern geht aber nicht.

Da Arrays aber schon sehr eng mit Zeiger verwandt sind, muss man sie da allerdings verwenden.

das war gut, danke :slight_smile: