อะไรคือความแตกต่างระหว่าง #include <filename> และ #include“ filename”


2354

ในภาษาการเขียนโปรแกรม C และ C ++ ความแตกต่างระหว่างการใช้วงเล็บมุมและการใช้อัญประกาศในincludeคำสั่งมีดังนี้

  1. #include <filename>
  2. #include "filename"



สำหรับพฤติกรรมของ Visual Studio โปรดตรวจสอบ: docs.microsoft.com/en-us/cpp/preprocessor/ ......
smwikipedia

คำตอบ:


1404

ในทางปฏิบัติความแตกต่างอยู่ในตำแหน่งที่ตัวประมวลผลล่วงหน้าค้นหาไฟล์ที่รวมอยู่

สำหรับ#include <filename>การค้นหาตัวประมวลผลล่วงหน้าในลักษณะขึ้นอยู่กับการใช้งานตามปกติในไดเรกทอรีการค้นหาที่กำหนดไว้ล่วงหน้าโดยคอมไพเลอร์ / IDE โดยปกติจะใช้วิธีนี้เพื่อรวมไฟล์ส่วนหัวของไลบรารีมาตรฐาน

สำหรับ#include "filename"ตัวประมวลผลก่อนค้นหาในไดเรกทอรีเดียวกันเป็นไฟล์ที่มีคำสั่งจากนั้นตามเส้นทางการค้นหาที่ใช้สำหรับ#include <filename>ฟอร์ม โดยปกติจะใช้วิธีนี้เพื่อรวมไฟล์ส่วนหัวที่โปรแกรมเมอร์กำหนด

คำอธิบายที่สมบูรณ์มากขึ้นมีให้บริการในจีซีเอกสารเกี่ยวกับเส้นทางการค้นหา


135
คำสั่ง: "ตัวประมวลผลล่วงหน้าค้นหาในไดเรกทอรีเดียวกัน ... " อาจเป็นจริงในทางปฏิบัติ แต่สถานะมาตรฐานว่าไฟล์ต้นฉบับที่มีชื่อคือ "ค้นหาในลักษณะที่กำหนดตามการนำไปใช้" ดูคำตอบจาก piCookie
Richard Corden

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

5
"... ตัวประมวลผลล่วงหน้าค้นหาในไดเรกทอรีเดียวกันกับไฟล์ที่กำลังรวบรวมเพื่อรวมไฟล์" คำสั่งนี้ไม่ถูกต้องสมบูรณ์ ฉันสนใจคำถามนี้เพราะฉันอยากรู้ว่าคำตอบที่แท้จริงคืออะไร แต่ฉันรู้ว่านี่ไม่ใช่ความจริงเพราะอย่างน้อยกับ gcc เมื่อคุณระบุเส้นทางเพิ่มเติมรวมกับ -I ที่จะค้นหาไฟล์ที่ระบุด้วยชื่อไฟล์ #include ชั่วโมง "
Gabriel Southern

9
ผู้ที่ไม่ชอบคำตอบโปรดยกตัวอย่างการปฏิบัติหนึ่งข้อที่ผิด
0kcats

1
แน่นอนฉันเพิ่งผสมไวยากรณ์เหล่านี้เมื่อรวมส่วนหัวจากไลบรารี 'เดียวกัน' และจบลงด้วยข้อผิดพลาดการกำหนดซ้ำ หากฉันเข้าใจถูกต้องให้#include <...>ใช้แพ็คเกจที่ติดตั้งบนระบบและ#include "..."ใช้เวอร์ชันที่เก็บใกล้เคียง ฉันอาจมีที่ถอยหลัง ทั้งสองวิธีตัวป้องกันการรวมในส่วนหัวของแพคเกจนั้นจะนำหน้าด้วยการขีดเส้นใต้ (อาจเป็นแบบแผนสำหรับแพ็คเกจหรืออาจเป็นวิธีการป้องกันการผสมสองอย่างโดยจงใจแม้ว่าตัวระบุเวอร์ชันจะสมเหตุสมผลสำหรับฉันมากขึ้น)
John P

714

วิธีเดียวที่จะรู้คือการอ่านเอกสารการใช้งานของคุณ

ในมาตรฐาน Cส่วน 6.10.2 ย่อหน้า 2 ถึง 4 สถานะ:

  • คำสั่ง preprocessing ของแบบฟอร์ม

    #include <h-char-sequence> new-line

    ค้นหาสถานที่ลำดับของการดำเนินงานที่กำหนดไว้สำหรับเป็นหัวระบุไม่ซ้ำกันโดยลำดับที่ระบุระหว่าง<และ>ตัวคั่นและทำให้เกิดการเปลี่ยนคำสั่งว่าโดยเนื้อหาทั้งหมดของส่วนหัว วิธีระบุสถานที่หรือส่วนหัวที่ระบุนั้นมีการนำมาใช้

  • คำสั่ง preprocessing ของแบบฟอร์ม

    #include "q-char-sequence" new-line

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

    #include <h-char-sequence> new-line

    ด้วยลำดับที่มีอยู่เหมือนกัน (รวมถึง>อักขระถ้ามี) จากคำสั่งดั้งเดิม

  • คำสั่ง preprocessing ของแบบฟอร์ม

    #include pp-tokens new-line

    (ที่ไม่ตรงกับหนึ่งในสองรูปแบบก่อนหน้านี้) ได้รับอนุญาต โทเค็นการประมวลผลล่วงหน้าหลังจากincludeอยู่ในคำสั่งจะถูกประมวลผลเช่นเดียวกับในข้อความปกติ (แต่ละตัวระบุที่กำหนดในปัจจุบันเป็นชื่อแมโครจะถูกแทนที่ด้วยรายการการแทนที่โทเค็นการประมวลผลล่วงหน้า) คำสั่งที่เกิดขึ้นหลังจากการแทนที่ทั้งหมดจะต้องตรงกับหนึ่งในสองรูปแบบก่อนหน้านี้ วิธีที่ลำดับของโทเค็นการประมวลผลล่วงหน้าระหว่าง a <และ>โทเค็นการประมวลผลล่วงหน้าหรือคู่ของ"อักขระจะรวมกันเป็นชื่อส่วนหัวเดียวโทเค็น preprocessing โทเค็นการดำเนินงานที่กำหนดไว้

