Autor Beitrag
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Sa 12.06.10 13:52 
Hi!

Bei Wikibooks ( de.wikibooks.org/wik...rundelemente/_Zeiger ) findet man folgendes:

Zitat:
void-Zeiger (anonyme Zeiger)

Eine besondere Rolle spielen die „Zeiger auf void“, die so genannten generischen Zeiger. Einem Zeiger vom Typ void* kann jeder beliebige Zeiger zugewiesen werden. void-Zeiger werden in der Sprache C z.B. bei der dynamischen Speicherverwaltung verwendet. In C++ kommt man weitgehend ohne sie aus. Vermeiden Sie Zeiger auf void wenn Sie eine andere Möglichkeit haben.

Eine Variable kann nicht vom Typ void sein. Daher würde folgende Zeile zu einem Fehler führen:

ausblenden C#-Quelltext
1:
void variable;					


Sie können einer Variable, die auf void zeigt, einen beliebigen Zeiger zuweisen. Deshalb werden solche Variablen meist für Zeiger verwendet, dessen Typ noch nicht feststeht und sich erst im Laufe des Programmes ergibt oder aber als temporärer Speicher mit wechselnden Zeigertypen.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
#include <iostream>

int main() {
    int intValue    = 1;
    int *intPointer = &intValue; // zeigt auf intValue

    void *voidPointer;
    voidPointer = intPointer; // voidPointer zeigt auf intPointer


Sie können jetzt nicht ohne Weiteres auf *voidPointer zugreifen, um an die Adresse von intValue zu bekommen. Da es sich um einen Zeiger, vom Typ void handelt, muss man diesen erst casten. In diesem Fall nach int*.


ausblenden C#-Quelltext
1:
2:
3:

    std::cout << *reinterpret_cast<int*>(voidPointer) << std::endl;
}


Ablauf im Detail:

1. Zeiger *voidPointer ist vom Typ void und zeigt auf intValue
2. reinterpret_cast<int*>, Zeiger ist vom Typ int*
3. Zeiger dereferenzieren ( *), um Wert zu erhalten


Ich verstehe irgendwie nicht ganz, warum das klappen soll. Das fängt hier an:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
int main() {
    int intValue    = 1;
    int *intPointer = &intValue; // zeigt auf intValue

    void *voidPointer;
    voidPointer = intPointer; // voidPointer zeigt auf intPointer


voidPointer zeigt auf intPointer? Müsste voidPointer nicht eher auf intValue zeigen? Hier wird doch der Zeiger und nicht seine Referenz übernommen, oder hat void* da eigene Syntaxregeln? Logischer wäre für mich dann eher das hier:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
void *voidPointer = intPointer;

bzw.

void *voidPointer;
voidPointer = &intPointer;


Vll. ein Tippfehler bei Wikibooks? Aber warum kann ich das dann nicht einfach so machen:

ausblenden C#-Quelltext
1:
2:
3:
4:
int  iValue    = 1;
int  *pValue   = &iValue;

int  addr = reinterpret_cast<int> (pValue);


Warum geht der eine Cast, aber der andere nicht?
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Sa 12.06.10 15:30 
Hey,

also das mit dem Zeiger auf intPointer is wirklich Mist! Das is ein und der selbe Zeiger, bloß das der eine eben vom Typ int is un der andere void is. Das mit der Ausgabe stimmt so. Erst sagst du das der voidPointer ein intPointer ist (mit (int*)) und dann holst du dir den Wert auf den der Pointer zeigt (mit * vor dem ganzen). Und die Zahl wird dann ausgegeben. Wenn du nur den voidPointer wieder in ein intPointer casten willst müsste das so aussehen:
int *intPointer = (int*)voidPointer;
Bei deinem Beispiel castest du den Pointer in ein int, heißt du zeigst die Adresse, auf die der Pointer zeigt als ein Integer an und nicht den Wert an der Adresse.

€: hier ma noch ein Bsp.:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
int main(int argc, char *argv[]){
    int intValue    = 1;
    int *intPointer = &intValue;

    void *voidPointer;
    voidPointer = intPointer; 

  int* intPointer2 = (int*)voidPointer;  //voidPointer in intPointer casten
  cout << *intPointer2;          //Zahl hinter intPointer ausgeben
  cout << *(int*)voidPointer;        //das gleich wie oben, bloß in einem Schritt

  cin.get();

  return 0;
}


MfG Bergmann.

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
Jakob_Ullmann Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Sa 12.06.10 16:45 
Danke!

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:

Bei deinem Beispiel castest du den Pointer in ein int, heißt du zeigst die Adresse, auf die der Pointer zeigt als ein Integer an und nicht den Wert an der Adresse.


Darum ging es mir ja auch. Aber so wie ich das verstanden hatte, war das ja auch das Ziel bei Wikibooks, aber der Abschnitt war wirklich sehr konfus geschrieben. Mir kam es nur halt komisch vor, dass man zum Holen der Adresse erst einen Umweg über void machen muss. Wobei: Delphi lässt ja auch nicht DWORD(Pointer) zu (aber in Delphi kann ich ja nicht mal einem Char ein Byte zuweisen. :P ).
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Sa 12.06.10 17:08 
user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Aber so wie ich das verstanden hatte, war das ja auch das Ziel bei Wikibooks
Denke ich nicht, es soll sicherlich
Zitat:
Sie können jetzt nicht ohne Weiteres auf *voidPointer zugreifen, um an die Adresseden Wert von intValue zu bekommen.
heißen. Dann passen Wort und Tat auch wieder zusammen ;) .

user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Wobei: Delphi lässt ja auch nicht DWORD(Pointer) zu
Seit wann das denn nicht mehr :gruebel: ?

user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
(aber in Delphi kann ich ja nicht mal einem Char ein Byte zuweisen. :P ).
Dürfte in C auch nicht ganz einfach werden, so ganz ohne Byte-Typ ;) .

_________________
>λ=
Greenberet
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 339
Erhaltene Danke: 20

Win 10
C# (VS 2012), C++ (VS 2012/GCC), PAWN(Notepad++), Java(NetBeans)
BeitragVerfasst: Sa 12.06.10 17:29 
user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Mir kam es nur halt komisch vor, dass man zum Holen der Adresse erst einen Umweg über void machen muss.


muss man doch nicht?

ausblenden C#-Quelltext
1:
&intValue; // zeigt auf intValue					

'&' holt die Adresse von intValue und diese weist du halt in dem Beispiel dem Pointer zu. du könntest dir das natürlich sparen und gleich direkt mit &intValue arbeiten.

user profile iconJakob_Ullmann hat folgendes geschrieben:

user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
(aber in Delphi kann ich ja nicht mal einem Char ein Byte zuweisen. :P ).
Dürfte in C auch nicht ganz einfach werden, so ganz ohne Byte-Typ ;) .

dann mach dir doch einfach einen :P
typedef unsigned char byte; voila ein Byte Datentyp wurde geboren ;)
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Sa 12.06.10 18:59 
Hey,

user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Mir kam es nur halt komisch vor, dass man zum Holen der Adresse erst einen Umweg über void machen muss.

Das kapitel heißt ja bestimmt nich "Pointer - Adresszuweisung" sondern "Einführung void-Pointer" das is bloß n dummes Bsp, welches an der Stelle überhaupt kein Sinn hat ;)

MfG Bergmann

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^