การมองหาพื้นฐานที่คำว่า " โมฆะ " มาจากไหนและทำไมจึงเรียกว่าโมฆะ จุดประสงค์ของคำถามคือช่วยคนที่ไม่มีประสบการณ์เกี่ยวกับ C และจู่ๆก็มองไปที่ codebase บนพื้นฐานของ C
การมองหาพื้นฐานที่คำว่า " โมฆะ " มาจากไหนและทำไมจึงเรียกว่าโมฆะ จุดประสงค์ของคำถามคือช่วยคนที่ไม่มีประสบการณ์เกี่ยวกับ C และจู่ๆก็มองไปที่ codebase บนพื้นฐานของ C
คำตอบ:
โดยทั่วไปมันหมายถึง "ไม่มีอะไร" หรือ "ไม่มีประเภท"
มี 3 วิธีพื้นฐานที่ใช้เป็นโมฆะ:
อาร์กิวเมนต์ของฟังก์ชัน: int myFunc(void)
- ฟังก์ชันไม่ทำอะไรเลย
ฟังก์ชั่นคืนค่า: void myFunc(int)
- ฟังก์ชั่นคืนค่าอะไร
ตัวชี้ข้อมูลทั่วไป: void* data
- 'data' เป็นตัวชี้ไปยังข้อมูลประเภทที่ไม่รู้จักและไม่สามารถถูกปฏิเสธได้
หมายเหตุ: void
อาร์กิวเมนต์ในฟังก์ชั่นเป็นตัวเลือกใน C ++ ดังนั้นจึงint myFunc()
เป็นเช่นเดียวกับint myFunc(void)
และมันถูกทิ้งไว้อย่างสมบูรณ์ใน C # มันจำเป็นสำหรับค่าส่งคืนเสมอ
ฉันได้นำเสมอว่ามันหมายถึงขาด ต่อไปนี้เป็นสี่กรณีในภาษา C ที่ตรงกับการใช้งานที่ไม่มีอยู่
R f(void)
- ขาดฟังก์ชั่นพารามิเตอร์void f(P)
- ค่าที่ส่งกลับคือขาดvoid *p
- ประเภทของสิ่งที่ชี้ไปยังขาดอยู่(void) p
- ขาดการใช้งานมูลค่าลูกหลาน C คนอื่นใช้มันเพื่อสิ่งอื่น D
ภาษาการเขียนโปรแกรมใช้มันสำหรับกรณีที่ซึ่งการเริ่มต้นคือขาด
T t = void;
- ค่าเริ่มต้นคือขาด(void)p
ทำอย่างไร ฉันไม่ได้รับสิ่งที่คุณหมายถึงโดย "การใช้งานของมูลค่าขาด"
(void) var;
คำสั่งฉันได้พบคำตอบรายละเอียดที่stackoverflow.com/q/21045615
มีสองวิธีในการใช้ช่องว่าง:
void foo(void);
หรือ
void *bar(void*);
ตัวแรกระบุว่าไม่มีการส่งผ่านอาร์กิวเมนต์หรือไม่มีการส่งคืนอาร์กิวเมนต์
ที่สองบอกคอมไพเลอร์ว่าไม่มีประเภทที่เกี่ยวข้องกับข้อมูลได้อย่างมีประสิทธิภาพซึ่งหมายความว่าคุณไม่สามารถใช้ข้อมูลที่ชี้ไปจนกว่าจะส่งไปยังประเภทที่รู้จัก
ตัวอย่างเช่นคุณจะเห็นการvoid*
ใช้งานจำนวนมากเมื่อคุณมีอินเทอร์เฟซที่เรียกใช้ฟังก์ชันซึ่งพารามิเตอร์ไม่สามารถทราบล่วงหน้าได้
ตัวอย่างเช่นในเคอร์เนล Linux เมื่อเลื่อนการทำงานคุณจะตั้งค่าฟังก์ชั่นที่จะทำงานในเวลาต่อมาโดยให้มันเป็นตัวชี้ไปยังฟังก์ชั่นที่จะทำงานและตัวชี้ไปยังข้อมูลที่จะส่งผ่านไปยังฟังก์ชั่น:
struct _deferred_work {
sruct list_head mylist;
.worker_func = bar;
.data = somedata;
} deferred_work;
จากนั้นเคอร์เนลเธรดจะผ่านรายการของงานที่ถูกเลื่อนออกไปและเมื่อมันไปถึงโหนดนี้มันจะทำงานได้อย่างมีประสิทธิภาพ:
bar(somedata);
จากนั้นในบาร์คุณมี:
void bar(void* mydata) {
int *data = mydata;
/* do something with data */;
}
มันหมายถึง "ไม่มีค่า" คุณใช้void
เพื่อระบุว่าฟังก์ชันไม่ส่งคืนค่าหรือไม่มีพารามิเตอร์หรือทั้งสองอย่าง ค่อนข้างสอดคล้องกับการใช้คำในภาษาอังกฤษเป็นโมฆะ
มันบ่งบอกถึงการไม่มีค่าตอบแทนในฟังก์ชั่น
บางภาษามีรูทีนย่อยสองประเภท: ขั้นตอนและฟังก์ชั่น ขั้นตอนเป็นเพียงลำดับของการดำเนินการในขณะที่ฟังก์ชั่นเป็นลำดับของการดำเนินการที่ส่งกลับผลลัพธ์
ใน C และอนุพันธ์ของความแตกต่างระหว่างทั้งสองไม่ชัดเจน ทุกอย่างนั้นเป็นฟังก์ชั่น void
คำหลักที่แสดงให้เห็นว่ามันไม่ได้เป็น "จริง" ฟังก์ชั่นเพราะมันไม่ได้ส่งกลับค่า
คิดว่าเป็นโมฆะในฐานะ "โครงสร้างที่ว่างเปล่า" ให้ฉันอธิบาย
ทุกฟังก์ชั่นใช้ลำดับของพารามิเตอร์โดยที่แต่ละพารามิเตอร์มีประเภท ในความเป็นจริงเราสามารถรวมพารามิเตอร์เข้าไปในโครงสร้างด้วยสล็อตโครงสร้างที่สอดคล้องกับพารามิเตอร์ ทำให้ทุกฟังก์ชั่นมีอาร์กิวเมนต์เดียว ในทำนองเดียวกันฟังก์ชั่นสร้างผลลัพธ์ซึ่งมีประเภท มันอาจเป็นบูลีนหรืออาจลอยหรืออาจเป็นโครงสร้างที่มีชุดค่าพิมพ์อื่นโดยพลการ ถ้าเราต้องการ languge ที่มีค่าส่งคืนหลายค่ามันเป็นเรื่องง่ายเพียงแค่ยืนยันว่าพวกเขาจะถูกบรรจุลงในโครงสร้าง ในความเป็นจริงเราสามารถยืนยันได้เสมอว่าฟังก์ชั่นคืนโครงสร้าง ตอนนี้ทุกฟังก์ชั่นรับอาร์กิวเมนต์เดียวและสร้างหนึ่งค่า
ตอนนี้จะเกิดอะไรขึ้นเมื่อฉันต้องการฟังก์ชั่นที่สร้างค่า "ไม่" เอาล่ะลองพิจารณาสิ่งที่ฉันได้รับเมื่อสร้างโครงสร้างที่มี 3 สล็อต: มันมีค่า 3 ค่า เมื่อฉันมี 2 สล็อตมันเก็บค่าสองค่า เมื่อมันมีหนึ่งช่องหนึ่งค่า และเมื่อมันมีช่องว่างเป็นศูนย์ก็จะถือ ... เอ่อ, ค่าศูนย์หรือ "ไม่มี" ค่า "ดังนั้นฉันสามารถคิดว่าฟังก์ชั่นกลับเป็นโมฆะเป็นคืนโครงสร้างที่มีค่าไม่มีคุณยังสามารถตัดสินใจว่า" โมฆะ " เป็นเพียงคำพ้องความหมายสำหรับประเภทที่แสดงโดยโครงสร้างที่ว่างเปล่ามากกว่าคำหลักในภาษา (อาจเป็นเพียงประเภทที่กำหนดไว้ล่วงหน้า :)
ในทำนองเดียวกันฉันสามารถคิดได้ว่าฟังก์ชั่นที่ไม่ต้องการค่าใด ๆ เป็นการยอมรับโครงสร้างที่ว่างเปล่าเช่น "void"
ฉันยังสามารถใช้ภาษาโปรแกรมของฉันด้วยวิธีนี้ การส่งค่าเป็นโมฆะใช้เวลาเป็นศูนย์ไบต์ดังนั้นการผ่านค่าโมฆะเป็นเพียงกรณีพิเศษในการส่งผ่านค่าอื่น ๆ ที่มีขนาดตามอำเภอใจ สิ่งนี้ทำให้ง่ายสำหรับคอมไพเลอร์ในการรักษาผลหรือโมฆะ "โมฆะ" คุณอาจต้องการฟีเจอร์ที่ทำให้ฟังก์ชั่นหลุดออกไป ใน C ถ้าคุณเรียกใช้ฟังก์ชันผลลัพธ์ non-void foo ในคำสั่งต่อไปนี้: foo (... ); คอมไพเลอร์รู้ว่าฟูสร้างผลลัพธ์และไม่สนใจเลย ถ้าเป็นโมฆะเป็นค่าการทำงานอย่างสมบูรณ์แบบและตอนนี้ "ขั้นตอน" (ซึ่งเป็นเพียงคำคุณศัพท์สำหรับฟังก์ชั่นที่มีผลเป็นโมฆะ) เป็นเพียงกรณีพิเศษเล็กน้อยของฟังก์ชั่นทั่วไป
Void * สนุกขึ้นเล็กน้อย ฉันไม่คิดว่านักออกแบบ C คิดว่าเป็นโมฆะในวิธีข้างต้น พวกเขาเพิ่งสร้างคำหลัก คำหลักนั้นพร้อมใช้งานเมื่อมีคนต้องการชี้ไปที่ประเภทที่กำหนดเองจึงเป็นโมฆะ * เป็นสำนวนใน C. มันใช้งานได้ดีจริง ๆ ถ้าคุณตีความโมฆะว่าเป็นโครงสร้างที่ว่างเปล่า ตัวชี้โมฆะ * คือที่อยู่ของสถานที่ซึ่งวางโครงสร้างว่างไว้
ปลดเปลื้องจากโมฆะ * เป็น T * สำหรับประเภทอื่น T ยังทำงานกับมุมมองนี้ ตัวชี้การร่ายเป็นสูตรสมบูรณ์ที่ทำงานบนสถาปัตยกรรมทั่วไปส่วนใหญ่เพื่อใช้ประโยชน์จากความจริงที่ว่าถ้าชนิดผสม T มีองค์ประกอบที่มีชนิดย่อย S วางทางกายภาพที่จุดเริ่มต้นของ T ในรูปแบบการจัดเก็บแล้วหล่อ S * ถึง T * และ ในทางกลับกันโดยใช้ที่อยู่ทางกายภาพของเครื่องเดียวกันมีแนวโน้มที่จะทำงานออกมาเนื่องจากตัวชี้ของเครื่องส่วนใหญ่มีการแสดงเพียงครั้งเดียว การแทนที่ type S ด้วยโมฆะ type นั้นให้ผลเหมือนกันทุกประการดังนั้นการร่ายไปยัง / จาก void * จะได้ผล
ภาษาการเขียนโปรแกรม PARLANSE ใช้ความคิดข้างต้นอย่างใกล้ชิด เราหลงทางในการออกแบบและไม่ใส่ใจกับ "โมฆะ" ในฐานะประเภทส่งคืนและมีคำหลักที่เป็นคำแนะนำสำหรับกระบวนการ ส่วนใหญ่เป็นเพียงการเปลี่ยนแปลงทางไวยากรณ์อย่างง่าย แต่สิ่งหนึ่งที่คุณไม่ได้ทำเมื่อคุณได้รับรหัสการทำงานที่ใหญ่ในภาษา
ใน c # คุณจะต้องใช้คำหลักที่เป็นโมฆะเพื่อระบุว่าวิธีการใดไม่ส่งคืนค่า:
public void DoSomeWork()
{
//some work
}
กรณีการใช้งานสามกรณีสำหรับโมฆะ:
ฟังก์ชั่นลายเซ็นต์ void foo(int bar)
ไม่ส่งคืนค่า int bar(void)
ไม่ใช้พารามิเตอร์ใด ๆ int bar()
แต่นี้มักจะแสดงกับรายการอาร์กิวเมนต์ที่ว่างเปล่า การใช้คำสำคัญเป็นโมฆะที่นี่ตรงกับความหมายในภาษาอังกฤษ
ตัวชี้ชนิดด้านบนทั่วไปvoid *
ที่ชี้ไปยังข้อมูลที่ไม่ระบุและไม่สามารถยกเลิกการลงทะเบียนได้ ที่นี่ความหมายของโมฆะแตกต่างจากความหมายอื่น ๆ ของโมฆะ: ประเภทสากลกับไม่มีประเภท
ในการปลดเปลื้องเช่น(void) new Foo(this)
มีความหมายว่ามูลค่าส่งคืนจะถูกโยนทิ้งไปอย่างจงใจ นี่คือการใช้คำหลักตรงกับความหมายในภาษาอังกฤษ
กรณีที่ 1 และ 2 ถูกครอบคลุมโดย @Gerald แต่กรณีที่ 3 ยังไม่ได้รับการแก้ไข
หากคุณกำลังอธิบายแนวคิดให้กับผู้เริ่มต้นอาจเป็นประโยชน์ในการใช้การเปรียบเทียบ การใช้ช่องว่างในทุกกรณีเหล่านี้คล้ายคลึงกับความหมายของหน้าในหนังสือที่มีคำต่อไปนี้ "หน้านี้ปล่อยว่างไว้โดยเจตนา" เป็นการแยกความแตกต่างระหว่างคอมไพเลอร์ระหว่างสิ่งที่ควรถูกตั้งค่าสถานะเป็นข้อผิดพลาดเมื่อเทียบกับชนิดที่ตั้งใจเว้นว่างไว้เนื่องจากเป็นลักษณะการทำงานที่คุณต้องการ
มันมักจะปรากฏในรหัสที่โดยปกติคุณคาดว่าจะเห็นประเภทปรากฏขึ้นเช่นประเภทกลับหรือประเภทตัวชี้ นี่คือเหตุผลใน C # โมฆะแมปประเภท CLR จริง System.Void เนื่องจากเป็นชนิดในตัวเอง
ภาษาการเขียนโปรแกรมบางภาษาไม่เคยพัฒนาแนวคิดเกี่ยวกับความว่างเปล่าเช่นเดียวกับวัฒนธรรมของมนุษย์บางคนที่ไม่เคยคิดค้นแนวคิดของเลขศูนย์ โมฆะแสดงถึงความก้าวหน้าในภาษาโปรแกรมเหมือนกับแนวคิดของ zero หมายถึงภาษามนุษย์
มันหมายถึง "ไม่มีค่า" คุณใช้โมฆะเพื่อระบุว่าฟังก์ชั่นไม่ส่งคืนค่าหรือไม่มีพารามิเตอร์หรือทั้งสองอย่างมันสอดคล้องกับการใช้คำว่าโมฆะในภาษาอังกฤษโดยทั่วไป
โมฆะไม่ควรสับสนกับ null Null หมายถึงตัวแปรที่มีที่อยู่บนสแต็กค่าบนฮีปสำหรับที่อยู่นั้นว่างเปล่า
โมฆะใช้ในลายเซ็นวิธีเท่านั้น สำหรับประเภทการส่งคืนหมายถึงวิธีการจะไม่ส่งคืนรหัสใด ๆ สำหรับพารามิเตอร์หมายความว่าจะไม่มีการส่งพารามิเตอร์ไปยังเมธอด
เช่น
void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}
ใน C # เราสามารถละเว้นโมฆะสำหรับพารามิเตอร์และสามารถเขียนโค้ดข้างต้นเป็น:
void MethodThatReturnsAndTakesVoid()
{
// Method body
}
โมฆะไม่ควรสับสนกับ null Null หมายถึงตัวแปรที่มีที่อยู่บนสแต็กค่าบนฮีปสำหรับที่อยู่นั้นว่างเปล่า
Void เป็นชนิดที่ไม่สมบูรณ์ซึ่งตามนิยามแล้วจะไม่สามารถเป็น lvalue ได้ นั่นหมายความว่าไม่สามารถกำหนดค่าได้
ดังนั้นจึงไม่สามารถเก็บค่าใด ๆ
ถือเป็นโมฆะหมายความว่าคุณจะไม่ส่งคืนค่าใด ๆ ในรูปแบบฟังก์ชั่นหรือวิธีการ
Void หมายถึงไม่จำเป็นต้องใช้ค่าในประเภทส่งคืนจากฟังก์ชันในทั้งสามภาษา
Void เทียบเท่ากับ Sub ของ Visual Basic