คำนิยาม:

  • h-char: สมาชิกของชุดอักขระต้นฉบับยกเว้นอักขระบรรทัดใหม่และ >

  • q-char: สมาชิกของชุดอักขระต้นฉบับยกเว้นอักขระบรรทัดใหม่และ "


108
ที่เกี่ยวข้อง: การนำไปใช้ในg ++และในVisual c ++
Alexander Malakhov

27
@piCookie ทั้ง <filename> และ "filename" ค้นหาสถานที่ที่มีการนำไปปฏิบัติ แล้วความแตกต่างคืออะไร?
onmyway133

15
@ สเตฟานฉันแค่อ้างอิงมาตรฐานซึ่งไม่ได้พูดอะไรเกี่ยวกับ INCLUDE_PATH การดำเนินการของคุณอาจทำเช่นนั้นและของฉันอาจไม่ คำถามเดิมคือ C ทั่วไปและไม่ใช่ gcc โดยเฉพาะ (ซึ่งฉันไม่คิดว่าใช้ INCLUDE_PATH) หรือ Microsoft C (ซึ่งฉันคิดว่าทำ) หรืออื่น ๆ ดังนั้นจึงไม่สามารถตอบได้โดยทั่วไป แต่ต้องอ้างอิงเอกสารของแต่ละการใช้งาน
piCookie

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

132
"นี่เป็นวิธีมาตรฐาน C สามารถอย่างละเอียดและไม่ได้ตอบคำถามของคุณ"
anatolyg

287

ลำดับของอักขระระหว่าง <และ> อ้างอิงถึงส่วนหัวซึ่งไม่จำเป็นต้องเป็นไฟล์ การใช้งานนั้นฟรีมากที่จะใช้ลำดับอักขระตามที่ต้องการ (ส่วนใหญ่อย่างไรก็ตามเพียงถือเป็นชื่อไฟล์และทำการค้นหาในเส้นทางรวมเป็นรัฐโพสต์อื่น ๆ )

หาก#include "file"มีการใช้แบบฟอร์มการใช้งานครั้งแรกจะมองหาไฟล์ที่มีชื่อที่กำหนดหากได้รับการสนับสนุน หากไม่ได้รับการสนับสนุน (หรือสนับสนุน) หรือการค้นหาล้มเหลวการใช้งานจะมีลักษณะเหมือนกับว่าใช้#include <file>รูปแบบอื่น ( )

นอกจากนี้ยังมีรูปแบบที่สามและใช้เมื่อ#includeคำสั่งไม่ตรงกับรูปแบบใดรูปแบบหนึ่งด้านบน ในแบบฟอร์มนี้การประมวลผลล่วงหน้าขั้นพื้นฐานบางอย่าง (เช่นการขยายมาโคร) จะทำใน "ตัวถูกดำเนินการ" ของ#includeคำสั่งและคาดว่าผลลัพธ์จะตรงกับหนึ่งในสองรูปแบบอื่น ๆ


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

3
ดูความคิดเห็นของ Dan Moulding เพื่อรับคำตอบของ quest49; ส่วนหัวมาตรฐานไม่จำเป็นต้องอยู่ในรูปแบบไฟล์ แต่สามารถสร้างได้ในตัว
aib

10
ฉันอ่านมาแล้วว่า "ส่วนหัวมาตรฐานไม่จำเป็นต้องอยู่ในรูปแบบไฟล์" เป็นเวลาสิบปี การดูแลเพื่อให้เป็นตัวอย่างที่แท้จริงของโลก?
Maxim Egorushkin

12
@ Maxim Yegorushkin: ฉันไม่สามารถนึกถึงตัวอย่างในโลกแห่งความจริงที่มีอยู่ได้เช่นกัน อย่างไรก็ตามยังไม่มีการคอมไพเลอร์ C11 สมบูรณ์สามารถที่มีอยู่สำหรับ MS-DOS ในกรณีที่ส่วนหัวจะได้ไม่ต้องเป็นไฟล์ นี่เป็นเพราะชื่อส่วนหัว C11 บางส่วนไม่เข้ากันได้กับข้อ จำกัด ชื่อไฟล์ "8.3" MS-DOS
Dan Molding เมื่อ

18
@MaximEgorushkin: ผู้ VAX / VMS C คอมไพเลอร์ที่เก็บไว้ทั้งหมดส่วนหัวห้องสมุดรันไทม์ C ในไฟล์ห้องสมุดที่เป็นข้อความเดียว (คล้ายกับที่เก็บยูนิกซ์) และใช้เชือกระหว่าง<และ>เป็นกุญแจสำคัญในการจัดทำดัชนีเข้าไปในห้องสมุด
Adrian McCarthy

117

บางคำตอบที่ดีที่นี่อ้างอิงถึงมาตรฐาน C แต่ลืมมาตรฐาน POSIX โดยเฉพาะพฤติกรรมที่เฉพาะเจาะจงของคำสั่งc99 (เช่น C คอมไพเลอร์)

ตามคุณสมบัติที่เปิดฐานกลุ่มฉบับที่ 7 ,

ไดเรกทอรีฉัน

