Trong ngôn ngữ lập trình C và C ++, sự khác biệt giữa sử dụng dấu ngoặc góc và sử dụng dấu ngoặc kép trong include
câu lệnh, như sau là gì?
#include <filename>
#include "filename"
Trong ngôn ngữ lập trình C và C ++, sự khác biệt giữa sử dụng dấu ngoặc góc và sử dụng dấu ngoặc kép trong include
câu lệnh, như sau là gì?
#include <filename>
#include "filename"
Câu trả lời:
Trong thực tế, sự khác biệt nằm ở vị trí mà bộ tiền xử lý tìm kiếm tệp được bao gồm.
Đối với #include <filename>
các tìm kiếm tiền xử lý theo cách phụ thuộc triển khai, thông thường trong các thư mục tìm kiếm được chỉ định trước bởi trình biên dịch / IDE. Phương pháp này thường được sử dụng để bao gồm các tệp tiêu đề thư viện tiêu chuẩn.
Đối với #include "filename"
các bộ xử lý tiền tìm kiếm trước tiên trong cùng thư mục với tệp chứa lệnh, sau đó theo đường dẫn tìm kiếm được sử dụng cho #include <filename>
biểu mẫu. Phương pháp này thường được sử dụng để bao gồm các tệp tiêu đề do lập trình viên xác định.
Một mô tả đầy đủ hơn có sẵn trong tài liệu GCC trên các đường dẫn tìm kiếm .
#include <...>
sử dụng gói được cài đặt trên hệ thống và #include "..."
sử dụng phiên bản kho lưu trữ gần đó. Tôi có thể có những người ngược. Dù bằng cách nào, bộ bảo vệ bao gồm trong tiêu đề được đóng gói có tiền tố gạch dưới. (Nó có thể là một quy ước cho các gói hoặc có thể là một cách cố tình ngăn chặn việc trộn lẫn cả hai, mặc dù vòng loại phiên bản sẽ có ý nghĩa hơn đối với tôi.)
Cách duy nhất để biết là đọc tài liệu triển khai của bạn.
Trong tiêu chuẩn C , mục 6.10.2, đoạn 2 đến 4 trạng thái:
Một chỉ thị tiền xử lý của mẫu
#include <h-char-sequence> new-line
tìm kiếm một chuỗi các vị trí được xác định thực hiện cho một tiêu đề được xác định duy nhất bởi trình tự được chỉ định giữa
<
và các>
dấu phân cách và gây ra sự thay thế của lệnh đó bởi toàn bộ nội dung của tiêu đề . Làm thế nào các địa điểm được chỉ định hoặc tiêu đề được xác định là xác định thực hiện.Một chỉ thị tiền xử lý của mẫu
#include "q-char-sequence" new-line
gây ra sự thay thế của lệnh đó bởi toàn bộ nội dung của tệp nguồn được xác định bởi trình tự được chỉ định giữa các
"
dấu phân cách. Tệp nguồn được đặt tên được tìm kiếm theo cách xác định thực hiện. Nếu tìm kiếm này không được hỗ trợ hoặc nếu tìm kiếm thất bại, lệnh sẽ được xử lý lại như thể nó đã đọc#include <h-char-sequence> new-line
với chuỗi chứa giống hệt nhau (bao gồm các
>
ký tự, nếu có) từ chỉ thị ban đầu.Một chỉ thị tiền xử lý của mẫu
#include pp-tokens new-line
(không phù hợp với một trong hai hình thức trước đó) được cho phép. Các mã thông báo tiền xử lý sau
include
trong lệnh được xử lý giống như trong văn bản thông thường. (Mỗi mã định danh hiện được xác định là tên macro được thay thế bằng danh sách mã thông báo tiền xử lý thay thế.) Lệnh được tạo sau tất cả các thay thế sẽ khớp với một trong hai dạng trước đó. Phương pháp mà theo đó một chuỗi các tiền xử lý tokens giữa<
và một>
cặp thẻ tiền xử lý hoặc một cặp"
nhân vật được kết hợp thành một tên tiêu đề đơn tiền xử lý mã thông báo là thực hiện xác định.Định nghĩa:
h-char: bất kỳ thành viên nào của bộ ký tự nguồn trừ ký tự dòng mới và
>
q-char: bất kỳ thành viên nào của bộ ký tự nguồn trừ ký tự dòng mới và
"
Chuỗi các ký tự giữa <và> duy nhất đề cập đến một tiêu đề, không nhất thiết phải là một tệp. Việc triển khai là khá nhiều miễn phí để sử dụng chuỗi ký tự như họ muốn. (Tuy nhiên, hầu hết, chỉ coi nó như một tên tệp và thực hiện tìm kiếm trong đường dẫn bao gồm , như trạng thái bài viết khác.)
Nếu #include "file"
biểu mẫu được sử dụng, trước tiên, việc triển khai sẽ tìm một tệp có tên đã cho, nếu được hỗ trợ. Nếu không (được hỗ trợ) hoặc nếu tìm kiếm thất bại, việc triển khai sẽ hoạt động như thể #include <file>
hình thức ( ) khác đã được sử dụng.
Ngoài ra, một hình thức thứ ba tồn tại và được sử dụng khi #include
chỉ thị không khớp với một trong các hình thức trên. Trong biểu mẫu này, một số tiền xử lý cơ bản (như mở rộng macro) được thực hiện trên "toán hạng" của lệnh #include
và kết quả dự kiến sẽ khớp với một trong hai dạng khác.
<
và >
làm khóa để lập chỉ mục vào thư viện.
Một số câu trả lời hay ở đây làm tham chiếu đến tiêu chuẩn C nhưng quên tiêu chuẩn POSIX, đặc biệt là hành vi cụ thể của lệnh c99 (ví dụ: trình biên dịch C) .
Theo Thông số kỹ thuật cơ sở nhóm mở số 7 ,
-Tôi thư mục
Thay đổi thuật toán tìm kiếm các tiêu đề có tên không phải là tên đường dẫn tuyệt đối để tìm trong thư mục được đặt tên theo tên đường dẫn thư mục trước khi tìm ở các vị trí thông thường. Do đó, các tiêu đề có tên được đặt trong dấu ngoặc kép ("") sẽ được tìm kiếm đầu tiên trong thư mục của tệp có dòng #include , sau đó trong các thư mục có tên trong tùy chọn -I và cuối cùng ở các vị trí thông thường. Đối với các tiêu đề có tên được đặt trong dấu ngoặc nhọn ("<>"), tiêu đề chỉ được tìm kiếm trong các thư mục có tên trong tùy chọn -I và sau đó ở các vị trí thông thường. Các thư mục có tên trong tùy chọn -I sẽ được tìm kiếm theo thứ tự được chỉ định.Lệnh gọi c99 .
Vì vậy, trong môi trường tuân thủ POSIX, với trình biên dịch C tuân thủ POSIX, #include "file.h"
có khả năng sẽ tìm kiếm ./file.h
trước, .
thư mục chứa tệp có #include
câu lệnh ở đâu, trong khi #include <file.h>
, có khả năng sẽ tìm kiếm /usr/include/file.h
trước, /usr/include
hệ thống của bạn được xác định ở đâu địa điểm thông thường cho các tiêu đề (dường như không được xác định bởi POSIX).
c99
- đó là tên POSIX cho trình biên dịch C. (Tiêu chuẩn POSIX 2008 khó có thể tham khảo C11; bản cập nhật 2013 cho POSIX 2008 không thay đổi tiêu chuẩn C mà nó đề cập đến.)
-L
.
Tài liệu của GCC cho biết như sau về sự khác biệt giữa hai:
Cả hai tệp tiêu đề người dùng và hệ thống đều được bao gồm bằng cách sử dụng chỉ thị tiền xử lý
‘#include’
. Nó có hai biến thể:
#include <file>
Biến thể này được sử dụng cho các tập tin tiêu đề hệ thống. Nó tìm kiếm một tập tin có tên tập tin trong một danh sách tiêu chuẩn của các thư mục hệ thống. Bạn có thể thêm các thư mục vào danh sách này với
-I
tùy chọn (xem Invocation ).
#include "file"
Biến thể này được sử dụng cho các tệp tiêu đề của chương trình của riêng bạn. Nó tìm kiếm một tệp có tên tệp đầu tiên trong thư mục chứa tệp hiện tại, sau đó trong các thư mục trích dẫn và sau đó các thư mục tương tự được sử dụng cho
<file>
. Bạn có thể thêm các thư mục vào danh sách các thư mục trích dẫn với-iquote
tùy chọn. Đối số của‘#include’
, cho dù được phân cách bằng dấu ngoặc kép hoặc dấu ngoặc nhọn, hoạt động như một hằng chuỗi trong đó các nhận xét không được nhận dạng và tên macro không được mở rộng. Do đó,#include <x/*y>
chỉ định bao gồm một tệp tiêu đề hệ thống có tênx/*y
.Tuy nhiên, nếu dấu gạch chéo ngược xảy ra trong tệp, chúng được coi là ký tự văn bản thông thường, không thoát ký tự. Không có chuỗi thoát ký tự nào phù hợp với hằng chuỗi trong C được xử lý. Do đó,
#include "x\n\\y"
chỉ định một tên tệp chứa ba dấu gạch chéo ngược. (Một số hệ thống diễn giải '\' như một dấu tách tên đường dẫn. Tất cả các hệ thống này cũng diễn giải‘/’
theo cùng một cách. Nó chỉ dễ sử dụng nhất‘/’
.)Đó là một lỗi nếu có bất cứ điều gì (ngoài ý kiến) trên dòng sau tên tệp.
Nó làm:
"mypath/myfile" is short for ./mypath/myfile
với .
hoặc là thư mục của tệp chứa tệp #include
này và / hoặc thư mục làm việc hiện tại của trình biên dịch và / hoặcdefault_include_paths
và
<mypath/myfile> is short for <defaultincludepaths>/mypath/myfile
Nếu ./
là trong <default_include_paths>
, thì nó không tạo ra sự khác biệt.
Nếu mypath/myfile
trong một thư mục bao gồm khác, hành vi không được xác định.
#include "mypath/myfile"
không tương đương với #include "./mypath/myfile"
. Như câu trả lời của piCookie nói, dấu ngoặc kép cho trình biên dịch tìm kiếm theo cách xác định thực hiện - bao gồm tìm kiếm ở những nơi được chỉ định cho #include <...>
. (Trên thực tế, nó có thể tương đương, nhưng chỉ vì, ví dụ, /usr/include/mypath/myfile
có thể được gọi là /usr/include/./mypath/myfile
- ít nhất là trên các hệ thống giống Unix.)
defaultincludepaths
, trái ngược với việc mang một ý nghĩa khác cho .
(như đã đề cập ở trên). Điều này có kết quả mong đợi là cả hai #include "..."
và #include <...>
tìm kiếm trong dirpath
Các <file>
bao gồm kể tiền xử lý để tìm kiếm trong -I
danh bạ và trong các thư mục được xác định trước đầu tiên , sau đó trong thư mục file .c của. Các "file"
bao gồm kể tiền xử lý để tìm kiếm thư mục nguồn tập tin của lần đầu tiên , và sau đó trở lại -I
và được xác định trước. Tất cả các điểm đến được tìm kiếm bằng mọi cách, chỉ có thứ tự tìm kiếm là khác nhau.
Tiêu chuẩn năm 2011 chủ yếu thảo luận về các tệp bao gồm trong "Bao gồm tệp nguồn 16.2".
2 Một chỉ thị tiền xử lý của mẫu
# include <h-char-sequence> new-line
tìm kiếm một chuỗi các vị trí được xác định thực hiện cho một tiêu đề được xác định duy nhất bởi trình tự được chỉ định giữa các dấu phân cách <và> và gây ra sự thay thế của lệnh đó bởi toàn bộ nội dung của tiêu đề. Làm thế nào các địa điểm được chỉ định hoặc tiêu đề được xác định là xác định thực hiện.
3 Một chỉ thị tiền xử lý của mẫu
# include "q-char-sequence" new-line
gây ra sự thay thế của lệnh đó bởi toàn bộ nội dung của tệp nguồn được xác định bởi chuỗi được chỉ định giữa "dấu phân cách. Tệp nguồn có tên được tìm kiếm theo cách xác định thực hiện. Nếu tìm kiếm này không được hỗ trợ hoặc nếu tìm kiếm thất bại , lệnh được xử lý lại như thể nó đọc
# include <h-char-sequence> new-line
với chuỗi chứa giống hệt nhau (bao gồm> ký tự, nếu có) từ lệnh ban đầu.
Lưu ý rằng "xxx"
biểu mẫu xuống cấp để <xxx>
hình thành nếu không tìm thấy tệp. Phần còn lại được xác định thực hiện.
-I
doanh nghiệp này được chỉ định không?
-I
.
#include <file.h>
yêu cầu trình biên dịch tìm kiếm tiêu đề trong thư mục "bao gồm" của nó, ví dụ như đối với MinGW, trình biên dịch sẽ tìm kiếm file.h
trong C: \ MinGW \ include \ hoặc bất cứ nơi nào trình biên dịch của bạn được cài đặt.
#include "file"
báo cho trình biên dịch tìm kiếm thư mục hiện tại (tức là thư mục chứa tệp nguồn) file
.
Bạn có thể sử dụng -I
cờ cho GCC để nói với nó rằng, khi nó gặp một bao gồm các dấu ngoặc nhọn, nó cũng nên tìm kiếm các tiêu đề trong thư mục sau -I
. GCC sẽ coi thư mục sau cờ như thể đó là includes
thư mục.
Ví dụ: nếu bạn có một tệp được gọi myheader.h
trong thư mục của riêng bạn, bạn có thể nói #include <myheader.h>
nếu bạn đã gọi GCC bằng cờ -I .
(cho biết rằng tệp đó sẽ tìm kiếm bao gồm trong thư mục hiện tại.)
Không có -I
cờ, bạn sẽ phải sử dụng #include "myheader.h"
để bao gồm tệp hoặc di chuyển myheader.h
đến include
thư mục của trình biên dịch.
Theo tiêu chuẩn - có, chúng khác nhau:
Một chỉ thị tiền xử lý của mẫu
#include <h-char-sequence> new-line
tìm kiếm một chuỗi các vị trí được xác định thực hiện cho một tiêu đề được xác định duy nhất bởi trình tự được chỉ định giữa
<
và các>
dấu phân cách và gây ra sự thay thế của lệnh đó bởi toàn bộ nội dung của tiêu đề. Làm thế nào các địa điểm được chỉ định hoặc tiêu đề được xác định là xác định thực hiện.Một chỉ thị tiền xử lý của mẫu
#include "q-char-sequence" new-line
gây ra sự thay thế của lệnh đó bởi toàn bộ nội dung của tệp nguồn được xác định bởi trình tự được chỉ định giữa các
"
dấu phân cách. Tệp nguồn được đặt tên được tìm kiếm theo cách xác định thực hiện. Nếu tìm kiếm này không được hỗ trợ hoặc nếu tìm kiếm thất bại, lệnh sẽ được xử lý lại như thể nó đã đọc#include <h-char-sequence> new-line
với chuỗi chứa giống hệt nhau (bao gồm các
>
ký tự, nếu có) từ chỉ thị ban đầu.Một chỉ thị tiền xử lý của mẫu
#include pp-tokens new-line
(không phù hợp với một trong hai hình thức trước đó) được cho phép. Các mã thông báo tiền xử lý sau
include
trong lệnh được xử lý giống như trong văn bản thông thường. (Mỗi mã định danh hiện được xác định là tên macro được thay thế bằng danh sách mã thông báo tiền xử lý thay thế.) Lệnh được tạo sau tất cả các thay thế sẽ khớp với một trong hai dạng trước đó. Phương pháp mà theo đó một chuỗi các tiền xử lý tokens giữa<
và một>
cặp thẻ tiền xử lý hoặc một cặp"
nhân vật được kết hợp thành một tên tiêu đề đơn tiền xử lý mã thông báo là thực hiện xác định.Định nghĩa:
h-char: bất kỳ thành viên nào của bộ ký tự nguồn trừ ký tự dòng mới và
>
q-char: bất kỳ thành viên nào của bộ ký tự nguồn trừ ký tự dòng mới và
"
Lưu ý rằng tiêu chuẩn không cho biết bất kỳ mối quan hệ nào giữa cách cư xử được xác định. Biểu mẫu đầu tiên tìm kiếm theo một cách được xác định theo cách thực hiện và biểu mẫu khác theo cách được xác định theo cách thực hiện (có thể khác). Tiêu chuẩn cũng chỉ định rằng các tệp bao gồm nhất định sẽ có mặt (ví dụ <stdio.h>
:).
Chính thức, bạn phải đọc hướng dẫn cho trình biên dịch của mình, tuy nhiên, thông thường (theo truyền thống), #include "..."
biểu mẫu tìm kiếm thư mục của tệp #include
được tìm thấy trước, và sau đó là các thư mục mà #include <...>
biểu mẫu tìm kiếm (đường dẫn bao gồm, ví dụ như tiêu đề hệ thống ).
Cảm ơn câu trả lời tuyệt vời, đặc biệt. Adam Stelmaszchot và piCookie, và aib.
Giống như nhiều lập trình viên, tôi đã sử dụng quy ước không chính thức là sử dụng "myApp.hpp"
biểu mẫu cho các tệp cụ thể của ứng dụng và <libHeader.hpp>
biểu mẫu cho các tệp hệ thống thư viện và trình biên dịch, tức là các tệp được chỉ định trong /I
và INCLUDE
biến môi trường, trong nhiều năm cho rằng đó là tiêu chuẩn.
Tuy nhiên, tiêu chuẩn C nói rằng thứ tự tìm kiếm là cụ thể, có thể làm cho tính di động trở nên phức tạp. Để làm cho vấn đề tồi tệ hơn, chúng tôi sử dụng kẹt, tự động tìm ra vị trí của các tệp bao gồm. Bạn có thể sử dụng đường dẫn tương đối hoặc tuyệt đối cho các tệp đính kèm của mình. I E
#include "../../MyProgDir/SourceDir1/someFile.hpp"
Các phiên bản cũ hơn của MSVS yêu cầu dấu gạch chéo kép (\\), nhưng hiện tại không bắt buộc. Tôi không biết khi nào nó thay đổi. Chỉ cần sử dụng dấu gạch chéo về phía trước để tương thích với 'nix (Windows sẽ chấp nhận điều đó).
Nếu bạn thực sự lo lắng về nó, hãy sử dụng "./myHeader.h"
cho một tệp bao gồm trong cùng thư mục với mã nguồn (dự án rất lớn hiện tại của tôi có một số tên tệp bao gồm trùng lặp - thực sự là một vấn đề quản lý cấu hình).
Đây là lời giải thích MSDN được sao chép ở đây để thuận tiện cho bạn).
Mẫu trích dẫn
Bộ tiền xử lý tìm kiếm các tệp bao gồm theo thứ tự này:
- Trong cùng thư mục với tệp chứa câu lệnh #incoide.
- Trong các thư mục hiện đang mở bao gồm các tệp, theo thứ tự ngược lại trong đó
chúng được mở. Việc tìm kiếm bắt đầu trong thư mục của tập tin cha mẹ bao gồm tập tin và
tiếp tục đi lên thông qua các thư mục của bất kỳ tập tin bao gồm ông bà.- Dọc theo đường dẫn được chỉ định bởi mỗi
/I
tùy chọn trình biên dịch.- Dọc theo các đường dẫn được chỉ định bởi
INCLUDE
biến môi trường.Hình thức khung góc
Bộ tiền xử lý tìm kiếm các tệp bao gồm theo thứ tự này:
- Dọc theo đường dẫn được chỉ định bởi mỗi
/I
tùy chọn trình biên dịch.- Khi biên dịch xảy ra trên dòng lệnh, dọc theo các đường dẫn được chỉ định bởi
INCLUDE
biến môi trường.
Ít nhất là đối với phiên bản GCC <= 3.0, biểu mẫu khung góc không tạo ra sự phụ thuộc giữa tệp được bao gồm và tệp bao gồm.
Vì vậy, nếu bạn muốn tạo quy tắc phụ thuộc (sử dụng tùy chọn GCC -M cho ví dụ), bạn phải sử dụng biểu mẫu được trích dẫn cho các tệp nên được bao gồm trong cây phụ thuộc.
Đối với #include ""
một trình biên dịch thường tìm kiếm thư mục của tệp chứa bao gồm và sau đó các thư mục khác. Đối với #include <>
trình biên dịch không tìm kiếm thư mục của tập tin hiện tại.
<filename>
và "filename"
tìm kiếm các địa điểm được xác định thực hiện.
Khi bạn sử dụng #include <filename>, bộ xử lý trước sẽ tìm tệp trong thư mục của tệp tiêu đề C \ C ++ (stdio.h \ cstdio, chuỗi, vector, v.v.). Nhưng, khi bạn sử dụng #include "filename": trước tiên, bộ xử lý trước sẽ tìm tệp trong thư mục hiện tại và nếu không có ở đây - anh ta sẽ tìm nó trong thư mục của tệp tiêu đề C \ C ++.
#include
này hoàn toàn không liên quan đến các tệp.
Một #incolee với dấu ngoặc góc sẽ tìm kiếm "danh sách địa điểm phụ thuộc vào việc triển khai" (đây là một cách rất phức tạp để nói "tiêu đề hệ thống") cho tệp được đưa vào.
Một #include với dấu ngoặc kép sẽ chỉ tìm kiếm một tệp (và, "theo cách phụ thuộc vào việc thực hiện", bleh). Điều đó có nghĩa là, trong tiếng Anh thông thường, nó sẽ cố gắng áp dụng đường dẫn / tên tệp mà bạn ném vào nó và sẽ không trả trước một đường dẫn hệ thống hoặc giả mạo nó bằng cách khác.
Ngoài ra, nếu #include "" không thành công, nó sẽ được đọc lại dưới dạng #include <> theo tiêu chuẩn.
Các tài liệu gcc có (biên dịch cụ thể) mô tả mà mặc dù là đặc trưng cho gcc và không phải là tiêu chuẩn, là dễ dàng hơn nhiều để hiểu hơn cuộc nói chuyện luật sư theo phong cách của các tiêu chuẩn ISO.
zlib.h
trong đường dẫn tìm kiếm 'người dùng của tôi và một phiên bản khác tồn tại trong đường dẫn tìm kiếm hệ thống, sau đó có #include <zlib.h>
bao gồm phiên bản hệ thống và #include "zlib.h"
bao gồm phiên bản của riêng tôi không?
#include "filename" // User defined header
#include <filename> // Standard library header.
Thí dụ:
Tên tệp ở đây là 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
Trong triển khai lớp (ví dụ, Seller.cpp
và trong các tệp khác sẽ sử dụng tệp Seller.h
), tiêu đề được xác định bởi người dùng bây giờ sẽ được đưa vào, như sau:
#include "Seller.h"
#include <>
dành cho các tệp tiêu đề được xác định trướcNếu tệp tiêu đề được xác định trước thì bạn chỉ cần viết tên tệp tiêu đề trong ngoặc vuông và nó sẽ trông như thế này (giả sử chúng ta có một tên tệp tiêu đề được xác định trước iostream):
#include <iostream>
#include " "
dành cho các tệp tiêu đề mà lập trình viên định nghĩaNếu bạn (lập trình viên) đã viết tệp tiêu đề của riêng bạn thì bạn sẽ viết tên tệp tiêu đề trong dấu ngoặc kép. Vì vậy, giả sử bạn đã viết một tệp tiêu đề được gọi myfile.h
, thì đây là một ví dụ về cách bạn sẽ sử dụng lệnh bao gồm để bao gồm tệp đó:
#include "myfile.h"
Nhiều câu trả lời ở đây tập trung vào các đường dẫn trình biên dịch sẽ tìm kiếm để tìm tệp. Mặc dù đây là những gì hầu hết các trình biên dịch làm, một trình biên dịch tuân thủ được phép được lập trình sẵn với các hiệu ứng của các tiêu đề tiêu chuẩn, và coi, #include <list>
như một công tắc, và nó hoàn toàn không tồn tại dưới dạng một tệp.
Đây không hoàn toàn là giả thuyết. Có ít nhất một trình biên dịch hoạt động theo cách đó. #include <xxx>
Chỉ sử dụng với các tiêu đề tiêu chuẩn.
#include <abc.h>
được sử dụng để bao gồm các tệp thư viện tiêu chuẩn. Vì vậy, trình biên dịch sẽ kiểm tra tại các vị trí mà các tiêu đề thư viện chuẩn đang cư trú.
#include "xyz.h"
sẽ báo cho trình biên dịch bao gồm các tệp tiêu đề do người dùng định nghĩa. Vì vậy, trình biên dịch sẽ kiểm tra các tệp tiêu đề này trong thư mục hiện tại hoặc -I
các thư mục được xác định.
Trong C ++, bao gồm một tệp theo hai cách:
Cái đầu tiên là #include báo cho bộ xử lý trước tìm tệp ở vị trí mặc định được xác định trước. Vị trí này thường là biến môi trường INCLUDE biểu thị đường dẫn bao gồm các tệp.
Và loại thứ hai là #include "filename" cho biết bộ xử lý trước tìm tệp trong thư mục hiện tại trước, sau đó tìm tệp đó trong các vị trí được xác định trước mà người dùng đã thiết lập.
Đầu tiên, tìm kiếm sự hiện diện của tệp tiêu đề trong thư mục hiện tại từ đó lệnh được gọi. Nếu không tìm thấy, sau đó nó tìm kiếm trong danh sách cấu hình sẵn của các thư mục hệ thống tiêu chuẩn.
Điều này tìm kiếm sự hiện diện của tệp tiêu đề trong thư mục hiện tại từ đó lệnh được gọi.
Danh sách thư mục tìm kiếm chính xác phụ thuộc vào hệ thống đích, cách GCC được cấu hình và nơi nó được cài đặt. Bạn có thể tìm thấy danh sách thư mục tìm kiếm của trình biên dịch GCC của mình bằng cách chạy nó với tùy chọn -v.
Bạn có thể thêm các thư mục bổ sung vào đường dẫn tìm kiếm bằng cách sử dụng - I dir , điều này khiến dir được tìm kiếm sau thư mục hiện tại (đối với dạng trích dẫn của lệnh) và trước các thư mục hệ thống tiêu chuẩn.
Về cơ bản, mẫu "xxx" không có gì ngoài tìm kiếm trong thư mục hiện tại; nếu không tìm thấy rơi trở lại mẫu
#include "header.h"
biểu mẫu không chính xác, @personal_cloud. Tôi coi câu trả lời của piCookie và Yann Droneaud là phù hợp nhất khi họ xác định thông tin của họ đến từ đâu. Tôi cũng không tìm thấy câu trả lời được bình chọn hàng đầu là hoàn toàn thỏa đáng.
Các #include <filename>
được sử dụng khi một tập tin hệ thống được nhắc đến. Đó là một tệp tiêu đề có thể được tìm thấy tại các vị trí mặc định của hệ thống như /usr/include
hoặc /usr/local/include
. Đối với các tệp của riêng bạn cần được đưa vào một chương trình khác, bạn phải sử dụng #include "filename"
cú pháp.
tìm kiếm "<tên tệp>" trong các vị trí thư viện C tiêu chuẩn
trong khi "tên tệp" tìm kiếm trong thư mục hiện tại là tốt.
Lý tưởng nhất là bạn sẽ sử dụng <...> cho các thư viện C tiêu chuẩn và "..." cho các thư viện mà bạn viết và có mặt trong thư mục hiện tại.
Nguyên tắc chung đơn giản là sử dụng dấu ngoặc nhọn để bao gồm các tệp tiêu đề đi kèm với trình biên dịch. Sử dụng dấu ngoặc kép để bao gồm bất kỳ tệp tiêu đề khác. Hầu hết các trình biên dịch làm theo cách này.
1.9 - Các tệp tiêu đề giải thích chi tiết hơn về các chỉ thị tiền xử lý. Nếu bạn là một lập trình viên mới làm quen, trang đó sẽ giúp bạn hiểu tất cả những điều đó. Tôi đã học được nó từ đây, và tôi đã theo dõi nó tại nơi làm việc.
#include <filename>
được sử dụng khi bạn muốn sử dụng tệp tiêu đề của thư viện trình biên dịch hoặc hệ thống C / C ++. Các thư viện này có thể là stdio.h, string.h, math.h, v.v.
#include "path-to-file/filename"
được sử dụng khi bạn muốn sử dụng tệp tiêu đề tùy chỉnh của riêng bạn trong thư mục dự án của bạn hoặc ở một nơi khác.
Để biết thêm thông tin về tiền xử lý và tiêu đề. Đọc C - Tiền xử lý .
#include <filename>
#include "filename"
#include <filename>
và tìm kiếm tệp tiêu đề đó tại nơi lưu trữ tệp tiêu đề hệ thống.#include <filename>
.Để xem thứ tự tìm kiếm trên hệ thống của bạn bằng gcc, dựa trên cấu hình hiện tại, bạn có thể thực hiện lệnh sau. Bạn có thể tìm thêm chi tiết về lệnh này tại đây
cpp -v /dev/null -o /dev/null
Apple LLVM phiên bản 10.0.0 (clang-1000.10.44.2)
Mục tiêu: x86_64-apple-darwin18.0.0
Mô hình chủ đề: posix InstalledDir: Library / Developer / CommandLineTools / usr / bin
"/ Thư viện / Nhà phát triển / CommandLineTools / usr / bin / clang" -cc1 -triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-used -Werror = deprecated-objc-isa-used vô hiệu hóa-llvm-xác minh -discard-value-name -main-file-name null -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-Elim -fno -rict-return -masm-verbose munwind-bảng -target-cpu penryn -dwarf-cột-thông tin -debugger-chỉnh = lldb -target-linker-phiên bản 409.12 -v -resource-dir /L Library / Nhà phát triển / CommLLineTools / usr / lib / 10 isysroot / Thư viện / Nhà phát triển / CommonLineTools / SNKs / MacOSX10,14.sdk -I / usr / local / bao gồm -fdebug-compilation-dir / Users / hogstrom -ferror-giới hạn 19 -fmessage-length -fencode-Extended-block-chữ ký -fobjc-runtime = macosx-10.14.0 -fmax-type-align = 16 -fdiagnostics-show-tùy chọn -fcolor-chẩn đoán -traditable-cpp -o - -xc / dev / null
clang -cc1 phiên bản 10.0.0 (clang-1000.10.44.2) mục tiêu mặc định x86_64-apple-darwin18.0.0 bỏ qua thư mục không tồn tại "/L Library / Nhà phát triển / CommonLineTools / DSKs / MacOSX10,14.sdk / usr thư mục "/ L Library / Nhà phát triển / CommonLineTools / SNKs / MacOSX10.14.sdk / L Library / Frameworks"
#include "..." tìm kiếm bắt đầu tại đây:
#include <...> tìm kiếm bắt đầu tại đây:
/ usr / local / include
/ Thư viện / Nhà phát triển / CommandLineTools / usr / lib / clang / 10.0.0 / bao gồm
/ Thư viện / Nhà phát triển / CommandLineTools / usr / bao gồm / Thư viện / Nhà phát triển /
CommonLineTools
/ SNKs / MacOSX10,14.sdk / usr / inc / CommandLineTools / SDKs / MacOSX10.14.sdk / System / Library / Frameworks (thư mục khung)
Kết thúc danh sách tìm kiếm.
Có hai cách để viết câu lệnh #incoide. Đây là:
#include"filename"
#include<filename>
Ý nghĩa của mỗi hình thức là
#include"mylib.h"
Lệnh này sẽ tìm tệp mylib.h
trong thư mục hiện tại cũng như danh sách các thư mục được chỉ định như đã đề cập n đường dẫn tìm kiếm bao gồm có thể đã được thiết lập.
#include<mylib.h>
Lệnh này sẽ tìm tệp mylib.h
trong danh sách chỉ định của các thư mục.
Đường dẫn tìm kiếm bao gồm không có gì ngoài một danh sách các thư mục sẽ được tìm kiếm cho tệp được bao gồm. Trình biên dịch C khác nhau cho phép bạn đặt đường dẫn tìm kiếm theo các cách khác nhau.