Forum: PC-Programmierung zwei Zeiger addieren


von Christian (Gast)


Lesenswert?

Hallo.

Ich möchte zwei Zeiger addieren, in der Form:

//zeigt auf irgendein Speicherbereich
UCHAR *DataScr;

UCHAR* pchTest1;
UCHAR *pchTest2;

pchTest1  = DataScr  +  2;
pchTest2  = DataScr + pchTest1;

Erhalte aber folgende Fehlermeldung:
error C2110: Zwei Zeiger koennen nicht addiert werden

Warum ist es nicht erlaubt zwei Zeiger zu addieren?

Testweise führte ich mal die Subtraktion aus und erhalte folgende 
Meldung:
error C2440: '=' : 'int' kann nicht in 'unsigned char *' konvertiert 
werden

Subtraktion:
...
pchTest2  = DataScr - pchTest1;

Danke für eure Hilfe
Christian

von Karl H. (kbuchegg)


Lesenswert?

Christian schrieb:

> Erhalte aber folgende Fehlermeldung:
> error C2110: Zwei Zeiger koennen nicht addiert werden
>
> Warum ist es nicht erlaubt zwei Zeiger zu addieren?

Weil es eine sinnlose Operation ist.

anderes Beispiel.
Du kannst nicht die geographischen Positionen 2-er Orte addieren. Was 
soll die physikalische Bedeutung dieser Operation sein? Es gibt keine! 
Du kannst sie voneinander abziehen und kriegst auf die Art die Distanz 
zwischen ihnen. Du kannst zu einem Ort eine Distanz addieren. Aber 2 
Orte addieren ergibt kein sinnvolles Ergebnis.

So auch hier.
Du kannst die DIfferenz 2-er Zeiger nehmen und kriegst als Ergebnis die 
Anzahl der Bytes (=Distanz) zwischen ihnen (bereinigt um die Größe des 
Datentyps). Du kannst zu einem Zeiger eine derartige Distanz wieder 
dazuzählen. Aber 2 Zeiger zu addieren ist keine sinnvolle OPeration.


Du musst anfangen zwischen absoluten und relativen Größen zu 
unterscheiden. Eine Uhrzeit ist eine absolute Einheit. Ein Zeitraum ist 
etwas relatives. Du kannst zur Uhrzeit 16:05 den Zeitraum 45 Minuten 
dazuaddieren und bekommst ein sinnvolles Ergebnis. Du kannst auch den 
Zeitpunkt 16:15 vom Zeitpunkt 16:47 abziehen und erhältst als Ergebnis 
den Zeitraum von 32 Minuten, der zwischen den beiden Zeitpunkten liegt. 
Aber zum Zeitpunk 15:49 den Zeitpunkt 14:38 addieren, das geht nicht. 
Was soll die Bedeutung dieses Ergebnisses sein?

: Bearbeitet durch User
von Borislav B. (boris_b)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Weil es eine sinnlose Operation ist.

In diesem konkreten Fall hast du Recht. Im Allgemeinen würde ich das 
aber so nicht sagen. Z.B. zur Mittelwertbildung kann das addieren von 
absoluten Größen doch durchaus sinnvoll sein:
Z.B. (10°C + 20°C) / 2 = 15°C ist IMHO eine sinnvolle Berechnung, obwohl 
hier zwei absolute Größen addiert werden.

Oder habe ich hier einen Denkfehler?

von Justus S. (jussa)


Lesenswert?

Boris B. schrieb:
> Oder habe ich hier einen Denkfehler?

Zeiger sind eben keine absolute Größen

von Karl H. (kbuchegg)


Lesenswert?

Boris B. schrieb:
> Karl Heinz Buchegger schrieb:
>> Weil es eine sinnlose Operation ist.
>
> In diesem konkreten Fall hast du Recht. Im Allgemeinen würde ich das
> aber so nicht sagen. Z.B. zur Mittelwertbildung kann das addieren von
> absoluten Größen doch durchaus sinnvoll sein:
> Z.B. (10°C + 20°C) / 2 = 15°C ist IMHO eine sinnvolle Berechnung, obwohl
> hier zwei absolute Größen addiert werden.
>
> Oder habe ich hier einen Denkfehler?

Was hast du numerisch gemacht.
Du hast die Distanz zwischen den beiden Temperaturen genommen
1
   T2 - T1
hast die halbiert
1
   ( T2 - T1 ) / 2
und dieses Distanz zu T1 dazugezählt
1
   T1 + ( T2 - T1 ) / 2

Bis hier her ist das eine sauber definierte Operation.
Was jetzt kommt ist dann einfach nur noch die Formel umgewandelt, um sie 
zu vereinfachen. Aber dadurch veränderst du an der Sinnhaftigkeit des 
Ergebnisses nichts mehr.

Deine 'hier sinnvolle Addition' von Temperaturen ist eine Folge der 
kompletten Operation. Im Allgemeinen ist es aber nicht sinnvoll 2 
Temperaturen zu addieren. Und nur weil man die korrekte Form der 
Mittelwertbildung mathematisch so umformen kann, dass Temperaturen 
addiert werden bedeutet das noch lange nicht, dass die Addition von 
Temperaturen im allgemeinen eine physikalische sinnvolle Operation ist.

: Bearbeitet durch User
von Robert L. (lrlr)


Lesenswert?

du meinst:
du hast den Pointer auf den Anfang eines Strings
und den Pointer auf das Ende eines Strings
und willst die Mitte wissen..

klingt Sinnvoll