เปลี่ยนอัลกอริทึมสำหรับการค้นหาสำหรับส่วนหัวที่มีชื่ออยู่ pathnames ไม่แน่นอนที่จะมองในไดเรกทอรีชื่อโดยไดเรกทอรีชื่อพา ธ ก่อนที่จะมองในสถานที่ตามปกติ ดังนั้นส่วนหัวที่มีชื่ออยู่ในเครื่องหมายคำพูดคู่ ("") จะถูกค้นหาครั้งแรกในไดเรกทอรีของไฟล์ที่มีบรรทัด#includeจากนั้นในไดเรกทอรีที่มีชื่อในตัวเลือก-Iและสุดท้ายในสถานที่ปกติ สำหรับส่วนหัวที่มีชื่ออยู่ในวงเล็บมุม ("<>") ส่วนหัวจะถูกค้นหาเฉพาะในไดเรกทอรีที่มีชื่อในตัวเลือก-Iแล้วในสถานที่ปกติ ไดเรกทอรีที่มีชื่อในตัวเลือก-Iจะถูกค้นหาตามลำดับที่ระบุc99อุทธรณ์คำสั่ง

ดังนั้นในสภาพแวดล้อมที่สอดคล้องกับ POSIX กับคอมไพเลอร์ที่เข้ากันได้กับ POSIX POSIX #include "file.h"มีแนวโน้มที่จะค้นหา./file.hก่อนโดยที่.เป็นไดเรกทอรีที่เป็นไฟล์ที่มี#includeคำสั่งในขณะที่#include <file.h>มีแนวโน้มที่จะค้นหา/usr/include/file.hครั้งแรกที่/usr/includeระบบของคุณกำหนดไว้สถานที่ปกติสำหรับส่วนหัว (ดูเหมือนว่าไม่ได้กำหนดโดย POSIX)


1
แหล่งที่มาที่แน่นอนของข้อความคืออะไร? มันมาจากส่วนที่เป็นบรรทัดฐานของ IEEE Std 1003.1, 2013 หรือไม่?
osgx

7
@osgx: พบว่าถ้อยคำ (หรือบางสิ่งที่คล้ายกันมาก) ในข้อกำหนด POSIX สำหรับc99- ซึ่งเป็นชื่อ POSIX สำหรับคอมไพเลอร์ C (มาตรฐาน POSIX 2008 แทบจะไม่สามารถอ้างถึง C11 ได้การอัปเดต 2013 เป็น POSIX 2008 ไม่ได้เปลี่ยนมาตรฐาน C ที่อ้างถึง)
Jonathan Leffler

1
นี่เป็นความคิดแรกของฉันด้วย manpage สำหรับ GCC รวมถึงสิ่งนี้เป็นสิ่งที่ต้องทำคนอื่น ๆ นอกจากนี้ยังมีสิ่งที่คล้ายกันสำหรับห้องสมุด -L-
Pryftan

50

เอกสาร GCC กล่าวว่าสิ่งต่อไปนี้เกี่ยวกับความแตกต่างระหว่างทั้งสอง:

‘#include’ทั้งผู้ใช้และระบบหัวรวมไฟล์โดยใช้คำสั่ง preprocessing มันมีสองสายพันธุ์:

#include <file>

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

#include "file"

ตัวแปรนี้ใช้สำหรับไฟล์ส่วนหัวของโปรแกรมของคุณเอง <file>จะค้นหาไฟล์ไฟล์ชื่อแรกในไดเรกทอรีที่มีไฟล์ปัจจุบันแล้วในไดเรกทอรีที่อ้างแล้วไดเรกทอรีเดียวกับที่ใช้สำหรับ คุณสามารถเพิ่มไดเรกทอรีลงในรายการไดเรกทอรีเสนอราคาด้วย-iquoteตัวเลือก อาร์กิวเมนต์ของ‘#include’ว่าไม่ว่าจะคั่นด้วยเครื่องหมายอัญประกาศหรือวงเล็บมุมทำตัวเหมือนค่าคงที่สตริงในความคิดเห็นที่ไม่เป็นที่รู้จักและชื่อแมโครจะไม่ขยาย ดังนั้นระบุรวมของไฟล์ระบบหัวชื่อ#include <x/*y>x/*y

อย่างไรก็ตามหากแบ็กสแลชเกิดขึ้นภายในไฟล์ถือว่าเป็นอักขระข้อความธรรมดาไม่ใช่อักขระยกเว้น ไม่มีการประมวลผลลำดับอักขระที่เหมาะสมกับค่าคงที่สตริงใน C ที่ถูกประมวลผล ดังนั้น#include "x\n\\y"ระบุชื่อไฟล์ที่มีแบ็กสแลชสามรายการ (ระบบบางระบบตีความ '\' เป็นตัวคั่นพา ธ ทั้งหมดเหล่านี้ตีความ‘/’ในลักษณะเดียวกันมันเป็นแบบพกพามากที่สุดที่จะใช้เท่านั้น‘/’)

มันเป็นข้อผิดพลาดหากมีสิ่งใด (นอกเหนือจากความคิดเห็น) ในบรรทัดหลังชื่อไฟล์


46

มันทำ:

"mypath/myfile" is short for ./mypath/myfile

ด้วย.การเป็นไดเรกทอรีของไฟล์ที่#includeมีอยู่ในและ / หรือไดเรกทอรีการทำงานปัจจุบันของคอมไพเลอร์และ / หรือdefault_include_paths

และ

<mypath/myfile> is short for <defaultincludepaths>/mypath/myfile

ถ้า./อยู่ใน<default_include_paths>นั้นมันไม่ได้สร้างความแตกต่าง

หากmypath/myfileอยู่ในไดเรกทอรีอื่นรวมถึงพฤติกรรมที่ไม่ได้กำหนด


12
ไม่มีจะไม่เทียบเท่ากับ#include "mypath/myfile" #include "./mypath/myfile"เป็นคำตอบของ piCookie กล่าวว่าคำพูดคู่บอกคอมไพเลอร์ที่จะค้นหาในลักษณะที่มีการดำเนินงานที่กำหนดไว้ - #include <...>ซึ่งรวมถึงการค้นหาในสถานที่ที่ระบุไว้สำหรับ (ที่จริงแล้วมันอาจจะเทียบเท่า แต่เพียงเพราะตัวอย่างเช่น/usr/include/mypath/myfileสามารถเรียกว่า/usr/include/./mypath/myfile- อย่างน้อยในระบบที่เหมือนยูนิกซ์)
Keith Thompson

