Die Bedeutung von void
void ist „typlos“, void * ist „typloser Zeiger“, der auf jeden Datentyp verweisen kann.
Verwendungsspezifikationen für Void-Zeiger
①Der Void-Zeiger kann auf jeden Datentyp zeigen, das heißt, ein Zeiger eines beliebigen Datentyps kann verwendet werden, um dem Void-Zeiger einen Wert zuzuweisen. Zum Beispiel:
int *pint;
void *pvoid; Sie müssen die Typkonvertierung erzwingen, z. B.: pint = (int *)pvoid;
Die Rolle von void
②Einschränkungen bei Funktionsparametern.
Wenn eine Funktion keinen Wert zurückgeben muss, muss die Void-Qualifikation verwendet werden. Zum Beispiel: void func(int, int);
Wenn eine Funktion keine Parameter akzeptieren darf, muss die Void-Qualifikation verwendet werden. Zum Beispiel: int func(void).
void * memcpy( void *dest, const void *src, size_t len );
void * memset( void * buffer, int c, size_t num );
Viele Anfänger sind verwirrt über die Zeigertypen void und void in der C/C++-Sprache, die nicht gut verstanden werden, daher gibt es einige Fehler bei der Verwendung. In diesem Artikel wird die tiefgreifende Bedeutung des Schlüsselworts void erläutert. Im Folgenden werden die Verwendungsmethoden und -techniken von void und den Zeigertypen void erläutert.
1. Regeln für die vorsichtige Verwendung von Void-Zeigertypen
Gemäß dem ANSI-Standard (American National Standards Institute) können arithmetische Operationen nicht auf Void-Zeigern ausgeführt werden, d. h. die folgenden Operationen sind illegal:void*pvoid;
pvoid++;//ANSI: Error
pvoid+=1;//ANSI: Error
//Der Grund, warum der ANSI-Standard dies erkennt, liegt darin, dass er darauf besteht, dass der Zeiger für algorithmisch ist Operationen müssen sicherstellen, dass der Datentyp bekannt ist, auf den sie verweisen.
//Zum Beispiel:
int*pint;
pint++;//ANSI: Richtig
Das Ergebnis von pint++ ist eine Vergrößerung von sizeof(int).
Aber das berühmte GNU (Abkürzung für GNU'sNotUnix) glaubt das nicht. Es legt fest, dass die Algorithmusoperation von void* mit char* übereinstimmt.
Die folgenden Anweisungen sind also im GNU-Compiler korrekt:
pvoid++; //GNU: korrekt
pvoid+=1; //GNU: korrekt
Das Ausführungsergebnis von pvoid++ ist, dass es um 1 erhöht wird .
Um den ANSI-Standard zu erfüllen und die Portabilität des Programms zu verbessern, können wir in der tatsächlichen Programmierung Code schreiben, um die gleiche Funktion wie folgt zu erreichen:
void*pvoid;
(char*)pvoid++; / /ANSI: richtig; GNU: richtig
(char*)pvoid+=1;//ANSI: falsch; GNU: richtig
Es gibt einige Unterschiede zwischen GNU und ANSI. als ANSI und bietet Unterstützung für mehr Syntaxen. Aber wenn wir im wirklichen Leben entwerfen, sollten wir uns dennoch so weit wie möglich an die ANSI-Standards halten.
2. Wenn der Parameter einer Funktion ein Zeiger eines beliebigen Typs sein kann, sollte sein Parameter als void* deklariert werden
void *memcpy(void*dest,constvoid*src,size_tlen);
void*memset(void*buffer,intc,size_tnum);
Auf diese Weise kann jede Art von Zeiger übergeben werden Memcpy und Memset verkörpern wirklich die Bedeutung der Speicheroperationsfunktion, da das von ihr betriebene Objekt nur ein Teil des Speichers ist, unabhängig davon, um welche Art von Speicher es sich handelt. Es wäre wirklich seltsam, wenn der Parametertyp von memcpy und memset nicht void*, sondern char* wäre! Solche Memcpy- und Memset-Funktionen sind offensichtlich keine „reinen, spaßfreien“ Funktionen!
Der folgende Code wird korrekt ausgeführt:
//Beispiel: memset akzeptiert Zeiger jeden Typs
int intarray[100];
memset(intarray,0,100*sizeof(int));//Intarray löschen 0
//Beispiel: memcpy akzeptiert jede Art von Zeiger
int intarray1[100], intarray2[100];
memcpy(intarray1,intarray2,100*sizeof(int));//Kopiere intarray2 nach intarray1
Interessant ist, dass die Funktionen memcpy und memset auch den Typ void* zurückgeben. Wie kompetent die Autoren der Standardbibliotheksfunktionen sind!
3. Regel 3: void kann keine reale Variable darstellen
voida; // Fehler
function(voida);//Error
void verkörpert eine Abstraktion. Variablen in dieser Welt sind alle „typisiert“. Beispielsweise ist eine Person entweder ein Mann oder eine Frau (und eine Transe?).
Das Erscheinungsbild von void dient nur einem abstrakten Bedarf. Wenn Sie das Konzept der „abstrakten Basisklasse“ im objektorientierten Bereich richtig verstehen, ist der Datentyp void leicht zu verstehen. So wie wir keine Instanz einer abstrakten Basisklasse definieren können, können wir auch keine void-Variable (nennen wir void analog einen „abstrakten Datentyp“) definieren.