komisch,
nachdem in C eigentlich sonst alles erlaubt ist, was gott und die welt 
verbieten würde...



(mit typecasting kann man natürlich 2 pointer addieren...)

von Peter II (Gast)


Lesenswert?

Robert L. schrieb:
> du hast den Pointer auf den Anfang eines Strings
> und den Pointer auf das Ende eines Strings
> und willst die Mitte wissen..

das ist doch kein Problem

char* mitte = anfang + ((ende-anfang)/2)

dafür muss man keine Zeiger addieren.

von Bastler (Gast)


Lesenswert?

Warum nicht auf den kleineren Pointer die halbe Differenz addieren.
Das ist alles erlaubt!
BTW, das mit der Addition bei der Temperatur funktioniert nur, weil 
diese nach oben nicht beschränkt ist. Bei 16bit Pointern ist 0x8000 + 
0x8002 aber schon ein Überlauf. Unterschied klar?

von Karl H. (kbuchegg)


Lesenswert?

Robert L. schrieb:
> du meinst:
> du hast den Pointer auf den Anfang eines Strings
> und den Pointer auf das Ende eines Strings
> und willst die Mitte wissen..

Die Mitte in welchem Sinn?
Im Sinne des Zahlenwertes der numerischen Adresse, die sich daraus 
ergibt? Oder im Sinne des mittleren Elementes?

Das sich das bei Hälfte und dem Datentyp char alles numerisch ausgeht, 
ist klar.
Aber das ist ein Sonderfall. Nimm mal anstelle von char den Typ int und 
anstelle von 'Hälfte' ein 'Drittel'.

Und dann überlegst du dir mal, was dir da jetzt alles bei diversen 
Arraygrößen passieren kann, wenn du Pointer einfach naiv numerisch 
addierst.

: Bearbeitet durch User
von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Möglicherweise will Christian ja gar nicht den "Zeiger auf" (Objekt) 
addieren, sondern den "Inhalt von Zeiger auf (Objekt)".

Vielleicht ist ihm dieser Unterschied des "Zeiger auf" und "inhalt von" 
gar nicht so richtig bewußt, und für ihn sind Zeiger ein Synonym für das 
eigentliche Objekt (also den Wert des Objekts)

: Bearbeitet durch User
von Robert L. (lrlr)


Lesenswert?

>Aber das ist ein Sonderfall. Nimm mal anstelle von char den Typ int und
>anstelle von 'Hälfte' ein 'Drittel'.

aha

kombinieren wir also mal die antworten:

>das ist doch kein Problem
>char* mitte = anfang + ((ende-anfang)/2)

ergibt:

int* drittel = anfang + ((ende-anfang)/3)

oder

int* drittel = ((anfang + anfang + ende)/3)

wobei ersteres "erlaubt" ist, zweites aber nicht (rechnerisch ist es das 
selbe..)

optisch zumindest (in Wirklichkeit natürlich nicht.. weil bei

>char* mitte = anfang + ((ende-anfang)/2)

ja hier ja internein  (* sizeOf(char)) gemacht wird
bzw. eben das " * SizeOf(int)"

>Und dann überlegst du dir mal, was dir da jetzt alles bei diversen
>Arraygrößen passieren kann, wenn du Pointer einfach naiv numerisch
>addierst.

ich weiß das schon, nur die "erlaubte" Version (siehe oben) ist auch 
nicht viel besser.. (im sinne von "idiotensicherer").
mit Pointer ist eben immer vorsicht geboten..

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Robert L. schrieb:

> ich weiß das schon, nur die "erlaubte" Version (siehe oben) ist auch
> nicht viel besser.. (im sinne von "idiotensicherer").

Doch ist sie.
Denn aus der Subtraktion bekommst du immer die Anzahl der Elemente 
zwischen dem ersten und dem zweiten Pointer raus. Eben wegen der 
impliziten sizeof Rechnerei.

Anzahl der Elemente! Und nicht Anzahl der Bytes.

von Bastler (Gast)


Lesenswert?

Robert L. schrieb:
> int* drittel = anfang + ((ende-anfang)/3)
>
> oder
>
> int* drittel = ((anfang + anfang + ende)/3)
Hä???
Vor dem Programmieren würde ich erst mal Mathe wiederholen.

anfang + ((ende-anfang)/3) = anfang + ende/3 - anfang/3 = anfang* 2/3 + 
ende/3

Das könnte man dann wieder im beschränkte Zahlenraum uint16 oder uint32 
in jedem Fall richtig rechnen. (Bitte die implizite Voraussetzung 
"anfang < ende" beachten!)

von Robert L. (lrlr)


Lesenswert?

>Vor dem Programmieren würde ich erst mal Mathe wiederholen.

lol

anfang + ((ende-anfang)/3) = anfang + ende/3 - anfang/3 = anfang* 2/3 +
ende/3 = (anfang * 2 + ende) / 3 = siehe oben..

von (prx) A. K. (prx)


Lesenswert?

Die richtige Mathe. Also die ohne Assoziativ- und Distributivgesetz.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Darum gehts doch gar nicht.

Es geht darum, dass ein Array aus 5 Stück 16 Bit int in Summe 10 Bytes 
verbraucht. Nehme ich davon über Pointer Arithmetik 1/3 her, dann kriege 
ich einen Pointer, der sicher nicht mehr auf einen int-Anfang zeigt.

Rechne ich das aber so, wie es mir C erlaubt, dann zeigt mein Pointer 
auf den 3-ten int im Array.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.