1
@ Keith Thompson: ถูกต้องฉันกำลังคิดถึงกล่อง Linux ของฉัน เห็นได้ชัดว่ามันอาจแตกต่างกัน แม้ว่าในทางปฏิบัติแล้ว Windows ในฐานะระบบปฏิบัติการที่ไม่ใช่ Posix ก็ยังมี interprete / เป็นตัวคั่นพา ธ และ. / ก็มีอยู่เช่นกัน
Stefan Steiger

1
อ็อพชัน-L dirpathจากนั้นเพิ่มdirpathให้กับdefaultincludepaths, แทนที่จะให้ความหมายอื่นกับ.(ตามที่อ้างถึงด้านบน) สิ่งนี้มีผลที่คาดว่าทั้งคู่#include "..."และ#include <...>ค้นหาในdirpath
Protongun

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

39

การ<file>รวมบอกให้ตัวประมวลผลล่วงหน้าค้นหาใน-Iไดเร็กทอรีและในไดเร็กทอรีที่กำหนดไว้ล่วงหน้าก่อนจากนั้นในไดเร็กทอรีของไฟล์. c การ"file"รวมจะบอกให้ตัวประมวลผลล่วงหน้าค้นหาไดเร็กทอรีของไฟล์ต้นฉบับก่อนจากนั้นจึงย้อนกลับ-Iและกำหนดไว้ล่วงหน้า ทุกสถานที่มีการค้นหาต่อไปเพียงเพื่อการค้นหาที่แตกต่างกัน

มาตรฐาน 2011 ส่วนใหญ่กล่าวถึงการรวมไฟล์ใน "16.2 แหล่งรวมไฟล์"

2 preprocessing สั่งของแบบฟอร์ม

# include <h-char-sequence> new-line

ค้นหาลำดับของตำแหน่งที่กำหนดการนำไปใช้งานเพื่อค้นหาส่วนหัวที่ระบุโดยไม่ซ้ำกันตามลำดับที่ระบุระหว่างตัวคั่น <และ> และทำให้การเปลี่ยนคำสั่งนั้นโดยเนื้อหาทั้งหมดของส่วนหัว วิธีระบุสถานที่หรือส่วนหัวที่ระบุนั้นมีการนำมาใช้

3 คำสั่ง preprocessing ของแบบฟอร์ม

# include "q-char-sequence" new-line

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

# include <h-char-sequence> new-line

ด้วยลำดับที่มีเหมือนกัน (รวมถึง> อักขระถ้ามี) จากคำสั่งดั้งเดิม

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


4
คุณสามารถให้การอ้างอิงถึงมาตรฐาน C -Iที่ระบุในธุรกิจนี้ได้หรือไม่
juanchopanza

1
-Iผมเห็นไม่มีการอ้างอิงถึง
juanchopanza

2
นั่นคือส่วน "กำหนดการนำไปปฏิบัติ"

27

#include <file.h>บอกคอมไพเลอร์เพื่อค้นหาส่วนหัวในไดเรกทอรี " file.hinclude " ของมันเช่นสำหรับ MinGW คอมไพเลอร์จะค้นหาใน C: \ MinGW \ include \ หรือติดตั้งที่ใดที่คอมไพเลอร์ของคุณ

#include "file"บอกคอมไพเลอร์ที่จะค้นหาไดเรกทอรีปัจจุบัน (IE ไดเรกทอรีที่อยู่ของแหล่งที่มาของไฟล์) fileสำหรับ

คุณสามารถใช้-Iธง GCC จะบอกว่าเมื่อมันพบข้อ ได้แก่ -Iมีวงเล็บมุมก็ยังควรค้นหาส่วนหัวในไดเรกทอรีหลัง GCC จะปฏิบัติต่อไดเรกทอรีหลังจากธงราวกับว่ามันเป็นincludesไดเรกทอรี

ตัวอย่างเช่นหากคุณมีไฟล์ชื่อmyheader.hในไดเรกทอรีของคุณเองคุณสามารถพูดได้ว่า#include <myheader.h>คุณเรียกว่า GCC พร้อมกับตั้งค่าสถานะ-I .(ระบุว่าควรจะค้นหาไฟล์นั้นรวมอยู่ในไดเรกทอรีปัจจุบัน)

โดยไม่ต้อง-Iธงคุณจะต้องใช้#include "myheader.h"ในการรวมไฟล์หรือย้ายmyheader.hไปยังincludeไดเรกทอรีของคอมไพเลอร์ของคุณ


22

ตามมาตรฐาน - ใช่พวกเขาแตกต่างกัน:

  • คำสั่ง preprocessing ของแบบฟอร์ม

    #include <h-char-sequence> new-line

    ค้นหาลำดับของสถานที่ที่กำหนดให้มีการนำไปใช้งานสำหรับส่วนหัวที่ระบุโดยไม่ซ้ำกันตามลำดับที่ระบุระหว่าง<และ>ตัวคั่นและทำให้การเปลี่ยนคำสั่งนั้นโดยเนื้อหาทั้งหมดของส่วนหัว วิธีระบุสถานที่หรือส่วนหัวที่ระบุนั้นมีการนำมาใช้

  • คำสั่ง preprocessing ของแบบฟอร์ม

    #include "q-char-sequence" new-line

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

    #include <h-char-sequence> new-line

    ด้วยลำดับที่มีอยู่เหมือนกัน (รวมถึง>อักขระถ้ามี) จากคำสั่งดั้งเดิม

  • คำสั่ง preprocessing ของแบบฟอร์ม

    #include pp-tokens new-line

    (ที่ไม่ตรงกับหนึ่งในสองรูปแบบก่อนหน้านี้) ได้รับอนุญาต โทเค็นการประมวลผลล่วงหน้าหลังจากincludeอยู่ในคำสั่งจะถูกประมวลผลเช่นเดียวกับในข้อความปกติ (แต่ละตัวระบุที่กำหนดในปัจจุบันเป็นชื่อแมโครจะถูกแทนที่ด้วยรายการการแทนที่โทเค็นการประมวลผลล่วงหน้า) คำสั่งที่เกิดขึ้นหลังจากการแทนที่ทั้งหมดจะต้องตรงกับหนึ่งในสองรูปแบบก่อนหน้านี้ วิธีที่ลำดับของโทเค็นการประมวลผลล่วงหน้าระหว่าง a <และ>โทเค็นการประมวลผลล่วงหน้าหรือคู่ของ"อักขระจะรวมกันเป็นชื่อส่วนหัวเดียวโทเค็น preprocessing โทเค็นการดำเนินงานที่กำหนดไว้

