สิ่งที่ควรอยู่ใน c-file และสิ่งที่ควรอยู่ใน h-file? ออนไลน์รวมไฟล์ต้นฉบับ C หนึ่งไฟล์ไว้ในอีกไฟล์หนึ่งหรือไม่? ไฟล์ต้นฉบับค

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

ส่วนหนึ่งมันเป็นเรื่องของรสนิยม ดังนั้นหากใครสนใจว่าฉันจะทำยังไงก็ยินดีต้อนรับเจ้าแมว

แม้ว่า "ความจริงทั้งหมด" เกี่ยวกับไฟล์ h จะอยู่ในส่วนที่เกี่ยวข้องของคำอธิบายของตัวประมวลผลล่วงหน้า gcc แต่ฉันจะให้คำอธิบายและภาพประกอบบางอย่างกับตัวเอง

ดังนั้น แท้จริงแล้ว ไฟล์ส่วนหัว (h-file) จึงเป็นไฟล์ที่มีการประกาศ C และคำจำกัดความของแมโครที่มีไว้สำหรับใช้ในไฟล์ต้นฉบับหลายไฟล์ (c-files) เรามาอธิบายเรื่องนี้กัน

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

ดังนั้นเราจึงเพียงแค่แยกส่วนทั่วไปของไฟล์ทั้งสองและวางไว้ในไฟล์ส่วนหัว
แต่ไฟล์ส่วนหัวเป็นส่วนต่อประสานในกรณีนี้หรือไม่

  • หากเราจำเป็นต้องใช้ฟังก์ชันการทำงานที่ฟังก์ชัน 1 และ 2 นำไปใช้ที่อื่น แสดงว่าใช่
  • หากมาโคร 2 มีไว้สำหรับใช้ในไฟล์ Unit1.c และ Unit2.c เท่านั้น จะไม่มีตำแหน่งในไฟล์อินเทอร์เฟซ
ยิ่งไปกว่านั้น เราจำเป็นต้องมีไฟล์ C สองไฟล์เพื่อใช้อินเทอร์เฟซที่กำหนดไว้ในไฟล์ส่วนหัวหรือไม่? หรืออันเดียวพอ?
คำตอบสำหรับคำถามนี้ขึ้นอยู่กับรายละเอียดการใช้งานฟังก์ชันอินเทอร์เฟซและตำแหน่งที่นำไปใช้ ตัวอย่างเช่น หากคุณทำให้ไดอะแกรมมีรายละเอียดมากขึ้น คุณสามารถจินตนาการถึงสถานการณ์ที่มีการนำฟังก์ชันอินเทอร์เฟซไปใช้ในไฟล์ต่างๆ:


ตัวเลือกการใช้งานนี้นำไปสู่การเชื่อมโยงโค้ดที่สูง ความสามารถในการทดสอบต่ำ และความยากลำบากในการนำโมดูลดังกล่าวกลับมาใช้ใหม่
เพื่อหลีกเลี่ยงปัญหาดังกล่าว ฉันมักจะถือว่าไฟล์ C และไฟล์ส่วนหัวเป็นโมดูลเดียวเสมอ ซึ่งในนั้น
  • ไฟล์ส่วนหัวประกอบด้วยเฉพาะการประกาศฟังก์ชัน ประเภท มาโครที่เป็นส่วนหนึ่งของอินเทอร์เฟซของโมดูลนี้
  • ในทางกลับกันไฟล์ C จะต้องมีการใช้งานฟังก์ชั่นทั้งหมดที่ประกาศในไฟล์ h รวมถึงประเภทส่วนตัว มาโคร และฟังก์ชั่นที่จำเป็นในการใช้งานอินเทอร์เฟซ
ดังนั้น หากฉันจะติดตั้งโค้ดที่สอดคล้องกับไดอะแกรมด้านบน ฉันจะพยายามทำสิ่งต่อไปนี้ (ส่วนท้าย _с และ _h ในชื่อไฟล์ถูกเพิ่มเข้าไป เนื่องจากไม่สามารถใช้จุดในเครื่องมือที่ฉันใช้สร้างไม่ได้ แผนภาพ):


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

ฉันหวังว่าฉันจะสามารถระบุเอนทิตีเหล่านั้นที่ต้องวางไว้ในไฟล์ส่วนหัวได้ และยังแสดงความแตกต่างระหว่างอินเทอร์เฟซและไฟล์ที่มีการประกาศและมาโครที่จำเป็นสำหรับไฟล์ C หลายไฟล์

ขอขอบคุณที่ให้ความสนใจกับเนื้อหา

