“ Objective-C คือส่วนเหนือของ C ที่เคร่งครัดกว่า C ++” หมายความว่าอย่างไร


87

จากสิ่งที่ฉันอ่าน: เหตุใด Objective-C จึงไม่ได้รับความนิยมมากนักนอกชุมชน Apple

Objective-C เป็นส่วนเสริมของ C (ที่จริงแล้วเคร่งครัดกว่า C ++ มาก) ดังนั้นปัญหาความเข้ากันได้แบบย้อนหลังจึงไม่เกิดขึ้น ทุกสิ่งที่คุณทำได้ใน C คุณสามารถทำได้ใน Objective-C

การเป็นซูเปอร์เซ็ตเป็นไบนารีเช่นการตั้งครรภ์ Obj-C เป็นส่วนเหนือของ C และ C ++ ไม่ใช่

superset หมายถึงอะไร? Object-C จะใกล้เคียงกว่า // เข้ากันได้กับ C ในทางใด Object-C ปฏิบัติตามปรัชญา C อย่างใกล้ชิดมากกว่า C ++ อย่างไร

โปรแกรม C ใด ๆ สามารถคอมไพล์โดยไม่ต้องดัดแปลงโดยคอมไพเลอร์ Object-C (เข้ากันได้ 100%)?

นี่เป็นคำถามเกี่ยวกับการออกแบบภาษาโปรแกรมและความเข้ากันได้มากกว่าสงครามที่ว่าอันไหนดีกว่ากัน

คำตอบ:


134

ฉันเตรียมแผนภาพง่ายๆ มันไม่สวยมาก แต่หวังว่าจะได้ประเด็น:

  • สีแดง:ชุดของโปรแกรมทั้งหมดใช้ได้ใน C, C ++ และ Objective-C (ค่อนข้างเล็ก)
  • สีเขียว:ชุดของโปรแกรมทั้งหมดที่ใช้ได้ใน C และ Objective-C แต่ไม่ถูกต้องใน C ++ (เล็กกว่า)
  • สีเทา:ชุดของโปรแกรมทั้งหมดใช้ได้ใน Objective C และ C ++ แต่ไม่ถูกต้องใน C (ว่างเปล่าเท่าที่ฉันรู้)
  • สีน้ำเงิน:ชุดของโปรแกรมทั้งหมดใช้ได้เฉพาะใน Objective C (ค่อนข้างใหญ่)
  • สีเหลือง:ชุดของโปรแกรมทั้งหมดใช้ได้เฉพาะใน C ++ (ใหญ่ที่สุด)

ชุดโปรแกรม C ที่ถูกต้อง (สีแดงและสีเขียว) เป็นชุดย่อยที่เข้มงวดของชุดโปรแกรม Objective C ที่ถูกต้อง (สีน้ำเงิน)

ใส่คำอธิบายภาพที่นี่


14
สิ่งที่เกี่ยวกับวัตถุประสงค์ c ++?
user1115057

14
ความคล้ายแปลก ... : justindomke.files.wordpress.com/2008/11/scalaimage11.png
user1115057

19
วัดใดที่คุณอ้างว่าสีเหลือง "ใหญ่" กว่าสีน้ำเงินที่นี่? สัญชาตญาณบอกฉันว่าทั้งสองชุดจะนับไม่ถ้วน
Wim

4
@wim: และทั้งสองจะแสดงเป็นเซตย่อยที่นับไม่ได้ของ R ^ 2;) นี่เป็นเคล็ดลับเดียวกับที่คุณจะเห็น N ภายใน Q แม้ว่าจะมีขนาดเท่ากันก็ตาม (และ N เป็นเซตย่อยที่เข้มงวดของ Q)
Maciej Piechotka

3
ฉันกำลังคิดเกี่ยวกับเรื่องนี้มากขึ้นและตระหนักว่าชุด ObjC ++ จะไม่ล้อมรอบทั้งหมดนี้ เป็นส่วนเหนือของ C ++ แต่ไม่ใช่ชุดเหนือที่เข้มงวดของ ObjC โปรแกรมเดียวกันกับที่เป็นกฎหมาย C แต่ C ++ ที่ผิดกฎหมาย (พื้นที่สีเขียว) เป็น ObjC ++ ที่ผิดกฎหมาย
Rob Napier

