void pointer
-
Hi Leute!
Ich spielte mich gerade mit c so rum (void pointer) da kam mir eine Frage..
Um einen Void-Pointer zu interpretiern, bzw. mit dem auf das er zeigt arbeiten zu können, muss ich ihn casten. Doch warum kann ich das:
1. auf 2 Arten und
2. kann ich nur auf andere pointer casten oder in mit x=(int*)a direkt übergeben?Zum Test baute ich den kleinen Code:
#include <stdio.h> #include <stdlib.h> void ahh(void* a) { int* x=(void*) a; //mal so? *x=0; } void bee(void* b) { int* i=(int*) b;//mal so?? printf ("nachher ist b:%d",*i); } int main(void) { int a=6,b=12; printf ("vorher ist a:%d\n",a); ahh(&a); printf ("nachher ist a:%d\n",a); printf ("vorher ist b:%d\n",b); bee(&b); getch(); return 0; }
-
/FALSCH void ahh(void* a) { //Hier weis der kompiler das a ein void pointer ist // hier castet ud ein void auf ein void und kopierst den pointer bzw. adresse auf ein in :) geht zwar, aber der compiler müsste ne warung bringen;) int* x=(void*) a; //mal so? *x=0; } // RICHTIG void bee(void* b) { //hier weis der compiler b ist ein vodi pointer, uns sagst du willst ihn als in casten und weist diesen dann auch einem int pointer zu int* i=(int*) b;//mal so?? printf ("nachher ist b:%d",*i); }
-
In C braucht man void-Zeiger nicht zu casten, weil C implizit void* Zeiger kastet
void *foo; ... int *bar = (void*) foo;
geht, weil foo ein void* ist, (void*) foo ebenfalls ein void* und jedes void* lässt sich implizit "umwandeln". Deshalb sollte es keine Warnung geben.
void *foo; ... int *bar = (int*) foo;
ist in C unnötig, dennoch korrekt
void *foo; ... int *bar = foo;
auch möglich, weil Compiler implizit castet.
-
--
-
das heißt alle 2 schreiweisen sind das selbe und machen das gleiche..
zur sache void* nicht casten --> dann weiß er ja nicht wie er zu interpretiern hat char , int?? was hald dort steht.
und warum geht das nicht?:
void* a; int x; .. x=(int*)a; ..
ist für mich mündlich:nimm das wo der void hinzeigt interpretiere als int und weise x zu.oder verstehe ich da was falsch?
-
willi wills schrieb:
das heißt alle 2 schreiweisen sind das selbe und machen das gleiche..
hmm, nein, die sind nicht die selben Schreibweisen, sie tun zwar dasselbe, aber sind nicht unbedingt gleich.
willi wills schrieb:
und warum geht das nicht?:
void* a; int x; .. x=(int*)a; ..
ist für mich mündlich:nimm das wo der void hinzeigt interpretiere als int und weise x zu.oder verstehe ich da was falsch?
Bei
x=(int*)a;
interpretierst du den typenlosen Zeigera
als einen Interger-Zeiger und willst in eine Integer Variable zuweisen. Das ist ein Konflikt, denn es ist nicht garantiert, dass ein Int-Zeiger einem Integer Wert entspricht, hier geht es nicht worauf der Zeiger zeigt, sondern was der Zeiger (als Variable) speichert.Ein void-Zeiger kann man sich wie eine Referenz (nicht im C++ klassischen Sinne) auf eine Adresse im Speicher. Diese könnte eine Referenz auf ein int, oder double, oder struct was_auch_immer sein. Wenn du versucht zu deferenzieren (sprich über den Zeiger an die Daten zuzugreifen) wird der Compiler meckern, weil für ihn nur die Adresse bekannt ist, jedoch nicht wie der Speicher aufgebaut wird (noch die Größe, usw).
Ein int-Zeiger ist im Prinzip ein void-Zeiger (von der Funktionalität her) bloß mit dem Unterschied, dass der Compiler zu jedem Zeitpunkt annehmen darf, dass die Daten, worauf der Zeiger zeigt, int Daten sind (sprich 4 Bytes auf x86 Rechnern, usw). Mit der Zuweisung
x=(int*)a;
machst du nichts anders, als INTEGER wird eine ADRESSE zugewissen, also weist du unterschiedliche (möglicherweise inkopatibel) Daten zu. Du willst aber auf die Daten kommen, worauf der Zeiger zeigt, und damit musst du deferenzieren.void* a; int x; .. x=*(int*)a; /* *zeiger == zeiger[0] */ ..
-
danke supertux!!