ไฟล์ต้นฉบับ

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

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

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

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

ในตัวอย่างต่อไปนี้ โปรแกรมต้นฉบับประกอบด้วยไฟล์ต้นฉบับสองไฟล์ ฟังก์ชั่น หลักและ สูงสุดนำเสนอใน แยกไฟล์- การทำงาน หลักใช้ฟังก์ชัน สูงสุดในกระบวนการดำเนินการ

/* ไฟล์ต้นฉบับ 1 - ฟังก์ชั่นหลัก */

ภายนอก int max(int, int); /* ประกาศฟังก์ชัน */

main() /* นิยามฟังก์ชัน */

int w = หนึ่ง, x = สอง, y = สาม;

/* ไฟล์ต้นฉบับ 2 - ฟังก์ชั่นสูงสุด */

int max (a, b) /* นิยามฟังก์ชัน */

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

บรรทัดที่ขึ้นต้นด้วยสัญลักษณ์ # คือคำสั่งของตัวประมวลผลล่วงหน้า คำสั่งระบุให้ผู้ประมวลผลล่วงหน้าทราบถึงความจำเป็นในการแทนที่ตัวระบุ ONE, TWO, THREE ด้วยค่าที่สอดคล้องกันในไฟล์ต้นฉบับแรก ขอบเขตของคำสั่งไม่ขยายไปยังไฟล์ต้นฉบับที่สอง

สนับสนุน.microsoft

เมื่อคุณปรับเปลี่ยนแฟ้มต้นฉบับใน Visual C++ และบันทึก บรรทัดจะต้องลงท้ายด้วยชุด "CR/LF" [การขึ้นบรรทัดใหม่ การป้อนบรรทัด] ใน ระบบยูนิกซ์บรรทัดจะลงท้ายด้วย "LF" ดังนั้นเมื่อดูไฟล์ที่ถูกแก้ไขแล้ว กลุ่มวินโดว์บนระบบ UNIX อักขระ "^M" จำนวนมากอาจปรากฏในสตริง สิ่งนี้จะเกิดขึ้นเมื่อใช้โปรแกรมแก้ไขที่ไม่รู้วิธีการตีความเท่านั้น ไฟล์วินโดว์- Visual C++ สามารถเปิดไฟล์ที่มีบรรทัดลงท้ายด้วยการสร้าง UNIX LF หากคุณแก้ไขไฟล์นี้และบันทึกจาก Visual C++ ไฟล์นั้นจะถูกบันทึกในรูปแบบ Windows (คุณจะเห็น CR/LF ไม่ใช่ LF ที่เคยอยู่ในระบบ)

บทความนี้อธิบายขั้นตอนในการบันทึกไฟล์ที่ถูกแก้ไขที่สร้างขึ้นบนแพลตฟอร์ม Windows ในรูปแบบที่สามารถใช้ได้กับระบบ UNIX

บันทึก: Visual C++.NET IDE มีฟังก์ชันสำหรับบันทึกไฟล์ในรูปแบบ UNIX ใน IDE ให้บันทึกไฟล์โดยใช้ บันทึกเป็น...ให้เลือกบันทึกจากรายการแบบเลื่อนลง บันทึกด้วยการเข้ารหัส...แล้วกดปุ่มthrn ใช่- เลือกการเข้ารหัสสตริงจากรายการแบบเลื่อนลง ยูนิกซ์ (LF)แล้วคลิกปุ่ม ตกลง.

คุณสามารถใช้ขั้นตอนต่อไปนี้เพื่อสร้างโครงการแอปพลิเคชันคอนโซล Win32 ที่แปลงไฟล์ที่มี "CR/LF" เพื่อสิ้นสุดบรรทัดสำหรับ "LF":

  1. หากต้องการสร้างใหม่โดยใช้แอปพลิเคชันคอนโซล Win32 ซึ่งเป็นโปรเจ็กต์ว่างชื่อ DOS2UNIX
  2. จาก ไฟล์เมนู ให้กดปุ่ม ใหม่แล้วคลิกปุ่ม ไฟล์แท็บ
  3. เลือก ไฟล์ต้นฉบับ C/C++และกรอกชื่อไฟล์ใหม่ DOS2UNIX.cpp
  4. วางโค้ดต่อไปนี้ลงใน DOS2UNIX.cpp:

    #รวม #รวม #รวม ใช้เนมสเปซมาตรฐาน; int main(int argc, char* argv) ( ถ้า(argc !=2) ( ศาล<< "Please specify: dos2unix filename" << endl; return 0; } char ch; char temp="\0"; //Open the file for reading in binarymode. ifstream fp_read(argv, ios_base::in \ / ios_base::binary); sprintf(temp, "%s.temp", argv); //Create a temporary file for writing in the binary mode. This //file will be created in the same directory as the input file. ofstream fp_write(temp, ios_base::out \ / ios_base::trunc \ / ios_base::binary); while(fp_read.eof() != true) { fp_read.get(ch); //Check for CR (carriage return) if((int)ch == 0x0D) continue; if (!fp_read.eof())fp_write.put(ch); } fp_read.close(); fp_write.close(); //Delete the existing input file. remove(argv); //Rename the temporary file to the input file. rename(temp, argv); //Delete the temporary file. remove(temp); return 0; }

  5. จาก การก่อสร้างเมนู ให้กดปุ่ม การสร้าง DOS2UNIX.exeเพื่อสร้างไฟล์ EXE