62
  1. superset หมายถึงอะไร?

    หมายถึง superset ที่เข้มงวด โปรแกรม C ที่ถูกต้องใด ๆ จะคอมไพล์ด้วยคอมไพเลอร์ Objective-C โปรแกรม C ที่ถูกต้องบางโปรแกรมจะไม่รวบรวมด้วยคอมไพเลอร์ C ++

  2. Object-C จะใกล้เคียงกว่า // เข้ากันได้กับ C ในทางใด

    นี่คือตัวอย่างง่ายๆ:

    int *foo = malloc(12);
    

    คอมไพล์ใน C และ Objective-C แต่ไม่ใช่ใน C ++ แน่นอนว่ามีตัวอย่างอื่น ๆ เช่นกัน

  3. Object-C ปฏิบัติตามปรัชญา C อย่างใกล้ชิดมากกว่า C ++ อย่างไร

    ทั้งหมด - Objective-C เป็นส่วนเหนือที่เข้มงวดของ C

  4. โปรแกรม C ใด ๆ สามารถคอมไพล์โดยไม่ต้องดัดแปลงโดยคอมไพเลอร์ Object-C (เข้ากันได้ 100%)?

    ใช่.


2
ใช่ว่าจะดี สมมติว่าคุณไม่จำเป็นต้องใช้ Objective-C สำหรับ GUI เช่นกันหากคุณต้องการหาฟังก์ชันรันไทม์ระดับต่ำที่จะใช้
Carl Norum

3
ส่วนใหญ่เป็นปรัชญา
Carl Norum

2
+1 คำอธิบายที่ยอดเยี่ยม ฉันขอแนะนำว่าคำถามของ "ปรัชญา C" นั้นค่อนข้างคลุมเครือ แต่ผู้สังเกตการณ์ส่วนใหญ่อาจเห็นด้วยว่า "เป้าหมาย" ของ C และ "เป้าหมาย" ของ ObjC นั้นแตกต่างกัน เจตนาของ C คือการอยู่ใกล้กับฮาร์ดแวร์มากในขณะที่ให้ความสามารถในการพกพาที่เป็นประโยชน์ในขณะที่เป้าหมายของ ObjC คือการนำแนวทาง SmallTalk มาสู่ C. เนื่องจาก Cocoa กลายเป็นส่วนสำคัญของ ObjC ในช่วงไม่กี่ปีที่ผ่านมาความแตกต่างนี้จึงแข็งแกร่งยิ่งขึ้น "ปรัชญา" (แนวทางการออกแบบ) ของ C-array และ NSArray นั้นแตกต่างกันมาก
Rob Napier

2
ขึ้นอยู่กับโปรแกรมทั้งหมด คุณอาจจะไม่ทำอะไรสไตล์ C มากเกินไปในโปรแกรม Objective-C ทำไมคุณถึงใช้ Objective-C?
Carl Norum

1
@ user1115057: คุณไม่ควรกังวลมากเกินไปเกี่ยวกับการพิจารณาสิ่งต่างๆ มีปัญหาสองประการในการเขียนโค้ด C ++ ที่คอมไพล์เป็น (หรืออย่างน้อยก็ดูเหมือน) C ประการหนึ่งคือคุณไม่ได้รับประโยชน์ใด ๆ จาก C ++ แต่นั่นคือคำเรียกของคุณ สิ่งที่สำคัญคือคุณกำลังเขียนด้วยภาษา C ที่ไม่ถูกต้องซึ่งไม่ใช่ภาษา C จริงๆคุณควรรวบรวมรหัส C ของคุณด้วยคอมไพเลอร์ C และเชื่อมโยงกับรหัส C ++ ของคุณ ข้อกังวลหลังนั้นใช้ไม่ได้กับ Objective-C เนื่องจากชุดย่อยของ Objective-C ที่รวบรวมเป็น C คือ C.
Steve Jessop

31

ตั้งแต่เริ่มต้น C ++ ได้รับการออกแบบให้เป็น "C ที่ดีกว่า" โดยแก้ไขการละเว้นการออกแบบทั้งที่เกิดขึ้นจริงและจากการรับรู้เนื่องจากผู้เขียน C ++ ได้ใช้ภาษา ผลของการตัดสินใจออกแบบนี้คือการXเป็นโปรแกรม C ที่ถูกต้องไม่ได้รับประกันว่าXจะคอมไพล์ได้นับประสาอะไรกับการรันเมื่อประมวลผลโดยคอมไพเลอร์ C ++ การเปลี่ยนแปลงได้สัมผัสโครงสร้างพื้นฐานเช่นตัวอักษรสตริง (กลายเป็นconst char*) การกำหนดพvoidอยน์เตอร์การแปลงระหว่างenums และชนิดอินทิกรัลความหมายของตัวดำเนินการกำหนดสารประกอบและอื่น ๆ