คำนิยาม:

  • h-char: สมาชิกของชุดอักขระต้นฉบับยกเว้นอักขระบรรทัดใหม่และ >

  • q-char: สมาชิกของชุดอักขระต้นฉบับยกเว้นอักขระบรรทัดใหม่และ "

โปรดทราบว่ามาตรฐานไม่ได้บอกความสัมพันธ์ใด ๆ ระหว่างมารยาทที่กำหนดโดยการนำไปปฏิบัติ รูปแบบแรกจะค้นหาในวิธีที่กำหนดโดยการนำไปใช้งานหนึ่งและอีกวิธีหนึ่งในวิธีกำหนดใช้งาน มาตรฐานยังระบุด้วยว่าจะต้องมีไฟล์รวมอยู่ด้วย (เช่น<stdio.h>)

คุณต้องอ่านคู่มืออย่างเป็นทางการสำหรับคอมไพเลอร์ของคุณ แต่ตามปกติ (ตามธรรมเนียม) #include "..."รูปแบบจะค้นหาไดเรกทอรีของไฟล์ที่#includeพบก่อนจากนั้นไดเรกทอรีที่#include <...>ฟอร์มนั้นค้นหา (พา ธ รวมเช่นส่วนหัวของระบบเช่นส่วนหัวของระบบ )


2
นี่เป็นเพียงข้อความเดียวกับคำตอบของ piCookie เมื่อเจ็ดปีก่อน
Kyle Strand

5
@KyleStrand นั่นเป็นเพราะข้อความเดียวกันเป็นข้อความของส่วนที่เกี่ยวข้องในมาตรฐาน - ข้อความนั้นควรจะเหมือนกัน คำตอบที่แท้จริงไม่ใช่ข้อความเดียวกันและค่อนข้างแตกต่าง - ในขณะที่ฉันยังจำได้ว่ามันจะถูกเขียนในเอกสารสำหรับการดำเนินการฉันยังทราบว่ายังมีวิธีดั้งเดิมที่ตีความเหล่านี้ (ส่วนใหญ่หรือทั้งหมดคอมไพเลอร์ที่ฉันเคารพ) .
skyking

2
IMO นี่เป็นคำตอบที่ดีที่สุดเพราะครอบคลุมทั้งสิ่งที่มาตรฐานพูดและสิ่งที่คอมไพเลอร์ส่วนใหญ่ทำ
plugwash

17

ขอบคุณสำหรับคำตอบที่ดี Adam Stelmaszczyk และ piCookie และ aib

เช่นเดียวกับโปรแกรมเมอร์หลายคนฉันใช้แบบแผนทางการของการใช้"myApp.hpp"แบบฟอร์มสำหรับไฟล์เฉพาะแอปพลิเคชันและ<libHeader.hpp>แบบฟอร์มสำหรับไฟล์ไลบรารีและระบบคอมไพเลอร์เช่นไฟล์ที่ระบุใน/IและINCLUDEตัวแปรสภาพแวดล้อมสำหรับปีที่คิดว่าเป็นมาตรฐาน

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

#include "../../MyProgDir/SourceDir1/someFile.hpp"

MSVS เวอร์ชันเก่าต้องการแบ็กสแลชคู่ (\\) แต่ตอนนี้ไม่จำเป็น ฉันไม่รู้ว่ามันเปลี่ยนไปเมื่อไหร่ เพียงใช้เครื่องหมายทับซ้ายเพื่อเข้ากันได้กับ 'ระวัง (Windows จะยอมรับ)

หากคุณกำลังจริงๆกังวลเกี่ยวกับเรื่องนี้ใช้"./myHeader.h"สำหรับรวมไฟล์ในไดเรกทอรีเดียวกันกับรหัสที่มา (ปัจจุบันโครงการมีขนาดใหญ่มากของฉันมีบางส่วนที่ซ้ำกันรวมถึงชื่อไฟล์เกลื่อนกลาด - จริงๆปัญหาการจัดการการตั้งค่า)

นี่คือคำอธิบายของ MSDN ที่คัดลอกมาที่นี่เพื่อความสะดวกของคุณ)

แบบฟอร์มที่ยกมา

ตัวประมวลผลล่วงหน้าค้นหาไฟล์ include ตามลำดับนี้:

  1. ในไดเรกทอรีเดียวกันกับไฟล์ที่มีคำสั่ง #include
  2. ในไดเรกทอรีของไฟล์ที่เปิดอยู่ในปัจจุบันเรียงตามลำดับย้อนกลับที่
    เปิดอยู่ การค้นหาเริ่มต้นในไดเรกทอรีของไฟล์ parent รวมถึง
    ขึ้นด้านบนผ่านไดเร็กทอรีของไฟล์ include grandparent ใด ๆ
  3. ตามเส้นทางที่ระบุโดย/Iตัวเลือกคอมไพเลอร์แต่ละตัว
  4. ตามเส้นทางที่ระบุโดยINCLUDEตัวแปรสภาพแวดล้อม

รูปแบบวงเล็บมุม

ตัวประมวลผลล่วงหน้าค้นหาไฟล์ include ตามลำดับนี้:

  1. ตามเส้นทางที่ระบุโดย/Iตัวเลือกคอมไพเลอร์แต่ละตัว
  2. เมื่อรวบรวมเกิดขึ้นในบรรทัดคำสั่งพร้อมเส้นทางที่ระบุโดยINCLUDEตัวแปรสภาพแวดล้อม

