ฉันเชื่อว่า C เป็นภาษาที่ดีในการเรียนรู้หลักการที่อยู่เบื้องหลังการเขียนโปรแกรม คุณยืนหยัดเพื่อเรียนรู้ในภาษาระดับต่ำกว่าที่เป็น "เวทมนต์" ห่างจากภาษาระดับสูงเช่นรูบี?
ฉันเชื่อว่า C เป็นภาษาที่ดีในการเรียนรู้หลักการที่อยู่เบื้องหลังการเขียนโปรแกรม คุณยืนหยัดเพื่อเรียนรู้ในภาษาระดับต่ำกว่าที่เป็น "เวทมนต์" ห่างจากภาษาระดับสูงเช่นรูบี?
คำตอบ:
ไม่มีหลักการในความหมายเชิงนามธรรมทั่วไปของวิทยาการคอมพิวเตอร์ที่มีอยู่ใน C ที่ไม่ได้อยู่ในภาษาระดับสูงกว่า วิทยาการคอมพิวเตอร์ทั้งหมดนั้นพัฒนาไปสู่อัลกอริธึมและอัลกอริธึมทั้งหมดสามารถนำไปใช้ในภาษาใดก็ได้ที่ทัวริงสมบูรณ์เหมือน C
ความแตกต่างที่ C ดำเนินการกับภาษาระดับสูงกว่านั้นคล้ายคลึงกับความแตกต่างที่รหัสเครื่องดำเนินการนอกเหนือจาก C: ความสัมพันธ์ของเครื่องกับรหัส
ในขณะที่คุณเขียนโค้ดในภาษาระดับสูงคุณจะไม่กังวลเกี่ยวกับวิธีการที่รหัสของคุณโต้ตอบกับเครื่อง เครื่องเสมือนที่ภาษากำหนดสำหรับตัวเองซ่อนหลายแง่มุมของการเรียกใช้โค้ด
ใน C การโต้ตอบของโปรแกรมกับหน่วยความจำของคุณจะอยู่ในระดับแนวหน้า มันเป็นมากกว่าแค่การที่คุณต้องจัดการการใช้งานฮีปรวมถึงการมีปฏิสัมพันธ์กับโค้ดของคุณกับสแต็คและการเข้าถึงหน่วยความจำของรหัสของคุณเพียงแค่ส่งผลกระทบต่อพฤติกรรมและประสิทธิภาพของรหัสของคุณ สามารถหลบหนีความสนใจของคุณได้เนื่องจากการอ่านหน่วยความจำที่ไม่ถูกต้องในเวลาที่ผิดสามารถทำลายประสิทธิภาพได้อย่างมีประสิทธิภาพ
ในภาษาระดับสูงกว่าสิ่งเหล่านี้ไม่ชัดเจนเท่าที่ควร หน่วยความจำถูกจัดสรรและยกเลิกการจัดสรรโดยที่คุณไม่ทราบและบางครั้งก็ไม่มีการแจ้งเตือน ส่วนใหญ่แล้วนี่เป็นเพียงการควบคุมของคุณ เมื่อไหร่ที่ไหนอย่างไรและทำไมการจัดสรรหน่วยความจำส่วนใหญ่นั้นถูกซ่อนไว้จากคุณ
ในทางกลับกันการเขียนรหัสเครื่องหรือรหัสแอสเซมบลีนำรายละเอียดเพิ่มเติมไปยังเบื้องหน้า: แทบไม่มีสิ่งใดเหลืออยู่นอกขอบเขตของคุณและโค้ดของคุณจะต้องเขียนให้ตระหนักถึงการจัดสรรทุกครั้งทุกทรัพยากรทุกชิ้นส่วนของข้อมูลที่ผ่าน ผ่านการลงทะเบียนของ CPU - ความรู้ที่ถูกลบออกไปจากภาษาระดับสูงเพื่อที่จะเป็นความลับ
ฉันรู้ว่า C เป็นภาษาที่ดีในการเรียนรู้หลักการที่อยู่เบื้องหลังการเขียนโปรแกรม
ฉันไม่เห็นด้วย. C ขาดคุณสมบัติมากเกินไปที่จะเรียนรู้หลักการที่อยู่เบื้องหลังการเขียนโปรแกรม คุณสมบัติของ C สำหรับการสร้าง abstractions นั้นแย่มากและนามธรรมเป็นหนึ่งในหลักการสำคัญที่อยู่เบื้องหลังการเขียนโปรแกรม
หากคุณต้องการเรียนรู้วิธีการทำงานของฮาร์ดแวร์และด้วยเหตุนี้ความเห็นอกเห็นใจทางกลไกสำหรับเครื่องคุณควรเรียนรู้รหัสเครื่องหรือที่รู้จักกันในชื่อชุดคำสั่งสถาปัตยกรรมและศึกษาการสร้างแคชของซีพียูสมัยใหม่ โปรดทราบว่าฉันไม่แนะนำภาษาแอสเซมบลีเพียงแค่เข้าใจคำแนะนำฮาร์ดแวร์เพื่อให้คุณเข้าใจสิ่งที่คอมไพเลอร์สร้าง
หากคุณต้องการเรียนรู้หลักการเขียนโปรแกรมใช้ภาษาสมัยใหม่เช่น Java, C # หรือ Swift หรือหนึ่งในสิบของอื่น ๆ เช่น Rust นอกจากนี้ศึกษากระบวนทัศน์การเขียนโปรแกรมประเภทต่าง ๆ รวมถึงฟังก์ชั่น
ภาษาการเขียนโปรแกรมส่วนใหญ่มีการอธิบายในแง่ของเครื่องนามธรรม จากนั้นพวกเขาจะถูกนำมาใช้โดยใช้ชุดเครื่องมือเช่นคอมไพเลอร์, ลิ้งค์, แอสเซมเบลอร์, ล่าม, เครื่องวิเคราะห์แบบคงที่, ภาษาระดับกลางและฮาร์ดแวร์ที่จะสร้างผลลัพธ์ที่รวมกันอย่างน้อย .
C ไม่ใช่ข้อยกเว้นของกฎข้างต้น มันอธิบายไว้ในแง่ของเครื่องนามธรรมที่ไม่มีความคิดของฮาร์ดแวร์ที่แท้จริงของคุณ
เมื่อผู้คนพูดว่า C สอนคุณว่าคอมพิวเตอร์ของคุณใช้งานได้จริงอย่างไรพวกเขามักจะพูดว่า C สอนคุณว่า C ทำงานอย่างไร แต่ C นั้นแพร่หลายในการเขียนโปรแกรมระบบจึงเป็นที่เข้าใจได้ว่าผู้คนจำนวนมากเริ่มสับสนกับคอมพิวเตอร์เอง และฉันเองก็อยากจะบอกว่าการรู้ว่า C ทำงานอย่างไรมีความสำคัญมากกว่าการรู้ว่าคอมพิวเตอร์ทำงานอย่างไร
แต่ถึงกระนั้น C และคอมพิวเตอร์ก็แตกต่างกัน ฮาร์ดแวร์จริงมีความซับซ้อนจริง ๆ - ในวิธีการที่ทำให้ข้อมูลจำเพาะ C อ่านเหมือนหนังสือสำหรับเด็ก หากคุณสนใจว่าฮาร์ดแวร์ของคุณทำงานอย่างไรคุณสามารถค้นหาคู่มือและเริ่มเขียนโค้ดในแอสเซมเบลอร์ได้ตลอดเวลา หรือคุณสามารถเริ่มเรียนรู้เกี่ยวกับวงจรดิจิตอลได้ตลอดเวลาเพื่อให้คุณสามารถออกแบบฮาร์ดแวร์ด้วยตัวเอง (อย่างน้อยที่สุดคุณจะประทับใจกับระดับ C ที่สูง)
โอเคจริงๆแล้วการเรียนรู้เกี่ยวกับฮาร์ดแวร์เกี่ยวข้องกับสิ่งอื่นนอกเหนือจากซี แต่วันนี้ซีสามารถสอนสิ่งอื่นใดให้โปรแกรมเมอร์ได้หรือไม่
ฉันคิดว่ามันขึ้นอยู่กับ
อย่าเร็วเกินไปที่จะเลือกหนึ่งในความเป็นไปได้เหล่านี้ ฉันเขียนโค้ดมาหลายปีแล้วและฉันก็ยังไม่รู้ว่าคำตอบที่ถูกต้องคืออะไรหรือคำตอบที่ถูกต้องนั้นเป็นเพียงหนึ่งในสองข้อหรือว่ามีคำตอบที่ถูกต้องสำหรับปัญหานี้หรือไม่
ฉันมีความโน้มเอียงเล็กน้อยที่จะเชื่อว่าในที่สุดคุณควรใช้ตัวเลือกทั้งสองอย่างหลวม ๆ ตามลำดับที่ฉันอธิบายไว้ แต่ฉันไม่คิดว่านี่เป็นเรื่องทางเทคนิคจริง ๆ ฉันคิดว่ามันเป็นเรื่องการศึกษาส่วนใหญ่ ดูเหมือนว่าทุกคนจะเรียนรู้ด้วยวิธีที่แตกต่างกัน
หากคุณตอบคำถามข้างต้นโดยอย่างน้อยเกี่ยวข้องกับตัวเลือกที่สองที่ฉันเสนอคุณมีคำตอบอยู่สองสามข้อแล้ว: สิ่งที่เรียนรู้ได้ในภาษาระดับสูงกว่าสามารถเรียนรู้ได้ดีขึ้นโดยการประดิษฐ์มันใหม่ใน C หรือ ขยายอย่างน้อยโดยการเพิ่ม C ลงในส่วนผสม
แต่ไม่ว่าคุณจะตอบอย่างไรก็มีบางสิ่งที่คุณสามารถเรียนรู้ได้จาก C (และอาจมีภาษาอื่น ๆ อีกเล็กน้อย)
C มีความสำคัญทางประวัติศาสตร์ มันเป็นเหตุการณ์สำคัญที่คุณสามารถดูและซาบซึ้งที่เรามาจากและอาจได้รับบริบทเพิ่มเติมเล็กน้อยเกี่ยวกับการที่เราจะไป คุณสามารถชื่นชมว่าทำไมมีข้อ จำกัด บางประการและคุณสามารถชื่นชมว่ามีการยกข้อ จำกัด บางอย่าง
C สามารถสอนให้คุณทำงานในสภาพแวดล้อมที่ไม่ปลอดภัย กล่าวอีกนัยหนึ่งมันสามารถฝึกให้คุณระวังหลังเมื่อภาษา (ภาษาใด ๆ ) ไม่สามารถหรือจะไม่ทำเพื่อคุณไม่ว่าด้วยเหตุผลใดก็ตาม สิ่งนี้สามารถทำให้คุณเป็นโปรแกรมเมอร์ที่ดีขึ้นแม้ในสภาพแวดล้อมที่ปลอดภัยเพราะคุณจะสร้างข้อบกพร่องน้อยลงด้วยตัวคุณเองและเพราะคุณจะสามารถปิดความปลอดภัยชั่วคราวเพื่อบีบความเร็วพิเศษออกจากโปรแกรมที่ปลอดภัยของคุณ (เช่นการใช้พอยน์เตอร์ ใน C #) ในกรณีที่ความปลอดภัยมาพร้อมกับต้นทุนรันไทม์
C สามารถสอนคุณได้ว่าทุกอ็อบเจ็กต์มีข้อกำหนดหน่วยเก็บข้อมูลเลย์เอาต์ของหน่วยความจำความจริงที่ว่าหน่วยความจำสามารถเข้าถึงได้ผ่านพื้นที่ที่อยู่ที่ จำกัด และอื่น ๆ ในขณะที่ภาษาอื่นไม่ต้องการความสนใจของคุณในเรื่องเหล่านี้มีบางกรณีที่สัญชาตญาณที่ได้รับบางอย่างสามารถช่วยคุณตัดสินใจได้อย่างชาญฉลาด
C สามารถสอนคุณเกี่ยวกับรายละเอียดของการเชื่อมโยงและวัตถุไฟล์และความซับซ้อนอื่น ๆ ผ่านระบบการสร้าง สิ่งนี้จะช่วยให้คุณมีความเข้าใจที่เป็นประโยชน์เกี่ยวกับวิธีที่โปรแกรมที่คอมไพล์แล้วมักจะไปจากซอร์สโค้ดถึงการดำเนิน
C สามารถทำให้จิตใจของคุณงอที่จะคิดด้วยวิธีแปลกใหม่ผ่านแนวคิดของพฤติกรรมที่ไม่ได้กำหนด พฤติกรรมที่ไม่ได้กำหนดเป็นหนึ่งในแนวคิดที่ฉันโปรดปรานในการพัฒนาซอฟต์แวร์เนื่องจากการศึกษาผลกระทบของมันต่อคอมไพเลอร์ที่ไม่คลาสสิคคือการออกกำลังกายทางจิตที่ไม่เหมือนใครซึ่งคุณไม่สามารถหาได้จากภาษาอื่น อย่างไรก็ตามคุณจะต้องปฏิเสธการทดลองและข้อผิดพลาดและเริ่มเรียนภาษาด้วยความระมัดระวังและรอบคอบก่อนที่คุณจะสามารถชื่นชมกับมุมมองนี้อย่างเต็มที่
แต่บางทีอาจจะก่อให้เกิดสิ่งที่สำคัญที่สุดที่ซีสามารถให้คุณเป็นภาษาขนาดเล็กคือความคิดที่ว่าทุกโปรแกรมเดือดลงไปข้อมูลและการดำเนินงาน คุณอาจต้องการดูสิ่งต่าง ๆ เป็นคลาสโมดูลาร์ที่มีลำดับชั้นและอินเทอร์เฟซที่มีการจัดส่งเสมือนจริงหรือค่าที่ไม่เปลี่ยนรูปที่สง่างามซึ่งดำเนินการโดยใช้ฟังก์ชันทางคณิตศาสตร์ล้วนๆ และที่ดีทั้งหมด - แต่ C จะเตือนคุณว่ามันเป็นเพียงแค่ทุกข้อมูลการดำเนินงาน + มันเป็นความคิดที่มีประโยชน์เพราะมันช่วยให้คุณสามารถลดอุปสรรคทางจิตลงได้บ้าง
เหตุผลที่ว่าทำไม C เป็นสิ่งที่ดีสำหรับการเรียนรู้ไม่ได้ว่ามันสอนใด ๆหลักการ มันสอนให้คุณรู้ว่าสิ่งต่าง ๆทำงานอย่างไร
C สามารถเปรียบเทียบกับหนึ่งในรถเก่าที่ดีเหล่านั้นจาก 70 หรือ 80 ซึ่งถูกสร้างขึ้นเพื่อขับ คุณสามารถแยกพวกมันออกจากกันได้ด้วยสกรูและเข้าใจว่าแต่ละส่วนทำงานอย่างไรและทำงานร่วมกับส่วนอื่น ๆ ที่คุณสามารถจับได้ เมื่อคุณเข้าใจชิ้นส่วนทั้งหมดแล้วคุณจะเห็นภาพที่ชัดเจนว่าการทำงานทั้งหมดเป็นอย่างไร
ภาษาสมัยใหม่เป็นเหมือนรถที่ทันสมัยซึ่งโดยทั่วไปแล้วเครื่องยนต์จะเป็นกล่องดำซึ่งเป็นวิธีที่ซับซ้อนเกินกว่าที่เจ้าของรถทั่วไปจะเข้าใจได้ รถยนต์เหล่านั้นสามารถทำอะไรได้มากมายในสมัยนี้พวกเขาเรียนรู้ที่จะขับด้วยตนเอง และด้วยความซับซ้อนและความสะดวกสบายนั้นอินเทอร์เฟซผู้ใช้ถูกย้ายไปไกลกว่าสิ่งที่เกิดขึ้นจริงในเครื่องยนต์
เมื่อคุณเรียนรู้การเขียนโปรแกรมใน C คุณจะได้สัมผัสกับสกรูและน็อตจำนวนมากที่คอมพิวเตอร์สร้างขึ้น สิ่งนี้ช่วยให้คุณพัฒนาความเข้าใจของตัวเครื่องเอง ตัวอย่างเช่นมันช่วยให้คุณเข้าใจว่าทำไมมันไม่ควรสร้างสตริงที่มีความยาวเช่นนี้:
java.lang.String result = "";
for(int i = 0; i < components.size; i++) {
result = result + components[i];
};
(ฉันหวังว่านี่เป็นจาวาที่ถูกต้องฉันไม่ได้ใช้ในขณะที่ ... ) จากตัวอย่างโค้ดนี้ไม่ชัดเจนว่าทำไมลูปจึงมีความซับซ้อนเป็นกำลังสอง แต่เป็นกรณีนี้และนี่คือเหตุผลที่รหัสนี้จะหยุดชะงักเมื่อคุณมีส่วนประกอบเล็ก ๆ จำนวนไม่กี่ล้านชิ้นที่จะต่อกัน โปรแกรมเมอร์ C ที่มีประสบการณ์จะรู้ได้ทันทีว่าปัญหาเกิดขึ้นที่ใดและจะหลีกเลี่ยงการเขียนโค้ดในตอนแรก
for(int i = 0; i < strlen(s); i++)
ใน C วงก็จะมีความซับซ้อนเป็นกำลังสองและมันก็ไม่เป็นที่ชัดเจนเหมือนกับในตัวอย่าง Java ของคุณ ;-)
มีภาษาที่ดีกว่า C ในการเรียนรู้ "หลักการที่อยู่เบื้องหลังการเขียนโปรแกรม" โดยเฉพาะอย่างยิ่งในทางทฤษฎี แต่ C อาจจะดีในการเรียนรู้สิ่งที่มีประโยชน์และมีความสำคัญเกี่ยวกับงานฝีมือ คำตอบของ greyfade นั้นถูกต้องอย่างแน่นอน แต่ IMHO มีมากกว่าที่คุณสามารถเรียนรู้จาก C มากกว่าวิธีการจัดการหน่วยความจำด้วยตัวเอง ตัวอย่างเช่น,
วิธีการสร้างโปรแกรมที่มีการจัดการข้อผิดพลาดอย่างสมบูรณ์โดยไม่มีข้อยกเว้น
วิธีสร้างโครงสร้างในโปรแกรมโดยไม่มีภาษารองรับการวางแนววัตถุ
วิธีจัดการกับข้อมูลในกรณีที่ไม่มีโครงสร้างข้อมูลเช่นรายการขนาดใหญ่แบบไดนามิกพจนานุกรมหรือนามธรรมที่เป็นประโยชน์สตริง
วิธีหลีกเลี่ยงข้อผิดพลาดทั่วไปเช่น array overflows แม้เมื่อสภาพแวดล้อมคอมไพเลอร์หรือรันไทม์ไม่ได้เตือนคุณโดยอัตโนมัติ
วิธีสร้างโซลูชันทั่วไปโดยไม่ต้องมีการสนับสนุนด้านภาษาสำหรับแม่แบบหรือข้อมูลทั่วไป
และฉันพูดถึงว่าคุณสามารถเรียนรู้วิธีจัดการหน่วยความจำด้วยตัวเองได้หรือไม่? ;-)
ยิ่งไปกว่านั้นด้วยการเรียนรู้ C คุณจะได้เรียนรู้ว่าโครงสร้างของไวยากรณ์ของ C ++, Java, C #, Objective C มาจากไหน
ในปี 2005 Joel Spolsky เขียนคำแนะนำสำหรับการเรียนรู้ C ก่อนภาษาระดับสูงอื่น ๆ ข้อโต้แย้งของเขาคือ
"คุณจะไม่สามารถสร้างโค้ดที่มีประสิทธิภาพในภาษาระดับสูงกว่านี้ได้"
"คุณจะไม่สามารถทำงานกับคอมไพเลอร์และระบบปฏิบัติการซึ่งเป็นงานเขียนโปรแกรมที่ดีที่สุด"
"คุณจะไม่เชื่อใจในการสร้างสถาปัตยกรรมสำหรับโครงการขนาดใหญ่"
"ถ้าคุณไม่สามารถอธิบายได้ว่าทำไมการwhile(*s++ = *t++);
คัดลอกสตริงหรือถ้านั่นไม่ใช่สิ่งที่เป็นธรรมชาติที่สุดในโลกสำหรับคุณคุณกำลังเขียนโปรแกรมด้วยความเชื่อโชคลาง
แน่นอนสิ่งที่เขาเขียนนั้นเป็นที่ถกเถียงกันอย่างแน่นอน แต่ข้อโต้แย้งมากมายของ IMHO ยังคงใช้ได้ในปัจจุบัน
นามธรรมพื้นฐานสองประการของการคำนวณคือเครื่องทัวริงและแคลคูลัสแลมบ์ดาและ C เป็นวิธีการทดสอบด้วยมุมมองการคำนวณของทัวริง: ส่วนใหญ่เป็นการสืบทอดการกระทำระดับต่ำซึ่งเป็นผลลัพธ์ที่พึงประสงค์ แต่คุณต้องจำไว้ว่า C มาพร้อมกับรูปแบบการคำนวณของตัวเอง ดังนั้นการเรียนรู้ C จะสอนรายละเอียดในระดับต่ำของเครื่องนามธรรม C ซึ่งแตกต่างจากสถาปัตยกรรมจริง หนึ่งในสิ่งแรกที่ฉันสอนใน C คือไม่เคยพยายามที่จะเอาชนะคนเรียบเรียงโดยใช้เล่ห์เหลี่ยม "ฉลาด" และดูเหมือนว่าแนวโน้มนั้นมีต่อการปรับให้เหมาะสมที่สุดในคอมไพเลอร์ เช่นเดียวกับในภาษาระดับสูงอื่น ๆ เมื่อคุณเขียนใน C คอมไพเลอร์จะเข้าใจสิ่งที่คุณคาดหวังว่าจะทำได้บนเครื่อง C นามธรรมและทำให้มันเกิดขึ้นบนฮาร์ดแวร์จริง
ดังนั้นสิ่งที่ฉันหมายถึงคือการเรียนรู้ C ไม่จำเป็นต้องให้ภาพที่ดีของสิ่งที่เกิดขึ้นจริงในฮาร์ดแวร์ "C ใกล้กับเครื่อง" ควรเข้าใจว่าเป็น "ใกล้กว่าภาษาระดับสูงกว่า" การเรียนรู้สถาปัตยกรรมซอฟต์แวร์โดยตรงจะให้ผลตอบแทนมากขึ้นหากคุณต้องการภาพที่แม่นยำยิ่งขึ้นของ "วิธีการทำงาน"
ในทางกลับกันการเรียนรู้ C สามารถทำให้คุณคุ้นเคยกับการเขียนโปรแกรมระบบชนิดระดับต่ำพอยน์เตอร์และการจัดสรรหน่วยความจำโดยเฉพาะ สำหรับอัลกอริทึมการเรียนรู้และโครงสร้างข้อมูลฉันไม่มีข้อได้เปรียบในการเรียนรู้พวกเขาในภาษา C มากกว่าในภาษาอื่น
มันเป็นคำถามที่เปิดกว้างมากอาจไม่ใช่คำตอบสุดท้าย คุณสามารถเรียนรู้ทุกอย่างได้ในทุกภาษาหากคุณเข้าใจในกรอบภาษา C บังคับให้คุณเข้าใจรายละเอียดที่ต่ำกว่าเพราะมันถูกออกแบบมาเพื่อเขียนระบบปฏิบัติการเป็นหลัก แม้หลังจากผ่านไปหลายปีมันก็ยังคงเป็นหนึ่งในภาษาที่ใช้กันมากที่สุดส่วนใหญ่ต้องขอบคุณระบบฝังตัวและโครงการโอเพนซอร์ส ดังนั้นคำถามคือสิ่งที่คุณต้องการเรียนรู้? และในโดเมนไหน