คุณอาจต้องทดสอบไฟล์ exe นี้เพื่อดูว่าไฟล์ทำงานถูกต้องหรือไม่ เมื่อต้องการทำเช่นนี้ ให้เปิดแฟ้มในตัวแก้ไขไบนารีของ Visual C++ เมื่อคุณเลือก เปิดในกลุ่ม ไฟล์เมนูโดยเลือก DOS2UNIX.ex การตั้งค่า เปิดเป็นถึงใคร ไบนารี่แล้วคลิก เปิด- ตัวอย่างเช่น หากไฟล์มี "hellocrlfworld" ข้อมูลไฟล์ไบนารี (เลขฐานสิบหก) จะมีลักษณะดังนี้:

48 65 6 ค 6 ค 6F 0 ง 0A 57 6F 72 6 ค 64

นี่เทียบเท่ากับ:

สวัสดี
โลก

ที่พรอมต์คำสั่ง ให้เรียกใช้ dos2unix.exe - ถัดไป เปิดไฟล์ในตัวแก้ไขไบนารี Visual C++ คุณจะเห็นว่า 0x0d s ถูกลบออก จนกว่าคุณจะเปลี่ยนไฟล์และบันทึกใน Visual C++ 0x0d s จะไม่ปรากฏขึ้น

สามารถใช้ร่วมกับ Visual C++ Automation Model เพื่อทำให้กระบวนการทั้งหมดเป็นแบบอัตโนมัติ คุณสามารถเขียนสคริปต์แมโคร Microsoft Visual Basic แบบธรรมดาเพื่อเรียกใช้เครื่องมือนี้ได้ แต่ต้องเพิ่มเครื่องมือก่อน บริการเมนูมีลักษณะดังนี้:

  1. จาก บริการเมนู ให้กดปุ่ม การตั้งค่าแล้วคลิกปุ่ม บริการแท็บ
  2. ระบุชื่อเช่น DOS2UNIX และระบุเส้นทางแบบเต็มไปยังไฟล์ Dos2unix.exe ทีมแก้ไขฟิลด์
  3. ตั้งค่าอาร์กิวเมนต์เป็น $(Filename)$(FileExt)
  4. ระบุไดเร็กทอรีต้นทาง $(WkspDir) (ระบุพาธของคุณเอง)

หากต้องการตรวจสอบการทำงานของโปรแกรม ให้เปิดไฟล์ในตัวแก้ไข Visual C++ จากนั้นเปิดไฟล์ บริการเมนูเริ่ม ดอสทูยูนิกซ์วิธี. คุณจะเห็นว่าไฟล์ที่เปิดในตัวแก้ไขได้ลบอักขระ CR ทั้งหมดออกแล้ว

หากคุณต้องการทำให้กระบวนการนี้เป็นแบบอัตโนมัติ ให้จัดการเพื่อให้ทุกครั้งที่คุณบันทึกไฟล์ที่เปิดอยู่ในโปรแกรมแก้ไข Visual C++ DOS2UNIX.exe จะถูกเรียกให้ลบ 0x0d s จากนั้นใช้แมโคร VBScript ต่อไปนี้:

"เหตุการณ์นี้เกิดขึ้นทุกครั้งที่เอกสารถูกบันทึกในตัวแก้ไข VC++ Sub Application_DocumentSave(theDocument) "ซึ่งจะเรียกเครื่องมือผู้ใช้ในเมนูเครื่องมือ "เปลี่ยนตัวเลขขึ้นอยู่กับสิ่งที่คุณมี โดยค่าเริ่มต้นคุณมีเพียง 6 เครื่องมือภายใต้เมนู Tools ดังนั้นเครื่องมือ DOS2UNIX จะเป็นอันดับที่ 7 ExecuteCommand "UserTool7" สิ้นสุดย่อย