16

อย่างน้อยสำหรับรุ่น GCC <= 3.0 รูปแบบวงเล็บมุมจะไม่สร้างการพึ่งพาระหว่างไฟล์ที่รวมและไฟล์ที่รวม

ดังนั้นหากคุณต้องการสร้างกฎการพึ่งพา (ใช้ตัวเลือก GCC -M สำหรับตัวอย่าง) คุณต้องใช้แบบฟอร์มที่ยกมาสำหรับไฟล์ที่ควรจะรวมอยู่ในโครงสร้างการพึ่งพา

(ดูhttp://gcc.gnu.org/onlinedocs/cpp/Invocation.html )


1
ใช่ - มีหลายวิธีในการสร้างการพึ่งพา นั่นเป็นหนึ่งในนั้น แต่ไม่ใช่คนเดียว
Pryftan

15

สำหรับ#include ""คอมไพเลอร์โดยปกติแล้วจะค้นหาโฟลเดอร์ของไฟล์ที่มีไฟล์นั้นซึ่งรวมถึงโฟลเดอร์อื่นแล้ว สำหรับ#include <>คอมไพเลอร์ไม่ได้ค้นหาโฟลเดอร์ของไฟล์ปัจจุบัน


1
ไม่แน่ใจว่าทำไมคนไม่เห็นด้วย
Maxim Egorushkin

ฉันสงสัยว่าเป็นเพราะคนส่วนใหญ่รวบรวมเฉพาะไฟล์ใน CWD ของพวกเขา หากคุณอยู่ในไดเรกทอรี foo และคุณกำลังรวบรวม foo / unittest / bar.c และมี bar.h อยู่ด้วย "bar.h" จะทำงานและ <bar.h> ไม่ทำงาน

1
@ คนมากที่สุดไม่เห็นด้วยเพราะพฤติกรรมที่คุณอธิบายนั้นไม่ได้มาตรฐาน C.
osvein

2
@Spookbuster Right มาตรฐานบอกทั้งคู่<filename>และ"filename"ค้นหาสถานที่ที่กำหนดการนำไปใช้งาน
Maxim Egorushkin

14

เมื่อคุณใช้ #include <filename> ตัวประมวลผลล่วงหน้าจะค้นหาไฟล์ในไดเรกทอรีของไฟล์ส่วนหัว C \ C ++ (stdio.h \ cstdio, สตริง, เวกเตอร์ ฯลฯ ) แต่เมื่อคุณใช้ #include "filename": ก่อนตัวประมวลผลล่วงหน้าจะค้นหาไฟล์ในไดเรกทอรีปัจจุบันและหากไม่อยู่ที่นี่เขาจะค้นหาในไดเรกทอรีของไฟล์ส่วนหัว C \ C ++


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

@Ispectable โปรดอธิบายว่าทำไมมันจึงไม่เกี่ยวข้องกับไฟล์เลย
Behrooz Karjoo

11

#include ที่มีเครื่องหมายวงเล็บมุมจะค้นหา "รายชื่อสถานที่ที่ขึ้นอยู่กับการนำไปใช้งาน" (ซึ่งเป็นวิธีที่ซับซ้อนมากในการพูดว่า "ส่วนหัวของระบบ") เพื่อรวมไฟล์

#include ที่มีเครื่องหมายคำพูดจะค้นหาไฟล์ (และ "ในลักษณะที่ขึ้นกับการนำไปใช้งาน", bleh) ซึ่งหมายความว่าในภาษาอังกฤษปกติมันจะพยายามใช้พา ธ / ชื่อไฟล์ที่คุณโยนไปและจะไม่เพิ่มเส้นทางของระบบหรือยุ่งเกี่ยวกับมันเป็นอย่างอื่น

นอกจากนี้หาก #include "" ล้มเหลวจะถูกอ่านอีกครั้งเป็น #include <> ตามมาตรฐาน

เอกสาร GCCมีคำอธิบาย (คอมไพเลอร์ที่เฉพาะเจาะจง) ซึ่งแม้ว่าจะเป็นที่เฉพาะเจาะจงกับ GCC และไม่ได้มาตรฐานเป็นที่ง่ายมากที่จะเข้าใจกว่าการพูดคุยทนายความสไตล์ของมาตรฐาน ISO


อย่างไรก็ตามการใช้วงเล็บเหลี่ยมหรือคำพูดไม่ได้ส่งผลกระทบต่อวิธีการรวมไฟล์มันเป็นสิ่งเดียวกัน: preprocessor ที่สำคัญสร้างไฟล์ต้นฉบับขนาดใหญ่โดย copy'n'pasting รหัสจากไฟล์รวมถึงไฟล์ต้นฉบับก่อนที่จะให้ ไปยังคอมไพเลอร์ (ตัวประมวลผลล่วงหน้าทำอย่างอื่นเช่น #define sustitution การประเมิน #if ฯลฯ แต่การประมวลผล #include นั้นง่ายมาก)
Loghorn

แล้วความขัดแย้งล่ะ เช่นบอกว่าฉันมีzlib.hในพา ธ การค้นหา 'ผู้ใช้' ของฉันและมีเวอร์ชันอื่นอยู่ในพา ธ การค้นหาระบบดังนั้นจะ#include <zlib.h>รวมเวอร์ชันระบบและ#include "zlib.h"รวมเอาเองด้วยหรือไม่
the_mandrill


ขอขอบคุณสำหรับการยอมรับว่าทั้งมาตรฐานและอนุสัญญาการดำเนินงานตามปกติมีความเกี่ยวข้องกันที่นี่ไม่ใช่แค่ระบุว่าไม่สามารถรู้ได้เพราะไม่ได้ระบุไว้โดยมาตรฐาน
Kyle Strand

10
#include "filename" // User defined header
#include <filename> // Standard library header.

ตัวอย่าง:

ชื่อไฟล์ที่นี่คือSeller.h:

#ifndef SELLER_H     // Header guard
#define SELLER_H     // Header guard

#include <string>
#include <iostream>
#include <iomanip>

class Seller
{
    private:
        char name[31];
        double sales_total;

    public:
        Seller();
        Seller(char[], double);
        char*getName();

#endif

ในการปรับใช้คลาส (ตัวอย่างเช่นSeller.cppและในไฟล์อื่น ๆ ที่จะใช้ไฟล์Seller.h) ส่วนหัวที่กำหนดโดยผู้ใช้ควรรวมไว้ในตอนนี้ดังนี้:

#include "Seller.h"

10
  • #include <> ใช้สำหรับไฟล์ส่วนหัวที่กำหนดไว้ล่วงหน้า

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

#include <iostream>
  • #include " " สำหรับไฟล์ส่วนหัวที่โปรแกรมเมอร์กำหนด

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

#include "myfile.h"

2
ไม่มีส่วนเกี่ยวข้องกับไฟล์ส่วนหัวที่กำหนดไว้ล่วงหน้าเลย มันจะทำอย่างไรกับสถานที่เพื่อค้นหา
C Johnson

9

คำตอบมากมายที่นี่ให้ความสำคัญกับเส้นทางที่คอมไพเลอร์จะค้นหาเพื่อค้นหาไฟล์ ในขณะที่สิ่งนี้เป็นสิ่งที่คอมไพเลอร์ส่วนใหญ่ทำคอมไพเลอร์ที่ได้รับอนุญาตจะได้รับการ preprogrammed กับเอฟเฟกต์ของส่วนหัวมาตรฐานและปฏิบัติต่อพูด#include <list>เป็นสวิตช์

นี่ไม่ใช่สมมุติฐานอย่างหมดจด มีคอมไพเลอร์อย่างน้อยหนึ่งตัวที่ทำงานในลักษณะนั้น แนะนำให้ใช้#include <xxx>กับส่วนหัวมาตรฐานเท่านั้น


9
#include <abc.h>

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

#include "xyz.h"

จะบอกคอมไพเลอร์ให้รวมไฟล์ส่วนหัวที่ผู้ใช้กำหนด ดังนั้นคอมไพเลอร์จะตรวจสอบไฟล์ส่วนหัวเหล่านี้ในโฟลเดอร์ปัจจุบันหรือ-Iโฟลเดอร์ที่กำหนดไว้


7

ใน C ++ ให้รวมไฟล์ด้วยสองวิธี:

อันแรกคือ #include ซึ่งบอกให้ preprocessor ค้นหาไฟล์ในตำแหน่งเริ่มต้นที่กำหนดไว้ล่วงหน้า ตำแหน่งนี้มักเป็นตัวแปรสภาพแวดล้อม INCLUDE ที่แสดงพา ธ เพื่อรวมไฟล์

และประเภทที่สองคือ #include "filename" ซึ่งบอกให้ preprocessor ค้นหาไฟล์ในไดเรกทอรีปัจจุบันก่อนจากนั้นค้นหาในตำแหน่งที่ผู้ใช้ตั้งค่าไว้ล่วงหน้า


7

แบบฟอร์ม 1 - #include <xxx>

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

แบบฟอร์ม 2 - #include "xxx"

สิ่งนี้ค้นหาการมีอยู่ของไฟล์ส่วนหัวในไดเรกทอรีปัจจุบันจากที่มีการเรียกใช้คำสั่ง


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

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


โดยทั่วไปรูปแบบ "xxx" นั้นไม่ได้มีอะไรนอกจากค้นหาในไดเรกทอรีปัจจุบัน หากไม่พบแบบฟอร์มที่ล้มลง


3
หากคุณตัดสินใจที่จะตอบคำถามที่เก่ากว่าซึ่งมีคำตอบที่ถูกต้องและถูกต้องแล้วการเพิ่มคำตอบใหม่ในช่วงปลายวันอาจไม่ได้รับเครดิตใด ๆ หากคุณมีข้อมูลใหม่ที่โดดเด่นหรือคุณมั่นใจว่าคำตอบอื่น ๆ นั้นผิดทั้งหมดโดยเพิ่มคำตอบใหม่ แต่ 'อีกคำตอบ' ให้ข้อมูลพื้นฐานเดียวกันเป็นเวลานานหลังจากที่คำถามถูกถามมักจะ ' คุณไม่ได้รับเครดิตมาก
Jonathan Leffler

1
@ Jonathan Leffler คุณช่วยชี้ให้ฉันเห็นคำตอบที่ "เป็นที่ยอมรับ" ที่คุณรู้สึกว่ากระชับและแม่นยำเหมือนคำตอบของ Darshan หรือไม่?
personal_cloud

1
คำอธิบายของ#include "header.h"แบบฟอร์มไม่ถูกต้อง @personal_cloud ฉันพิจารณาคำตอบโดยpiCookieและYann Droneaudให้มีความเกี่ยวข้องมากที่สุดเนื่องจากพวกเขาระบุว่าข้อมูลมาจากไหน ฉันไม่พบคำตอบที่ได้รับคะแนนสูงสุดว่าเป็นที่น่าพอใจอย่างแท้จริง
Jonathan Leffler

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

6

#include <filename>จะใช้เมื่อไฟล์ระบบจะถูกเรียกว่า นั่นคือส่วนหัวของแฟ้มที่สามารถพบได้ในสถานที่เริ่มต้นของระบบเช่นหรือ/usr/include /usr/local/includeสำหรับไฟล์ของคุณที่จะต้องรวมอยู่ในโปรแกรมอื่นคุณจะต้องใช้#include "filename"ไวยากรณ์


6

การค้นหา "<filename>" ในตำแหน่งไลบรารีมาตรฐาน C

ในขณะที่ "ชื่อไฟล์" ค้นหาในไดเรกทอรีปัจจุบันเช่นกัน

ตามหลักการแล้วคุณจะใช้ <... > สำหรับไลบรารี C มาตรฐานและ "... " สำหรับไลบรารีที่คุณเขียนและมีอยู่ในไดเรกทอรีปัจจุบัน


4
ข้อมูลใหม่ใดที่เพิ่มคำตอบนี้ให้กับคนอื่น ๆ ?
Daniel Langr

5

กฎทั่วไปง่ายๆคือการใช้วงเล็บมุมเพื่อรวมไฟล์ส่วนหัวที่มาพร้อมกับคอมไพเลอร์ ใช้เครื่องหมายคำพูดคู่เพื่อรวมไฟล์ส่วนหัวอื่น ๆ คอมไพเลอร์ส่วนใหญ่ทำแบบนี้

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


4
#include <filename>

ถูกใช้เมื่อคุณต้องการใช้ไฟล์ส่วนหัวของระบบ C / C ++ หรือไลบรารีคอมไพเลอร์ ไลบรารีเหล่านี้สามารถ stdio.h, string.h, math.h เป็นต้น

#include "path-to-file/filename"

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

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวประมวลผลล่วงหน้าและส่วนหัว อ่านC - ตัวประมวลผลล่วงหน้า


3

#include <filename>

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

#include "filename"

  • คอมไพเลอร์บอกให้ค้นหาไฟล์ส่วนหัวที่โปรแกรมทำงานอยู่ ถ้ามันล้มเหลวมันจะทำตัวเหมือน#include <filename>และค้นหาไฟล์ส่วนหัวที่ซึ่งเป็นที่เก็บไฟล์ส่วนหัวของระบบ
  • วิธีการนี้มักจะใช้เพื่อระบุไฟล์ส่วนหัวที่ผู้ใช้กำหนด (ไฟล์ส่วนหัวที่สร้างโดยผู้ใช้) ที่นั่นอย่าใช้สิ่งนี้หากคุณต้องการเรียก#include <filename>ไลบรารี่มาตรฐานเพราะใช้เวลาในการรวบรวมมากกว่า

2

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

cpp -v /dev/null -o /dev/null

Apple LLVM เวอร์ชั่น 10.0.0 (เสียงดัง -1000.10.44.2)
เป้าหมาย: x86_64-apple-darwin18.0.0
รุ่นเธรด: posix ติดตั้ง : ไลบรารี / นักพัฒนา / CommandLineTools / usr / bin
"/ Library / Developer / CommandLineTools / usr / bin / clang" -cc1 -triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-use -Werror = คัดค้าน-objc-isa-use ปิดการใช้งาน -lvm-verifier -discard-value- ชื่อ -main-file-name null -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -fno-เข้มงวด-return -masm-verbose - munwind ตาราง -target-cpu penryn -dwarf-column-info -debugger-tuning = lldb -target-linker-version 409.12 -v -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/10.0 isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -I / usr / local / รวม -fdebug-compilation-dir / ผู้ใช้ / hogstrom -ferror-limit 19 -fmessage-length 80 -stack-protector-1 -fencode-Extended-block-signature -fobjc-runtime = macosx-10.140 -fmax-type-align = 16 -fdiagnostics-show-option -fcolor-Diagnostics -traditional-cpp -o - -xc / dev / null
clang -cc1 รุ่น 10.0.0 (clang-1000.10.44.2) เป้าหมายเริ่มต้น x86_64-apple-darwin18.0.0 โดยไม่สนใจไดเรกทอรีที่ไม่มีอยู่ "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include" ไดเรกทอรี "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"
#include "... " การค้นหาเริ่มต้นที่นี่:
#include <... > การค้นหาเริ่มต้นที่นี่:
/ usr / local / include
/ ห้องสมุด / Developer / CommandLineTools / usr / lib / เสียงดังกราว / 10.0.0 / include
/ Library / Developer / CommandLineTools / usr / รวม
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include
/ Library / Developer / CommandLineTools / SDKs / MacOSX10.14.sdk / ระบบ / ไลบรารี / กรอบงาน (ไดเรกทอรีกรอบ)
สิ้นสุดรายการค้นหา


1
#include <file> 

รวมไฟล์ที่ไดเรกทอรีรวมเป็นค่าเริ่มต้น

#include "file" 

รวมถึงไฟล์ในไดเรกทอรีปัจจุบันที่มันถูกรวบรวม


-2

มีอยู่สองวิธีในการเขียนคำสั่ง #include นี่คือ:

#include"filename"
#include<filename>

ความหมายของแต่ละรูปแบบคือ

#include"mylib.h"

คำสั่งนี้จะค้นหาไฟล์mylib.hในไดเรกทอรีปัจจุบันเช่นเดียวกับรายการไดเรกทอรีที่ระบุดังกล่าว n เส้นทางการค้นหารวมที่อาจได้รับการตั้งค่า

#include<mylib.h>

คำสั่งนี้จะค้นหาไฟล์mylib.hในรายการไดเรกทอรีที่ระบุเท่านั้น

พา ธ การค้นหา include คืออะไรนอกจากรายการไดเร็กทอรีที่จะค้นหาไฟล์ที่ถูกรวมคอมไพเลอร์ C ที่แตกต่างกันให้คุณตั้งค่าพา ธ การค้นหาในลักษณะที่แตกต่างกัน


1
หากคุณตัดสินใจที่จะตอบคำถามที่เก่ากว่าซึ่งมีคำตอบที่ถูกต้องและถูกต้องแล้วการเพิ่มคำตอบใหม่ในช่วงปลายวันอาจไม่ได้รับเครดิตใด ๆ หากคุณมีข้อมูลใหม่ที่โดดเด่นหรือคุณมั่นใจว่าคำตอบอื่น ๆ นั้นผิดทั้งหมดโดยเพิ่มคำตอบใหม่ แต่ 'อีกคำตอบ' ให้ข้อมูลพื้นฐานเดียวกันเป็นเวลานานหลังจากที่คำถามถูกถามมักจะ ' คุณไม่ได้รับเครดิตมาก
Jonathan Leffler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.