เหตุใด C ใช้เครื่องหมายดอกจันสำหรับพอยน์เตอร์ [ปิด]


21

ฉันเพิ่งจะเรียนรู้เกี่ยวกับ C.

ฉันคิดว่ามันแปลกที่ผู้สร้างเลือกเครื่องหมายดอกจัน ( *) เป็นสัญลักษณ์สำหรับพอยน์เตอร์แทนที่จะเป็นสัญลักษณ์ที่ดูเหมือนตัวชี้ ( ->)

พิจารณาว่าตัวชี้การลงทะเบียนและฟังก์ชั่นที่ทำให้เกิดความสับสนสามารถมีเหตุผลทางประวัติศาสตร์หรือทางปฏิบัติได้หรือไม่สำหรับการใช้เครื่องหมายดอกจัน


10
โปรดทราบว่า->มีการใช้งานในภาษา C เป็นตัวดำเนินการอ้างอิง - เมื่อเข้าถึงฟิลด์ในโครงสร้าง: struct_pointer->fieldซึ่งย่อมา(*struct_pointer).fieldจาก
amon

@ มอน: มันใช้structsสำหรับการลดความอ้วนเท่านั้นซึ่งมันแปลกสำหรับฉัน มันเป็นสัญลักษณ์ตัวชี้ใช่มั้ย ทำไมไม่ ( <-) สำหรับการยกเลิกการอ้างอิง ฉันเป็นคนเดียวที่คิดแบบนี้จริงๆหรือ
Noob Saibot

1
ด้วยสองคำตอบที่ยอดเยี่ยมในคำถามนี้รวมถึงคำตอบที่ได้รับโดยตรงจากนักออกแบบภาษามันยากที่จะพิสูจน์ความใกล้ชิดว่า "อิงตามความคิดเห็น" ฉันจึงเสนอชื่อเพื่อเปิดใหม่
จูลส์

IMHO Pascal style ดีกว่า ^ถูกใช้และสามารถนึกถึงลูกศรที่หมุนแล้วและอ่านเป็น "ชี้ไปที่" ซึ่งมีความหมายเหมือนกัน->แต่สั้นกว่า ^integerหมายถึง "ตัวชี้ไปยังจำนวนเต็ม" สำหรับการประกาศชนิดและvar^หมายถึง "หน่วยความจำvarชี้ไปที่" สำหรับการยกเลิกการอ้างอิง ตำแหน่งสัญลักษณ์มีเหตุผลมากกว่า C เมื่ออ่านจากซ้ายไปขวาซึ่งจะใส่หลังจากพิมพ์และก่อนชื่อตัวแปรเสมอ นอกจากนี้ยังใช้ปาสกาล@สำหรับการอยู่ซึ่งจะดีกว่า&เพราะ@varเป็น "อยู่ที่ var ตั้งอยู่"
phuclv

คำตอบ:


59

เหตุใด C ใช้เครื่องหมายดอกจันสำหรับพอยน์เตอร์

เพียงเพราะBทำ

เนื่องจากหน่วยความจำเป็นอาร์เรย์แบบเส้นตรงจึงเป็นไปได้ที่จะตีความค่าในเซลล์เป็นดัชนีในอาร์เรย์นี้และ BCPL จะส่งโอเปอเรเตอร์เพื่อจุดประสงค์นี้ ในภาษาต้นฉบับที่มันถูกสะกดrvและต่อมา!ในขณะที่ B *ใช้เอก ดังนั้นถ้าpเป็นเซลล์ที่มีดัชนีของ (หรือที่อยู่) หรือตัวชี้ไปยัง) เซลล์อื่น*pหมายถึงเนื้อหาของเซลล์ชี้ไปที่ไม่ว่าจะเป็นค่าในการแสดงออกหรือเป็นเป้าหมายของการมอบหมาย

จากการพัฒนาภาษา C

แค่นั้นแหละ. ณ จุดนี้คำถามนี้ไม่น่าสนใจเหมือน "ทำไมไพ ธ อน 3 ใช้.วิธีเรียกเมธอดทำไม->? อืม ... เพราะ Python 2 ใช้.เพื่อเรียกเมธอด

ภาษาไม่ได้มีอยู่จริงจากสิ่งใด มันมีอิทธิพลและอยู่บนพื้นฐานของสิ่งที่มาก่อน


