Adressarithmetik C/C++

TanjaKs

Grünschnabel
Hallo,
ich versuche gerade, C/C++ zu lernen,
und habe bei der Zeigerarithmetik einige Probleme.
Z.B. hier:


ich versuche, ein long-Array nach Duplikaten
zu durchsuchen. Wobei die Elemente evtl. aus mehreren longs
zusamengesetzt werden können:
z.B so würde ein Array mit insgesamt 4 Elementen der Länge 3 und 2 Duplikaten aussehen :
2 1 1 2 1 1 3 6 6 3 6 6

nun will ich mit der compare - Function (wie bei qsort) die Duplikate erkennen:
Das eingentliche Problem liegt wohl an der Verwendung der Funktion compare,
die falsche Duplikaterkennung macht.

Wenn jemand wüsste, wo das Problem ist, wäre ich ihm sehr dankbar1
Gruss, Tanja
Hallo,
ich versuche gerade, C/C++ zu lernen,
und habe bei der Zeigerarithmetik einige Probleme.
Z.B. hier:


ich versuche, ein long-Array nach Duplikaten
zu durchsuchen. Wobei die Elemente evtl. aus mehreren longs
zusamengesetzt werden können:
z.B so würde ein Array mit insgesamt 4 Elementen der Länge 3 und 2 Duplikaten aussehen :
2 1 1 2 1 1 3 6 6 3 6 6

nun will ich mit der compare - Function (wie bei qsort) die Duplikate erkennen:
Das eingentliche Problem liegt wohl an der Verwendung der Funktion compare,
die falsche Duplikaterkennung macht.

Wenn jemand wüsste, wo das Problem ist, wäre ich ihm sehr dankbar1
Gruss, Tanja
 
weiteer :)

Quellcode:


#include <string.h>
#include <stdlib.h>
#include <stdio.h>

long glChainLength;

int compare(const void* obj1, const void* obj2){

long* ptr1 = (long*)obj1;
long* ptr2 = (long*)obj2;

long ctr = 0;

if(*ptr1 < *ptr2){
return -1;
}else{
if(*ptr1 > *ptr2){
return 1;
}else{
while(ctr < glChainLength){
ptr1++;
ptr2++;

if(*ptr1 < *ptr2){
return -1;
}
if(*ptr1 > *ptr2){
return 1;
}
ctr++;
}
return 0;
}
}
}
 
und nun...

und die Verwendung:

int main(){
long* longArray;
.....//aufsteigend sortiert mit lauter longs z.B. mit der Laenge (glChainLengh = 3 und
anzahl der Elemene (noOfLongs = 4)): 2 3 3 2 3 3 4 5 5 4 5 5
long* runPrt;
long* middlePtr;
long* endPtr;

runPtr = longArray;
middlePtr = runPtr + glChainLength;
endPtr = runPtr + noOfLongs*glChainLength;

for(; runPtr < endPtr; runPtr += glChainLength){
if(compare(runPtr, middlePtr)){ /// FALSCHER AUFRUF?
printf("\n ungleich \n"); //kein Duplikat

}else{
printf("gleich\n"); //Duplikat
}
middlePtr+=glChainLength;
}
}
}
 
Hallo Tanja,

Du mußt in der while-Schleife der compare()-Methode sofort zu Beginn den ctr erhöhen, sonst vergleicht er ein Wertepaar zuviel. Für ctr = 0 machst Du es ja bereits außerhalb der Schleife:

Code:
while(++ctr < glChainLength){
  ptr1++;
  ptr2++;

  if(*ptr1 < *ptr2){
    return -1;
  }
  if(*ptr1 > *ptr2){
    return 1;
  }
}

Daniel

EDIT: oki, ich hab das mal nachgeholt mit den Tags ;-)
 
Zuletzt bearbeitet von einem Moderator:
Also, ich würde anders rangehen und schonmal das Array umstrukturieren. Mit der Datenstruktur steht und fällt schließlich das Programm (oder so ähnlich ;) ). Da ja scheinbar immer die gleiche Anzahl longs zueinander gehören, solltest du zunächst dementsprechend strukturieren, entweder über ein 2 dimensionales Array oder - was ich bevorzugen würde - du haust ein Array in eine Struktur und erstellst ein Array mit dieser Struktur:

Code:
#define ELEMENTE 10
#define LAENGE 3

struct verylong
{
  long* data;
};

verylong* array;

//Speicher reservieren

array = new verylong[ELEMENTE];
for (int i = 0; i < ELEMENTE; i++)
{
  array[i] = new long[LAENGE]
}

Dann kannst du das ganze füllen. Beim Sortieren kann man jetzt sogar problemlos den Standardquicksort-Algorithmus benutzen, der schon als qsort-Funktion implementiert ist. Die compare-Funktion würde in etwa so aussehen:

Code:
int compare(const void* obj1, const void* obj2)
{
  verylong *e1 = (verylong*)obj1;
  verylong *e2 = (verylong*)obj2;

  int result = 0;
  for (int i = 0; i < LAENGE; i++)
  {
    if (e1->data[i] > e2->data[i])
    {
      result = -1;
      break;
    }
    if (e1->data[i] < e2->data[i])
    {
      result = 1;
      break;
    }
  }
  return result;
}

Wenn also 0 zurückkommt, sind sie gleich, ansonsten habe ich jetzt angenommen, dass die Größe wie bei den Dezimalzahlen auch positionsabhängig ist, wobei ich festgelegt habe, dass kleinere Indizes größere Potenzen bedeuten (wenn andersrum gewünscht, einfach Bedingungen für die for-Schleife umkehren).

Am Ende nicht vergessen den Speicher in den Array wieder freizugeben.

P.S.: Bitte Code-Tags benutzen.
 
Zurück