ยิ่งไปกว่านั้นเมื่อ C99 เข้ามาคุณลักษณะต่างๆที่ทำให้เป็นมาตรฐาน C ที่อัปเดตแล้วจะไม่อยู่ในมาตรฐาน C ++ ที่อัปเดต อีกครั้งคุณลักษณะทางภาษาที่สำคัญมากถูกทิ้งไว้โดยเฉพาะอย่างยิ่งตัวเริ่มต้นที่กำหนดและอาร์เรย์ขนาดตัวแปร

ในทางตรงกันข้าม Objective C ได้รับการจัดตำแหน่งให้เป็นส่วนเหนือของ C ซึ่งกำหนดให้โปรแกรม C ที่ถูกต้องทั้งหมดสามารถคอมไพล์ได้ด้วยคอมไพเลอร์ Objective C


4
ฉันตอบคำถามนี้เพราะฉันรู้ว่า "superset" คืออะไร แต่ฉันไม่รู้อะไรเกี่ยวกับ Objective-C ฉันเคยเห็นการอ้างสิทธิ์ในคำถาม SO อื่นว่าข้อมูลโค้ด C ที่ถูกต้องint nil = 0; nil++;ไม่ได้รวบรวมเป็น Objective-C มีปัญหาอะไรเป็นสิ่งที่ชัดเจนหรือไม่ที่ Objective-C สร้างส่วนหัวที่พร้อมใช้งานซึ่งเมื่อรวมแล้วสามารถทำลายโค้ดของคุณได้เหมือนกับที่ส่วนหัว C ทำได้หรือไม่? ดังนั้นผู้เขียนตัวอย่างข้อมูลดังกล่าวจึงไม่ควรรวมไว้ด้วย
Steve Jessop

2
"nil" เป็น #define แทนที่จะเป็นคำหลัก คุณพบปัญหาเนื่องจากรวม objc / objc.h สิ่งนี้คล้ายกับปัญหาที่คุณพบหากคุณพยายามสร้างตัวแปรชื่อ YES (Xcode เน้นสิ่งเหล่านี้ราวกับว่าเป็นคำหลักจริงๆเพราะมันง่ายกว่ามากที่จะคิดแบบนั้น แต่มันถูกนำไปใช้เป็นรหัส C ธรรมดา ๆ )
Rob Napier

4
BTW มันคุ้มค่าที่จะใช้ objc เล็กน้อยถ้าคุณสนใจว่า ObjC มีชีวิตอยู่เหนือ C ได้อย่างไรสิ่งที่คุณคิดว่าจะเป็นคำหลัก (id, BOOL, Class, nil ฯลฯ ) เป็นเพียงประเภทธรรมดาโครงสร้าง และกำหนด คุณยังสามารถใช้การส่งผ่านข้อความด้วยมือใน pure-C ไม่เคยทำอย่างนั้น : D แต่คุณทำได้ github.com/iosptl/ios6ptl/blob/master/ch28/Runtime/MyMsgSend.c
Rob Napier

2
@ DanNeely: Rob Napier กล่าวว่า "ไม่เคยทำอย่างนั้น" เป็นคำอธิบายเกี่ยวกับไฟล์ที่ลิงก์ ไฟล์ที่เชื่อมโยงไม่ใช่รันไทม์ Objective-C เป็นเพียงการแฮ็กด่วนที่แสดงให้เห็นว่าการส่งข้อความทำงานอย่างไร
Dietrich Epp

1
ไฟล์ที่เชื่อมโยงไม่ได้แสดงให้เห็นว่าการส่งผ่านข้อความ ObjC นั้นซับซ้อนเพียงใด มันแสดงให้เห็นว่ารันไทม์นั้นพร้อมใช้งานจาก C และโดยหลักการแล้วคุณสามารถแปลงรหัส ObjC เป็น C บริสุทธิ์ได้ แต่ ... มันช้าที่สุดเท่าที่คุณจะสร้างได้ มันขึ้นอยู่กับการที่ฉันรู้ประเภทการส่งคืนของวิธีการ (และสำหรับการส่งคืนบางประเภทฉันอาจจำเป็นต้องรู้ประเภทตัวประมวลผล) และฉันเลือกวิธีการที่ไม่ใช้พารามิเตอร์อย่างระมัดระวัง โซลูชันเต็มรูปแบบมีเทคนิคที่ละเอียดอ่อนมากมาย (ชิ้นส่วนต้องอยู่ในแอสเซมเบลอร์เพราะโกงด้วยสแต็กเฟรม) คุณไม่ควรพยายามสร้างใหม่
Rob Napier