ดังนั้นเหตุใด B จึงไม่ใช้!สำหรับการยกเลิกการอ้างอิงตัวชี้เหมือนกับรุ่นก่อนของ BCPL

BCPL เป็นคำที่พูดไม่ออก แทนที่จะ&&หรือ||BCPL ใช้และlogand logorนี่เป็นเพราะคีย์บอร์ดส่วนใหญ่ไม่มีหรือมีคีย์และไม่เท่ากันจริง ๆ แล้วคำว่าNEQV(ดูคู่มืออ้างอิง BCPL )

B ดูเหมือนจะได้รับแรงบันดาลใจบางส่วนเพื่อทำให้ไวยากรณ์แน่นขึ้นแทนที่จะมีคำยาวสำหรับตัวดำเนินการเชิงตรรกะเหล่านี้ทั้งหมดที่โปรแกรมเมอร์ทำค่อนข้างบ่อย และด้วยเหตุนี้จึง!กลายเป็น*สิ่งที่!สามารถนำมาใช้เพื่อการปฏิเสธแบบตรรกะ โปรดสังเกตว่ามีความแตกต่างระหว่างตัวดำเนิน*การเอกและตัวดำเนินการไบนารี*(การคูณ)


แล้วมีทางเลือกอื่นอีก->ไหม

->ถูกนำสำหรับน้ำตาลประโยครอบ derefrences ฟิลด์struct_pointer->fieldซึ่งเป็น(*struct_pointer).field

ตัวเลือกอื่น ๆ เช่น<-สามารถสร้างการแยกวิเคราะห์ที่ไม่ชัดเจน ตัวอย่างเช่น:

 foo <- bar

คือการที่จะอ่านเป็น:

(foo) <- (bar)

หรือ

(foo) < (-bar)

การสร้างโอเปอเรเตอร์ยูนารีที่ประกอบด้วยโอเปอเรเตอร์ไบนารี่และโอเปอเรเตอร์ยูนารีอีกอันค่อนข้างมีปัญหาเนื่องจากตัวดำเนินการยูนารีที่สองอาจเป็นคำนำหน้าสำหรับนิพจน์อื่น

ยิ่งไปกว่านั้นมันเป็นสิ่งสำคัญอีกครั้งที่จะพยายามทำให้สิ่งต่าง ๆ ถูกพิมพ์บ่อยครั้งให้น้อยที่สุด ฉันเกลียดที่จะต้องเขียน:

int main(int argc, char->-> argv, char->-> envp)

สิ่งนี้จะยากต่อการอ่าน