รหัส VBScript นี้จะใช้งานได้เฉพาะเมื่อคุณเปิดไฟล์ใน Visual C++ Editor นี่เป็นวิธีเดียวที่จะเรียกไฟล์ exe จากมาโคร VBScript (ไม่สามารถส่งพารามิเตอร์มาโคร VBScript ได้) คุณสามารถเขียนแทนได้และจะมีความยืดหยุ่นมากขึ้น เรียกใช้เครื่องมือ "DOS2UNIX.exe" จาก Add-in โดยไม่ต้องเพิ่มเข้าไป บริการเมนู.

ใน Visual C++ โดยใช้แมโคร VBScript ที่ให้มา:

  1. เปิดไฟล์ที่มีอยู่ด้วยนามสกุล .dsm หรือสร้างขึ้นใหม่
  2. วางรหัสที่ให้ไว้ก่อนหน้านี้ลงในไฟล์
  3. ใน Visual C++ ให้ทำดังต่อไปนี้:
    1. จาก บริการเมนู ให้กดปุ่ม การตั้งค่า.
    2. คลิกปุ่ม ไฟล์มาโครและไฟล์เสริมแท็บ
    3. คลิกปุ่ม ทบทวนโหลดไฟล์ .dsm ที่มีมาโคร เมื่ออยู่ในไฟล์ .dsm ก็ถูกเลือกเข้ามา ทบทวนกล่องโต้ตอบ ไฟล์จะปรากฏขึ้นมา ส่วนเสริมและมาโครรายการไฟล์โดยใช้ช่องทำเครื่องหมายที่เลือกอยู่ข้างๆ
    4. คลิกปุ่ม ปิดเพื่อดำเนินการต่อ

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



โหวตออนไลน์ (8)

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

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

นามสกุลไฟล์ไม่สำคัญสำหรับคอมไพเลอร์ภาษา C ส่วนใหญ่ ดังนั้นจึงใช้ได้

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

ขึ้นอยู่กับสภาพแวดล้อมการสร้างของคุณ (คุณจะไม่ระบุ) คุณอาจพบว่ามันทำงานตามที่คุณต้องการ

อย่างไรก็ตาม มีสภาพแวดล้อมมากมาย (ทั้ง IDE และ Makefile ที่ทำด้วยมือจำนวนมาก) ที่คาดหวังว่า *.c จะต้องถูกคอมไพล์ - หากสิ่งนี้เกิดขึ้น คุณจะพบข้อผิดพลาดของตัวเชื่อมโยงเนื่องจากสัญลักษณ์ที่ซ้ำกัน

โดยทั่วไปควรหลีกเลี่ยงการปฏิบัตินี้

หากคุณต้อง # รวมแหล่งที่มาอย่างแน่นอน (และโดยทั่วไปควรหลีกเลี่ยง) ให้ใช้ไฟล์อื่นสำหรับไฟล์นั้น

คุณสามารถใช้คอมไพเลอร์ gcc บน linux เพื่อลิงก์สองไฟล์กับเอาต์พุตเดียว สมมติว่าคุณมีไฟล์ c สองไฟล์ ไฟล์หนึ่งคือ "main.c" และอีกไฟล์คือ "support.c" ดังนั้นคำสั่งให้เชื่อมต่อสองตัวนี้ก็คือ

Gcc main.c support.c -o main.out

สองไฟล์นี้จะเชื่อมโยงกับ main.out หนึ่งไฟล์ ในการรันเอาต์พุตคำสั่งจะเป็น

./main.out

หากคุณใช้ฟังก์ชัน main.c ซึ่งได้รับการประกาศในไฟล์ support.c คุณควรประกาศฟังก์ชันดังกล่าวใน main และใช้คลาสพื้นที่เก็บข้อมูลภายนอกด้วย

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

การรวมไฟล์ .c ทำให้เรามีโอกาสเข้าถึงฟันเฟืองในเครื่อง ซึ่งน่าสนใจสำหรับเราในการทดสอบ

ภาษา C ไม่ได้ห้าม #include ประเภทนี้ แต่หน่วยการแปลผลลัพธ์จะต้องยังคงเป็น C ที่ถูกต้อง

ฉันไม่รู้ว่าคุณใช้โปรแกรมอะไรกับไฟล์ .prj หากคุณใช้บางอย่างเช่น "make" หรือ Visual Studio หรืออะไรก็ตาม เพียงตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าเป็นรายการไฟล์ที่ต้องคอมไพล์ โดยไม่มีไฟล์ที่ไม่สามารถคอมไพล์แยกกันได้