12

"Objective-C เป็นส่วนเหนือของ C" หมายความว่าโปรแกรม C ที่ถูกต้องทุกโปรแกรมเป็นโปรแกรม Objective-C ที่ถูกต้อง (มีความหมายเหมือนกัน)

มันเป็นบางครั้งกล่าวว่าแม้จะไม่ได้โดย c ++ ผู้เชี่ยวชาญที่ C ++ เป็นซูเปอร์ซีนี้ไม่ถูกต้องซึ่งเป็นเหตุผลที่คำพูดของคุณจะทำให้เป็นเรื่องใหญ่ของการเปรียบเทียบทั้งสอง


9

Objective C คือชุดของส่วนขยายที่เข้ากันได้กับ C ซึ่งเป็นไปได้เนื่องจากคุณลักษณะของ Objective C ถูกคั่นด้วยสองวิธีง่ายๆ:

  • @ใช้ของตัวละคร ปัจจุบันอักขระนี้ไม่ได้ใช้ในภาษาซี
  • ส่วนขยายของประโยคง่าย ๆ [obj method:argument]สำหรับการเรียกวิธีการ ใน C จะใช้วงเล็บเหลี่ยมในรูปแบบที่เฉพาะเจาะจงมากสำหรับการห้อยลงของอาร์เรย์ดังนั้นจึงเป็นไวยากรณ์ C ที่ไม่ถูกต้อง ส่วนขยายที่สร้างขึ้นจากไวยากรณ์ที่ไม่ถูกต้องจะไม่เปลี่ยนความหมายของสิ่งที่ถูกต้องในภาษาโฮสต์

ง่ายมากที่จะเห็นว่าไม่มีโปรแกรมใดที่ใช้ส่วนขยาย Objective C สามารถเป็นโปรแกรม ISO C ที่สอดคล้องอย่างเคร่งครัดไม่ว่าจะง่ายแค่ไหนก็ตาม ยิ่งไปกว่านั้นโปรแกรม ISO C ทุกโปรแกรมสามารถประกาศตามความหมายเพื่อให้เป็นโปรแกรม Objective C ที่ถูกต้อง Objective C สามารถติดตามการพัฒนาเช่น C99 และ C11 ได้อย่างง่ายดาย

ในทางกลับกัน C ++ ไม่ใช่แค่ส่วนขยายของ C เท่านั้น มันเป็นภาษาอื่นที่เปลี่ยนความหมายของบางส่วนของไวยากรณ์ของ C. C ++ และ C จะได้รับการดูแลแยกกันดังนั้นความสัมพันธ์จึงเปลี่ยนแปลงไปตามกาลเวลา ตัวอย่างเช่น C ได้รับคุณสมบัติใหม่ที่ไม่มีใน C ++ โดยสิ้นเชิงและมีแนวโน้มว่าจะไม่เข้าสู่ C ++ เช่นอาร์เรย์ที่มีความยาวตัวแปร C99 C ++ ไม่สามารถรับคุณสมบัติใหม่ของ C ได้อย่างง่ายดาย

หากคุณเขียนโปรแกรม C แบบพกพาควรเป็นโปรแกรม Objective C ในเวลาเดียวกัน แต่จะต้องมีการดูแลเพิ่มเติมเพื่อให้เป็นโปรแกรม C ++ ที่มีความหมายเดียวกัน (แนวปฏิบัตินี้ไม่เคยได้ยินมาก่อนและภาษาถิ่นที่ต้องใช้เรียกอย่างไม่เป็นทางการว่า "Clean C")

ตัวอย่างเล็ก ๆ น้อย ๆ ของโปรแกรม C ที่แบ่งเมื่อถือว่าเป็น C ++ เป็นโปรแกรม C ใด ๆ ที่ใช้ C ++ คำหลักที่เป็นตัวระบุเช่นหรือclass virtualวัตถุประสงค์ C ไม่แนะนำคำหลักที่สงวนไว้ มันมีคำหลักใหม่ที่ได้รับการแนะนำให้รู้จักกับตัวละครเช่น@@interface

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