อาจมีตัวละครอื่น ๆ ที่เป็นไปได้ ( @ไม่ได้ใช้จนกว่าObjective C จะจัดสรรให้ ) แม้ว่าจะเป็นเช่นนี้สิ่งนี้จะไปที่แกนกลางของ 'C ใช้*เพราะ B ทำ' ทำไมไม่ใช้ B @? เอาล่ะ B ไม่ได้ใช้ตัวละครทั้งหมด ไม่มีbppโปรแกรม (เปรียบเทียบcpp ) และอักขระอื่น ๆ พร้อมใช้งานใน B (เช่น#ซึ่งถูกใช้โดย cpp ในภายหลัง)

หากฉันอาจเป็นอันตรายต่อการเดาว่าทำไม - เพราะกุญแจอยู่ตรงไหน จากคู่มือใน B :

เพื่ออำนวยความสะดวกการจัดการของที่อยู่เมื่อมันดูเหมือนว่าแนะนำให้เลือก B มีสองผู้ประกอบการที่อยู่เอก, และ* เป็นผู้ดำเนินการที่อยู่ดังนั้นจึงเป็นที่อยู่ของสมมติว่ามันมีหนึ่ง เป็นผู้ดำเนินการทางอ้อม หมายถึง "ใช้เนื้อหาของ x เป็นที่อยู่"&&&xx**x

โปรดทราบว่า&shift-7 และ*shift-8 ความใกล้ชิดกันอาจเป็นคำใบ้ต่อโปรแกรมเมอร์ว่าพวกเขาทำอะไร ... แต่นั่นเป็นเพียงการเดา เราต้องถาม Ken Thompsonเกี่ยวกับสาเหตุที่เลือกมา


ดังนั้นคุณมีมัน C เป็นอย่างนั้นเพราะ B คือ B เป็นอย่างนั้นเพราะมันต้องการเปลี่ยนจากวิธี BCPL


2
... น่ากลัว! นี่เป็นคำตอบที่ยอดเยี่ยม @MichaelT! คุณแสดงให้ฉันเห็นทั้งเหตุผลในอดีตและในทางปฏิบัติและแม้แต่สิ่งที่ฉันไม่เข้าใจ แต่ก็สามารถดูได้ ขอขอบคุณ. +1
Noob Saibot

@NoobSaibot ตัวเลือกของตัวละครนั้นไม่ได้มีอะไรมากมายนักเนื่องจากข้อเท็จจริงที่ว่าโอเปอเรเตอร์นั้นเป็นแบบ prepend มากกว่าโอเปอเรเตอร์ที่เลื่อนออกไป สิ่งนี้จำเป็นต้องมี parens พิเศษจำนวนมาก (แม้ว่า -> น้ำตาลช่วยในการสร้างประโยค) ซึ่งสามารถนำไปสู่ข้อผิดพลาดที่งี่เง่า แต่น่ารำคาญแม้กระทั่งสำหรับโปรแกรมเมอร์ C ++ ที่มีประสบการณ์
ทริกซี่หมาป่า

1
คุณอาจพูดถึงว่า C พบการใช้งานสำหรับตัวละครเครื่องหมายวรรคตอน Ascii เกือบทุกตัว ไม่มีอะไหล่เหลืออยู่มากมาย ฉันเดาว่า@คงเป็นไปได้อีกอย่าง
david.pfx

1
@ david.pfx ฉันได้ขยายไปถึงแม้ว่ามันจะไม่ใช่ซีที่ทำให้มันเป็นตัวเลือก ... มันก็คือบีและก็ฉันก็เดาได้ว่าทำไม (ใกล้กับคีย์บอร์ด&และ*) B ยังไม่ได้ใช้#จึงมีเป็นอะไหล่อีกไม่กี่รอบแล้ว ... $นอกจากนี้ยังมี

1
@ david.pfx บทช่วยสอน Bที่ฉันพบถูกเขียนขึ้นโดย BW Kernighan น่าเสียดายที่เดนนิสริชชี่ไม่สามารถถูกถามได้อีกต่อไป (เขาจากไปในเดือนตุลาคมของปี 11) ในขณะที่ Kernighan ยังคงเป็นศาสตราจารย์ในภาควิชา CS ที่ Princeton Ken Thompson (ผู้สร้าง B คนอื่น) ทำงานที่ Google ... อาจมีปัญหากับแป้นพิมพ์บางตัว (ระบุโดย trigraphs สำหรับ C สำหรับสิ่งที่เราคิดว่าเป็นกุญแจทั่วไป) แนะนำว่าไม่สามารถใช้งานได้ทั้งหมด ( ฉันไม่แน่ใจว่า '@' เป็น)

55

ฉันถูกนักเรียนคนหนึ่งถาม&และ*เลือกเพราะพวกเขาอยู่ติดกันบนคีย์บอร์ด (สิ่งที่ฉันไม่เคยสังเกตเห็นมาก่อน) googling มากนำฉันไปที่เอกสาร B และ BCPL และหัวข้อนี้ อย่างไรก็ตามฉันไม่สามารถหาอะไรได้เลย ดูเหมือนว่ามีเหตุผลมากมายสำหรับ*ใน B แต่ฉันไม่สามารถหาอะไร&ได้

ดังนั้นตามคำแนะนำของ @ MichaelT ฉันถาม Ken Thompson:

จาก: Ken Thompson <ken@google.com>

ใกล้กับแป้นพิมพ์: ไม่
คัดลอกมาจาก b ดังนั้น & และ * เหมือนกัน
b ได้รับ * จากภาษาก่อนหน้า - การประกอบบางส่วน,
bcpl และฉันคิดว่า PL / 1
ฉันคิดว่าฉันใช้ & เพราะชื่อ (เครื่องหมายแอมเปอร์แซนด์)
ดูเหมือน "ที่อยู่" b ได้รับการออกแบบให้ทำงานด้วย
teletype model 33 teletype (รหัส baud-o 5 บิต)
ดังนั้นการใช้สัญลักษณ์จึงถูก จำกัด


19
+1 สำหรับการติดต่อ Ken Thompson และรายงานกลับมาที่นี่
stakx
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.