(โปรดอ่านย่อหน้านี้ก่อนอ่านโพสต์ ฉันขอให้ทุกคนที่สนใจอ่านโพสต์นี้ควรพยายามอ่านอย่างละเอียดและแน่นอนว่าอย่าลงคะแนนจนกว่าคุณจะเข้าใจอย่างสมบูรณ์ขอบคุณ)
ตอนนี้เป็นวิกิชุมชนแล้วหากมีผู้ไม่เห็นด้วยกับแนวคิดใด ๆ โปรดแก้ไขพร้อมคำอธิบายที่ชัดเจนและละเอียดว่าอะไรผิดและทำไมและถ้าเป็นไปได้โปรดอ้างอิงแหล่งที่มาหรือแสดงหลักฐานที่สามารถทำซ้ำได้
ตอบ
นี่คือสาเหตุอื่น ๆ บางส่วนที่อาจเป็นปัจจัยพื้นฐานสำหรับ NULL == 0
- ความจริงที่ว่าศูนย์เป็นเท็จดังนั้นเราสามารถทำได้โดยตรง
if(!my_ptr)
แทนif(my_ptr==NULL)
แทน
- ความจริงที่ว่าจำนวนเต็มโกลบอลที่ไม่ได้เริ่มต้นจะถูกกำหนดค่าเริ่มต้นโดยค่าเริ่มต้นเป็นศูนย์ทั้งหมดและด้วยเหตุนี้ตัวชี้ของศูนย์ทั้งหมดจะถือว่าไม่ได้เริ่มต้น
ที่นี่ฉันอยากจะพูดคำเกี่ยวกับคำตอบอื่น ๆ
ไม่ใช่เพราะน้ำตาลสังเคราะห์
การบอกว่า NULL เป็นศูนย์เนื่องจากน้ำตาลในรูปแบบไวยากรณ์ไม่สมเหตุสมผลมากเกินไปถ้าอย่างนั้นทำไมไม่ใช้ดัชนี 0 ของอาร์เรย์เพื่อเก็บความยาว
ในความเป็นจริงภาษา C เป็นภาษาที่ใกล้เคียงกับการใช้งานภายในมากที่สุดมันสมเหตุสมผลหรือไม่ที่จะบอกว่า C เลือกศูนย์เพราะน้ำตาลวากยสัมพันธ์ พวกเขาต้องการให้คีย์เวิร์ดเป็นโมฆะ (เช่นเดียวกับภาษาอื่น ๆ ) แทนที่จะแมปศูนย์เป็นโมฆะ!
ในขณะที่ ณ วันนี้มันอาจเป็นเพียงแค่น้ำตาลในการสังเคราะห์ แต่ก็เป็นที่ชัดเจนว่าความตั้งใจเดิมของผู้พัฒนาภาษาซีไม่ได้มีไว้สำหรับน้ำตาลวากยสัมพันธ์ดังที่ฉันจะแสดงต่อไป
1) ข้อกำหนด
แม้ว่าจะเป็นความจริงที่ข้อกำหนด C พูดจากค่าคงที่ 0 เป็นตัวชี้ค่าว่าง (ส่วน 6.3.2.3) และยังกำหนดค่า NULL ที่จะนำไปใช้งาน (ส่วน 7.19 ในข้อกำหนด C11 และ 7.17 ในข้อกำหนด C99) ความจริงก็คือในหนังสือ "ภาษาโปรแกรมซี" ที่เขียนโดยผู้ประดิษฐ์ภาษาซีมีการระบุไว้ในส่วน 5.4:
C รับประกันว่าศูนย์ไม่ใช่ที่อยู่ที่ถูกต้องสำหรับข้อมูลดังนั้นจึงสามารถใช้ค่าที่ส่งคืนเป็นศูนย์เพื่อส่งสัญญาณเหตุการณ์ผิดปกติได้ในกรณีนี้จะไม่มีช่องว่าง
ตัวชี้และจำนวนเต็มไม่สามารถใช้แทนกันได้ศูนย์เป็นข้อยกเว้นเพียงอย่างเดียว: ค่าคงที่ศูนย์อาจถูกกำหนดให้กับตัวชี้และตัวชี้อาจเปรียบเทียบกับศูนย์คงที่ ค่าคงที่ที่เป็นสัญลักษณ์มักใช้แทนศูนย์เพื่อช่วยในการจำเพื่อระบุให้ชัดเจนยิ่งขึ้นว่านี่เป็นค่าพิเศษสำหรับตัวชี้ NULL ถูกกำหนดใน. เราจะใช้ NULL ต่อจากนี้ไป
อย่างที่เราเห็น (จากคำว่า "ที่อยู่ศูนย์") อย่างน้อยความตั้งใจเดิมของผู้เขียน C คือศูนย์ที่อยู่ไม่ใช่ศูนย์คงที่นอกจากนี้ยังปรากฏจากข้อความที่ตัดตอนมานี้ว่าสาเหตุที่ข้อกำหนดนั้นพูดจาก ค่าคงที่ศูนย์อาจไม่รวมนิพจน์ที่ประเมินค่าเป็นศูนย์ แต่ให้รวมค่าคงที่จำนวนเต็มศูนย์เป็นค่าคงที่จำนวนเต็มเดียวที่อนุญาตให้ใช้ในบริบทตัวชี้โดยไม่ต้องแคสต์
2) สรุป
ในขณะที่ข้อกำหนดไม่ได้กล่าวอย่างชัดเจนว่าที่อยู่ศูนย์สามารถปฏิบัติได้แตกต่างจากค่าคงที่เป็นศูนย์ แต่ก็ไม่ได้บอกว่าไม่และความจริงเมื่อจัดการกับค่าคงที่ของตัวชี้ nullก็ไม่ได้อ้างว่าเป็นการใช้งานที่กำหนดไว้ ทำโดยค่าคงที่กำหนดค่า NULLแทนที่จะอ้างว่าเป็นศูนย์แสดงว่าอาจมีความแตกต่างระหว่างค่าคงที่เป็นศูนย์และที่อยู่ศูนย์
(อย่างไรก็ตามหากเป็นกรณีนี้ฉันแค่สงสัยว่าเหตุใดจึงมีการกำหนดการใช้งาน NULL เนื่องจากในกรณีเช่นนี้ NULL อาจเป็นศูนย์คงที่ได้เช่นกันเนื่องจากคอมไพเลอร์ต้องแปลงค่าคงที่เป็นศูนย์ทั้งหมดให้เป็นค่า NULL ที่กำหนดไว้ในการนำไปใช้งานจริง)
อย่างไรก็ตามฉันไม่เห็นสิ่งนี้ในการดำเนินการจริงและในแพลตฟอร์มทั่วไปที่อยู่ศูนย์และศูนย์คงที่จะได้รับการปฏิบัติเหมือนกันและส่งข้อความแสดงข้อผิดพลาดเดียวกัน
นอกจากนี้ความจริงก็คือระบบปฏิบัติการในปัจจุบันกำลังสำรองหน้าแรกทั้งหมด (ช่วง 0x0000 ถึง 0xFFFF) เพียงเพื่อป้องกันการเข้าถึงที่อยู่ศูนย์เนื่องจากตัวชี้ NULL ของ C (ดูhttp://en.wikipedia.org/wiki/ Zero_pageเช่นเดียวกับ "Windows Via C / C ++ โดย Jeffrey Richter และ Christophe Nasarre (เผยแพร่โดย Microsoft Press)")
ดังนั้นฉันจะขอจากใครก็ตามที่อ้างว่าได้เห็นการทำงานจริงโปรดระบุแพลตฟอร์มและคอมไพเลอร์และรหัสที่แน่นอนที่เขาทำจริง (แม้ว่าจะมีคำจำกัดความที่คลุมเครือในข้อกำหนด [ดังที่ฉันได้แสดง] คอมไพเลอร์ใด ๆ และแพลตฟอร์มมีอิสระที่จะทำทุกอย่างที่เขาต้องการ)
อย่างไรก็ตามดูเหมือนว่าผู้เขียนของ C ไม่ได้คำนึงถึงเรื่องนี้และพวกเขากำลังพูดถึง "ที่อยู่ศูนย์" และ "C รับประกันว่าที่อยู่นี้ไม่มีวันถูกต้อง" เช่นเดียวกับ "NULL เป็นเพียง ช่วยในการจำ "ซึ่งแสดงให้เห็นอย่างชัดเจนว่าเจตนาเดิมไม่ได้มีไว้สำหรับ" น้ำตาลวากยสัมพันธ์ "
ไม่ใช่เพราะระบบปฏิบัติการ
นอกจากนี้ยังอ้างว่าระบบปฏิบัติการปฏิเสธการเข้าถึงที่อยู่ศูนย์ด้วยเหตุผลบางประการ:
1) เมื่อเขียน C ไม่มีข้อ จำกัด ดังที่เห็นในวิกิพีเดียนี้http://en.wikipedia.org/wiki/Zero_page http://en.wikipedia.org/wiki/Zero_page
2) ความจริงก็คือคอมไพเลอร์ C เข้าถึงหน่วยความจำที่อยู่เป็นศูนย์
สิ่งนี้ดูเหมือนจะเป็นข้อเท็จจริงจากบทความต่อไปนี้ของ BellLabs ( http://www.cs.bell-labs.com/who/dmr/primevalC.html )
คอมไพเลอร์ทั้งสองแตกต่างกันในรายละเอียดในการรับมือกับสิ่งนี้ ในก่อนหน้านี้การเริ่มต้นจะพบได้โดยการตั้งชื่อฟังก์ชัน ในภายหลังการเริ่มต้นจะกลายเป็น 0 เท่านั้นซึ่งบ่งชี้ว่าคอมไพเลอร์ตัวแรกถูกเขียนขึ้นก่อนที่เราจะมีเครื่องที่มีการแมปหน่วยความจำดังนั้นจุดเริ่มต้นของโปรแกรมไม่ได้อยู่ที่ตำแหน่ง 0 ในขณะที่เวลาของวินาที เรามี PDP-11 ที่จัดทำแผนที่
(ในความเป็นจริง ณ วันนี้ (ตามที่ฉันอ้างถึงข้างต้นจาก wikipedia และ microsoft press) สาเหตุของการ จำกัด การเข้าถึงที่อยู่เป็นศูนย์นั้นเป็นเพราะตัวชี้ NULL ของ C ดังนั้นในตอนท้ายมันก็กลายเป็นอีกทางหนึ่ง!)
3) โปรดจำไว้ว่า C ยังใช้ในการเขียนระบบปฏิบัติการและแม้แต่คอมไพเลอร์ C!
ในความเป็นจริง C ได้รับการพัฒนาเพื่อจุดประสงค์ในการเขียนระบบปฏิบัติการ UNIX ด้วยเหตุนี้จึงดูเหมือนจะไม่มีเหตุผลว่าทำไมพวกเขาจึงควร จำกัด ตัวเองจากศูนย์ที่อยู่
(ฮาร์ดแวร์) คำอธิบายเกี่ยวกับวิธีที่คอมพิวเตอร์ (ทางกายภาพ) สามารถเข้าถึง Address Zero ได้
มีอีกประเด็นหนึ่งที่ฉันต้องการจะอธิบายที่นี่เป็นไปได้อย่างไรที่จะอ้างอิงที่อยู่ศูนย์เลย?
คิดว่าเป็นวินาทีที่อยู่จะถูกดึงโดยโปรเซสเซอร์จากนั้นส่งเป็นแรงดันไฟฟ้าบนบัสหน่วยความจำซึ่งระบบหน่วยความจำจะใช้เพื่อไปยังที่อยู่จริง แต่ที่อยู่เป็นศูนย์จะหมายความว่าไม่มีแรงดันไฟฟ้า ดังนั้นฮาร์ดแวร์ทางกายภาพของระบบหน่วยความจำจึงเข้าถึงที่อยู่เป็นศูนย์ได้อย่างไร?
คำตอบดูเหมือนจะเป็นศูนย์ที่อยู่นั้นเป็นค่าเริ่มต้นและกล่าวอีกนัยหนึ่งที่อยู่ศูนย์จะสามารถเข้าถึงได้โดยระบบหน่วยความจำเสมอเมื่อบัสหน่วยความจำปิดอยู่อย่างสมบูรณ์และด้วยเหตุนี้คำขอใด ๆ ที่จะอ่านหรือเขียนโดยไม่ระบุที่อยู่จริง (ซึ่ง คือกรณีที่มีที่อยู่เป็นศูนย์) จะเข้าถึงที่อยู่ศูนย์โดยอัตโนมัติ
if (p != 0)
ไปif (p)
ซึ่งเป็นสำนวนที่พบบ่อยใน C และ C ++ ถึงแม้ว่าคุณจะต้องได้รับออกมาจากนิสัยถ้าคุณใช้เวลาถึง Java