จากคำตอบนี้ในวิศวกรรมซอฟต์แวร์ void
ได้รับการปฏิบัติเป็นพิเศษขึ้นอยู่กับวิธีการใช้งาน ในC
และC++
, void
ใช้เพื่อระบุตัวตนของประเภทข้อมูลที่ในขณะที่void *
ถูกนำมาใช้เพื่อระบุตัวชี้ที่จุดบางข้อมูล / พื้นที่ในหน่วยความจำที่ไม่ได้มีประเภท void *
ไม่สามารถยกเลิกการลงทะเบียนด้วยตนเองได้และจะต้องนำไปใช้กับประเภทอื่นก่อน ไม่จำเป็นต้องหล่อนี้มีความชัดเจนในแต่ต้องอยู่ในอย่างชัดเจนC
C++
(นี่คือสาเหตุที่เราไม่ส่งค่าส่งคืนของ malloc ซึ่งก็คือvoid *
)
เมื่อใช้กับฟังก์ชั่นเป็นพารามิเตอร์void
หมายถึงการขาดทั้งหมดของพารามิเตอร์ใด ๆ และเป็นพารามิเตอร์เดียวที่ได้รับอนุญาต ความพยายามในการใช้ช่องว่างเช่นประเภทตัวแปรหรือรวมอาร์กิวเมนต์อื่น ๆ ทำให้เกิดข้อผิดพลาดของคอมไพเลอร์:
int foo(void, int); //trying to use "void" as a parameter
int bar(void baz); //trying to use "void" as an argument's type
main.c:1:8: error: 'void' must be the first and only parameter if specified
int foo(void, int);
^
main.c:2:14: error: argument may not have 'void' type
int bar(void baz);
^
มันเป็นไปไม่ได้ในการประกาศตัวแปรด้วยชนิดvoid
:
int main(void) {
void qux; //trying to create a variable with type void
}
main.c:5:8: error: variable has incomplete type 'void'
void qux;
void
เป็นค่าตอบแทนสำหรับฟังก์ชั่นบ่งชี้ว่าไม่มีข้อมูลจะถูกส่งกลับ เนื่องจากเป็นไปไม่ได้ที่จะประกาศตัวแปรชนิดvoid
จึงไม่สามารถรับค่าส่งคืนของvoid
ฟังก์ชันได้แม้จะมีตัวชี้เป็นโมฆะก็ตาม
void foo(int i) { return; }
int main(void) {
void *j;
j = foo(0);
return 0;
}
main.c:5:5: error: assigning to 'void *' from
incompatible type 'void'
j = foo(0);
^ ~~~~~~
พิมพ์ดีดvoid *
เป็นกรณีอื่น ตัวชี้โมฆะบ่งชี้ตัวชี้ไปยังตำแหน่งในหน่วยความจำ แต่ไม่ได้ระบุชนิดของข้อมูลที่ตัวชี้นั้น (นี่คือการใช้เพื่อให้เกิดความหลากหลายใน Cเช่นกับฟังก์ชั่น qsort () ) พอยน์เตอร์เหล่านี้สามารถใช้งานได้ยากเนื่องจากเป็นเรื่องง่ายที่จะโยนมันผิดประเภท โค้ดด้านล่างจะไม่ส่งข้อผิดพลาดของคอมไพเลอร์C
แต่จะส่งผลให้เกิดพฤติกรรมที่ไม่ได้กำหนด:
#include <stdio.h>
int main(void) {
double foo = 47.2; //create a double
void *bar = &foo; //create a void pointer to that double
char *baz = bar; //create a char pointer from the void pointer, which
//is supposed to hold a double
fprintf(stdout, "%s\n", baz);
}
อย่างไรก็ตามรหัสต่อไปนี้ถูกกฎหมายอย่างสมบูรณ์ การส่งไปยังและจากตัวชี้โมฆะจะไม่เปลี่ยนค่าที่เก็บไว้
#include <stdio.h>
int main(void) {
double foo = 47.2;
void *bar = &foo;
double *baz = bar;
fprintf(stdout, "%f\n", *baz);
}
47.200000
ในฐานะที่เป็นพารามิเตอร์ฟังก์ชั่นvoid *
ระบุว่าชนิดของข้อมูลที่ตัวชี้ที่คุณกำลังส่งผ่านนั้นไม่เป็นที่รู้จักและมันก็ขึ้นอยู่กับคุณโปรแกรมเมอร์ที่จะจัดการสิ่งที่อยู่ในตำแหน่งหน่วยความจำนั้น ในฐานะที่เป็นค่าส่งคืนvoid *
แสดงว่าชนิดของข้อมูลที่ส่งคืนไม่เป็นที่รู้จักหรือไม่พิมพ์และจะต้องได้รับการจัดการโดยโปรแกรม
int quux(void *); //a function that receives a pointer to data whose type is not known, and returns an int.
void *quuz(int); //a function that receives an int, and returns a pointer to data whose type is not known.
tl; dr void
ในฟังก์ชั่นต้นแบบหมายถึง "ไม่มีข้อมูล" และระบุว่าไม่มีค่าส่งคืนหรือไม่มีพารามิเตอร์void *
ในต้นแบบฟังก์ชั่นหมายถึง "ข้อมูลที่ตัวชี้ฟังก์ชั่นนี้จะได้รับไม่มีประเภทที่รู้จัก" และระบุพารามิเตอร์หรือค่าตอบแทน ซึ่งตัวชี้ต้องถูกส่งไปยังชนิดที่แตกต่างกันก่อนที่จะสามารถใช้ข้อมูลที่ตัวชี้ได้