ใช้อย่างถูกต้องนี่อาจเป็นวิธีที่มีประโยชน์

สมมติว่าคุณมีระบบย่อยที่มีความสำคัญต่อภารกิจที่ซับซ้อนซึ่งมีอินเทอร์เฟซสาธารณะที่ค่อนข้างเล็กและมีโค้ดการใช้งานจำนวนมากที่ยังไม่ได้ใช้งาน โค้ดมีความยาวหลายพันบรรทัด มีฟังก์ชันส่วนตัวนับร้อยและมีข้อมูลส่วนตัวไม่น้อย หากคุณทำงานกับระบบฝังตัวที่ไม่ซับซ้อน คุณอาจพบสถานการณ์นี้บ่อยครั้ง

โซลูชันของคุณมีแนวโน้มที่จะแบ่งชั้น เป็นโมดูล และแยกส่วน และประเด็นเหล่านี้สามารถนำเสนอและปรับปรุงได้อย่างสะดวกโดยการเขียนโค้ดส่วนต่างๆ ของระบบย่อยในไฟล์ต่างๆ

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

หากคุณรวมทุกอย่างไว้ในโมดูลซอร์ส C เดียวคุณจะได้รับ -

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

    ข้อมูลระดับช่องและฟังก์ชั่นถูกซ่อนอยู่

    หลีกเลี่ยงมลภาวะเนมสเปซและผลที่ตามมา - คุณสามารถใช้ชื่อที่ยุ่งยากน้อยลงได้

    การรวบรวมและการสื่อสารที่รวดเร็วยิ่งขึ้น

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

อย่างไรก็ตาม คุณต้องกำหนดแบบแผนบางประการเพื่อจัดการกับเรื่องนี้ สิ่งนี้จะขึ้นอยู่กับ toolchain ของคุณในระดับหนึ่ง แต่มีคำแนะนำทั่วไปบางประการ

    วางส่วนต่อประสานสาธารณะไว้ในไฟล์ส่วนหัวแยกต่างหาก - คุณยังควรทำสิ่งนี้อยู่

    มีไฟล์ .c หลักหนึ่งไฟล์ที่รวมไฟล์ .c ลูกทั้งหมด ซึ่งอาจรวมถึงโค้ดสำหรับอินเทอร์เฟซแบบเปิดด้วย

    ใช้ตัวป้องกันคอมไพเลอร์เพื่อป้องกันไม่ให้ส่วนหัวส่วนตัวและโมดูลต้นทางถูกรวมไว้ในโมดูลการคอมไพล์ภายนอก

    ข้อมูลส่วนบุคคลและฟังก์ชันทั้งหมดจะต้องประกาศให้เป็นแบบคงที่

    รักษาความแตกต่างทางแนวคิดระหว่างไฟล์ .c และ .h สิ่งนี้ใช้แบบแผนที่มีอยู่ ความแตกต่างก็คือ คุณจะมีโฆษณาคงที่จำนวนมากในส่วนหัวของคุณ

    หาก toolchain ของคุณไม่ได้กำหนดสิ่งใด คุณไม่ควรระบุไฟล์การใช้งานส่วนตัว เช่น .c และ .h หากคุณใช้ยามที่เปิดใช้งาน พวกเขาจะไม่สร้างโค้ดและจะไม่แนะนำชื่อใหม่ใด ๆ (คุณอาจจบลงด้วยส่วนที่ว่างเปล่าบางส่วน) ข้อดีอย่างมากคือเครื่องมืออื่นๆ (เช่น IDE) จะจัดการไฟล์เหล่านี้ตามนั้น

นี่สบายดีใช่ไหม? ใช่ มันจะรวบรวม

นี่แนะนำเหรอ? ไฟล์ no - .c จะถูกคอมไพล์เป็นไฟล์ .obj ซึ่งเชื่อมโยงหลังจากการคอมไพล์ (โดยตัวเชื่อมโยง) ไปยังไฟล์ปฏิบัติการ (หรือไลบรารี) ดังนั้นจึงไม่จำเป็นต้องรวมไฟล์ .c หนึ่งไฟล์ไว้ในอีกไฟล์หนึ่ง คุณมักจะต้องการสร้างไฟล์ .h ที่แสดงรายการฟังก์ชัน/ตัวแปรที่มีอยู่ในไฟล์ .c อื่น และรวมไฟล์ .h ไว้ด้วย



2024 wisemotors.ru. วิธีนี้ทำงานอย่างไร. เหล็ก. การทำเหมืองแร่ สกุลเงินดิจิทัล