มันเป็นนิสัยที่ดีในการใช้ C นิพจน์ในรหัส C ++ หรือไม่


19

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

คำถามของฉันตรงไปตรงมา ~ เป็นนิสัยที่ดีในการใช้ C นิพจน์ใน C ++ หรือไม่ ผมขอยกตัวอย่าง:

ควรรหัสนี้

#include <stdio.h>
#include <iostream>

int main() {
int x;
scanf("%d", &x);
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

มีประสิทธิภาพมากขึ้นหรือดีกว่าในทางใดทางหนึ่ง:

#include <iostream>

int main() {
int x;
cin >> x;
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

ฉันได้ทำเอกสารง่าย ๆ เกี่ยวกับเรื่องนี้แล้วในหนังสือเก่าที่เต็มไปด้วยฝุ่นและจากสิ่งที่ฉันสามารถหาได้การใช้ scanf แทน cout ก็เป็นการล้างกระแสข้อมูลหรืออะไรทำนองนั้นดังนั้นฉันจึงถามว่าควรใช้ scanf หรือไม่ สิ่งที่บริบท

สิ่งนี้ยังใช้กับไฟล์ IO เนื่องจากฉันพบว่า FIle IO ใช้งานง่ายกว่าใน C มากกว่าใน C ++ คำถามนี้มีความหมายสำหรับนิพจน์ทั่วไปทั้งหมดใน C ที่ใช้กับ C ++ เป็นที่น่าสังเกตว่าฉันใช้คอมไพเลอร์ที่ทันสมัยและมันก็ไม่สำคัญว่าฉันจะถามว่ามันเป็นนิสัยการเขียนโปรแกรมที่ดีในการใช้ C นิพจน์ในรหัส C ++ หรือไม่

อาจมีข้อเสียและข้อดีของการทำเช่นนี้ แต่ฉันแค่มองหาใช่ / ทำไมไม่ / ทำไมประเภทของคำตอบ

นอกจากนี้หากมีรายละเอียดใด ๆ ที่ฉันไม่ได้โพสต์แสดงความคิดเห็น


12
ระวังการผสมstdioและiostream. มีบางคำสั่งและการประสานการรับประกันภายในครอบครัวที่ไม่จำเป็นต้องใช้ภายนอก
David Thornley

ขอบคุณสำหรับเคล็ดลับ แต่รหัสเศษนั้นเป็นตัวอย่างที่แท้จริง ขอบคุณอยู่ดี
Bugster

25
หากคุณกำลังเรียนรู้การเขียนโปรแกรม คุณต้องเรียนรู้การเยื้องที่เหมาะสม!
bitmask

5
scanf () ไม่ใช่ตัวอย่างที่ยอดเยี่ยม มันผิดพลาดได้ง่ายมากที่จะใช้ที่ฉันอยากจะแนะนำให้คุณหลีกเลี่ยงใน C หรือ C ++
Russell Borogove

1
มันอาจเป็นโค้ดตัวอย่างเท่านั้น แต่ความคิดเห็นของเดวิดเป็นหัวใจสำคัญของปัญหาว่าทำไมคุณไม่ควรใช้สำนวน C เมื่อตั้งโปรแกรมใน C ++ พวกมันแตกต่างกันโดยสิ้นเชิง อย่าสับสนพวกเขามากไปกว่าที่คุณสับสน Java และ C หรือ C ++ และ Visual Basic
Cody Grey

คำตอบ:


36

ไม่มันเป็นนิสัยที่ไม่ดี เมื่อคุณทำเช่นนี้เพื่อหาเลี้ยงชีพคุณอาจท้ายลงด้วยการละเมิดคู่มือสไตล์ที่ทีมของคุณยึดถือ

ใช่มันใช้งานได้ แต่ถ้ามี c ++ เทียบเท่าให้ใช้ (เช่นพยายามไม่ผสมprintfsกับcouts)


+1 - สั้นและตรงประเด็น และสิ่งนี้ชี้ให้เห็นถึงประเด็นหลักในคำตอบของฉันว่าแนวทางของทีมช่วยให้คนมารวมกันและรวมพวกเขาไว้ด้วยกันเพื่อให้พวกเขาสามารถทำงานร่วมกันได้
jmort253

ความคิดเห็นนี้ค่อนข้างตอบคำถามของฉันอย่างถูกต้องและนำข้อโต้แย้งที่มั่นคง ขอขอบคุณ.
Bugster

1
@ ThePlan ขอบคุณ ทุกคนมีคำตอบที่ดีสำหรับคำถามนี้
jglouie

1
หมายเหตุ: การใช้printfอย่างสม่ำเสมอจะใช้ได้ผลเช่นเดียวกับการใช้coutอย่างสม่ำเสมอ ปัญหาเพียงอย่างเดียวคือการผสมพวกมันเข้าด้วยกันและสไตล์
user253751

คุณสามารถยกตัวอย่างคุณสมบัติใน C ที่ไม่เทียบเท่า C ++ ได้หรือไม่?
klutt

20

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

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

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

โดยสรุปเพียงเพราะคุณสามารถทำสิ่งที่ไม่ได้หมายความว่าคุณควรและเพียงเพราะคุณไม่ควรทำอะไรไม่ได้หมายความว่าคุณไม่สามารถ :)


ฉันเห็น. สิ่งที่เกี่ยวกับการทำงานมีกรณีใดบ้างเมื่อไวยากรณ์ C ดีกว่าไวยากรณ์ C ++
Bugster

10

C ++ สามารถใช้งานร่วมกับ C โดยการออกแบบย้อนหลังได้ดังนั้นโดยปกติรหัส C จะถูกคอมไพล์โดยคอมไพเลอร์ C ++ ที่ใช้ได้ ( โดยปกติเนื่องจากมีคำสงวนเพิ่มเติมใน C ++ ที่ไม่ได้อยู่ใน C และสามารถนำมาใช้ในรหัส C

อย่างไรก็ตามฉันเห็นว่ามันเป็นการฝึกผสมรหัสที่ไม่ดี ถ้าคุณใช้scanf- การใช้งานprintfถ้าคุณกำลังใช้operator >>- operator <<การใช้งาน สาเหตุที่ตัวดำเนินการ C ++ ที่โอเวอร์โหลดอาจห่อหุ้มฟังก์ชันการทำงานที่คุณไม่ทราบและการจับคู่ไม่ตรงกันจะทำให้โปรแกรมของคุณทำสิ่งที่คุณไม่ต้องการให้ทำ

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


5
ความเข้ากันไม่ได้ระหว่าง C และ C ++ เป็นมากกว่าคำหลัก ระบบการพิมพ์เปลี่ยนแปลงและมีคุณสมบัติที่มีอยู่ใน C (โดยเฉพาะ C99) ซึ่งไม่มีอยู่ใน C ++ (เช่นอาร์เรย์ที่มีความยาวผันแปรได้)
Arafangion

9

หากเราใส่สไตล์การเขียนโค้ดและปัญหาด้านความงามแล้วก็ยังมีปัญหาทางเทคนิคหลายอย่างที่คุณเผชิญเมื่อใช้ C ในรหัส C ++:

  • C คืออะไร C90, C99 หรือ C11 อาจมีปัญหาความเข้ากันได้หลายอย่างขึ้นอยู่กับมาตรฐาน C ที่คุณใช้ ประเภทบูลีน // ความคิดเห็นคุณสมบัติ C99 เช่น VLAs การกำหนดค่าเริ่มต้นเป็นต้น

  • C ++ มีการพิมพ์ที่เข้มงวดกว่า C เพื่อรวบรวมรหัส C ใน C ++ คุณต้องเพิ่ม typecasts ต่าง ๆ เพื่อให้ได้ชนิดที่ต้องการ ซึ่งหมายความว่าคุณอาจต้องเขียนรหัส C คุณภาพการผลิตใหม่อย่างสมบูรณ์แบบเพื่อให้มันทำงานใน C ++

  • typecasts ที่บังคับใช้โดยการพิมพ์ที่เข้มงวดมักเป็นเรื่องดี แต่ในบางกรณีพวกเขาสามารถแนะนำหรือซ่อนข้อบกพร่องได้ นำตัวอย่างผลลัพธ์ที่น่าอับอายจาก malloc () มาเป็นตัวอย่าง สิ่งนี้ควรพิมพ์ด้วย C ++ แต่ไม่ควรอยู่ใน C (1)

  • การผสมฟังก์ชั่น C และ C ++ สามารถนำไปสู่ข้อบกพร่องและพฤติกรรมที่ไม่ได้กำหนด ยกตัวอย่างเช่นมันจะไม่ทำงานในการจัดสรรด้วย malloc () และพ้นกับลบ (2)

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

    ในฐานะที่เป็น sidenote สำหรับโปรแกรมเมอร์ Windows: คอมไพเลอร์ Visual C ++ มีข้อผิดพลาดการรั่วไหลค่อนข้างนานเมื่อมีการใช้ฟังก์ชั่น Windows API CreateThread () ในโปรแกรมเดียวกับไลบรารี C (3, 4)

  • หลักการเรียกอาจเป็นปัญหาสำหรับคอมไพเลอร์บางรายบังคับให้ใช้extern "C"เพื่อบอกฟังก์ชั่นที่ควรจะเชื่อมโยงกับ "แผนการเรียก C" อย่างชัดเจน

  • รายละเอียดที่น่ารำคาญ เครื่องหมายจุลภาคตัวดำเนินการแตกต่างกัน คอมม่าต่อท้ายในการประกาศ struct / enum ได้รับอนุญาตใน C99 / C11 แต่ไม่ใช่ C ++ ขอบเขตของตัวแปรและฟังก์ชั่นต่างๆนั้นแตกต่างกันไป ฯลฯ

มีแนวโน้มมากขึ้น


อ้างอิง:

  1. http://c-faq.com/malloc/cast.html
  2. http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.3
  3. http://www.flounder.com/badprogram.htm#CreateThread
  4. http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx

7

สาเหตุที่ C ++ สามารถคอมไพล์ C นั้นมีไว้สำหรับ "ความเข้ากันได้แบบย้อนหลัง" เท่านั้น (หลีกเลี่ยงการเขียนรหัสการทำงานที่มีอยู่เดิม)

แต่ C ++ มีปรัชญาที่แตกต่างกับ c การผสมเข้าด้วยกันไม่ได้เป็นการบริการที่ดีสำหรับทั้งคู่

วิธีที่ C และ C ++ จัดการ i / o สามารถพึ่งพาวิธีอื่นในการจัดการสถานะภายในของ i / o ดังนั้น - อย่างน้อย - ใช้อินพุตและเอาต์พุตอย่างสม่ำเสมอ

และในโปรแกรม C ++ จะคำนึงถึงรูปแบบ C ++ (ยกเว้นว่าจำเป็นต้องทำที่อื่นเป็นพิเศษ)


5

ฉันจะบอกว่าการเรียนรู้ C อันดับแรกคือ IMHO ความคิดที่ดี วิธีนี้ทำให้ผู้คนเริ่มเข้าใจฮาร์ดแวร์ที่พวกเขาเขียนซอฟต์แวร์

การผสมสองภาษานี้ไม่จำเป็นต้องมีความคิดที่ดี เพราะคุณมีความซับซ้อนที่บ้าของ C ++ ควบคู่ไปกับ raw bit twiddling ร่วมกับ C

อย่างที่คุณเห็นในตัวอย่างง่ายๆเช่นของคุณมีปัญหาการซิงโครไนซ์กับสตรีมประเภทต่างๆและการบัฟเฟอร์ภายใน แต่วิธีการของ C & C ++ นั้นไม่ได้มีความยืดหยุ่นมากขึ้น เปลี่ยนเป็น class x และไม่มีโอเปอเรเตอร์ที่จะใช้การสตรีมและสิ่งของ

มันซับซ้อน...

ฉันคิดว่าโปรแกรมเมอร์ C ++ ที่ดีควรรู้ว่าบิตของมันพลิกไปตามโครงสร้างทุกอย่างอย่างไรและพฤติกรรมที่ซ่อนอยู่คืออะไร

แต่การเรียนรู้ภาษาซีพลัสพลัสอย่างน้อยกว่า 50% ใช้เวลาในการเขียนโค้ดระดับมืออาชีพนานกว่า 5 ปีและคุณไม่สามารถจัดการมันในหลักสูตรที่มีความยาว 6 เดือนโดยมีประสบการณ์มากกว่า 20 ชั่วโมง

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

คลาส wrapper, RAII, เทมเพลต, โอเวอร์โหลด, ความถูกต้องของ const และคลาสนามธรรมที่เป็นนามธรรมสำหรับอินเทอร์เฟซทั่วไป (อย่าใช้วิธี Java f-ng ที่นี่โปรด!) เป็นตัวเลือกที่ดี เพราะพวกเขาเพิ่มความปลอดภัยทั่วไปและใช้งานง่ายซึ่งมีความสำคัญมากสำหรับโครงการในชีวิตจริง อย่าลืมเกี่ยวกับสิ่งต่าง ๆ เช่นการทำลายเสมือนลักษณะการระเบิดของการสร้างสำเนาเริ่มต้นค่าใช้จ่ายในการรันไทม์ความถูกต้องแบบคงที่เป็นต้นที่นี่เช่นกัน

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