Apa perbedaan antara #include <filename> dan #include “filename”?

2357

Dalam bahasa pemrograman C dan C ++, apa perbedaan antara menggunakan kurung sudut dan menggunakan kutipan dalam includepernyataan, sebagai berikut?

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

Jawaban:

1405

Dalam praktiknya, perbedaannya adalah di lokasi di mana preprocessor mencari file yang disertakan.

Untuk #include <filename>pencarian preprosesor dengan cara yang bergantung pada implementasi, biasanya dalam direktori pencarian yang ditentukan sebelumnya oleh kompiler / IDE. Metode ini biasanya digunakan untuk memasukkan file header perpustakaan standar.

Untuk #include "filename"pencarian preprosesor pertama kali di direktori yang sama dengan file yang berisi arahan, dan kemudian mengikuti jalur pencarian yang digunakan untuk#include <filename> formulir. Metode ini biasanya digunakan untuk memasukkan file header yang ditentukan pemrogram.

Deskripsi yang lebih lengkap tersedia di dokumentasi GCC di jalur pencarian .

quest49
sumber
135
Pernyataan: "pencarian preprosesor di direktori yang sama ..." mungkin benar dalam praktiknya tetapi standar menyatakan bahwa file sumber yang dinamai "dicari dengan cara yang ditentukan implementasi". Lihat jawaban dari piCookie.
Richard Corden
60
Walaupun jawaban Anda tampaknya "benar", karena ini adalah berapa banyak implementasi yang bekerja dengan konvensi, Anda harus mencermati jawaban aib dan piCookie. Mereka berdua menunjukkan (didukung oleh kata-kata dari standar C) bahwa perbedaan sebenarnya adalah dimasukkannya "header" versus dimasukkannya "file sumber" (dan tidak, ini tidak berarti ".h" vs. ". c "). "File sumber" dalam konteks ini dapat berupa (dan biasanya, dan hampir selalu harus) file ".h". Header tidak harus berupa file (kompiler misalnya dapat menyertakan header yang diberi kode secara statis, bukan dalam file).
Dan Moulding
5
"... preprocessor mencari di direktori yang sama dengan file yang dikompilasi untuk file yang akan dimasukkan." Pernyataan ini tidak sepenuhnya benar. Saya tertarik pada pertanyaan ini karena saya ingin tahu apa jawaban yang sebenarnya, tetapi saya tahu ini tidak benar karena setidaknya dengan gcc ketika Anda menentukan path tambahan yang menyertakan -I yang akan mencari file yang ditentukan dengan #include "nama file. h "
Gabriel Southern
9
Mereka yang tidak suka jawabannya, tolong, berikan satu contoh praktis, di mana itu salah.
0kcats
1
Benar saja, saya baru-baru ini mencampur sintaksis ini ketika menyertakan header dari perpustakaan 'yang sama' dan berakhir dengan kesalahan redefinisi. Jika saya mengerti dengan benar, #include <...>gunakan paket yang diinstal pada sistem dan #include "..."gunakan versi repositori terdekat. Saya mungkin memiliki mereka mundur. Either way, termasuk penjaga di header paket diawali dengan garis bawah. (Ini bisa menjadi konvensi untuk paket-paket atau mungkin cara untuk dengan sengaja mencegah pencampuran keduanya, meskipun kualifikasi versi akan lebih masuk akal bagi saya.)
John P
714

Satu-satunya cara untuk mengetahui adalah membaca dokumentasi implementasi Anda.

Dalam standar C , bagian 6.10.2, paragraf 2 hingga 4 menyatakan:

  • Arahan preprocessing dari formulir

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

    mencari urutan tempat yang ditentukan implementasi untuk header yang diidentifikasi secara unik oleh urutan yang ditentukan antara <dan >pembatas, dan menyebabkan penggantian direktif tersebut dengan seluruh konten header . Bagaimana tempat ditentukan atau tajuk yang diidentifikasi ditentukan oleh implementasi.

  • Arahan preprocessing dari formulir

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

    menyebabkan penggantian arahan itu dengan seluruh konten file sumber diidentifikasi oleh urutan yang ditentukan antara "pembatas. File sumber yang dinamai dicari dengan cara yang ditentukan implementasi. Jika pencarian ini tidak didukung, atau jika pencarian gagal, arahan diolah kembali seolah-olah dibaca

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

    dengan urutan berisi identik (termasuk >karakter, jika ada) dari arahan asli.

  • Arahan preprocessing dari formulir

    #include pp-tokens new-line

    (yang tidak cocok dengan salah satu dari dua formulir sebelumnya) diizinkan. Token preprocessing setelah includedalam direktif diproses sama seperti pada teks normal. (Setiap pengidentifikasi yang saat ini didefinisikan sebagai nama makro diganti dengan daftar penggantian token pemrosesan sebelumnya.) Arahan yang dihasilkan setelah semua penggantian harus cocok dengan salah satu dari dua formulir sebelumnya. Metode dimana urutan token preprocessing antara a <dan >sepasang token preprocessing atau sepasang "karakter digabungkan ke dalam token preprocessing nama header tunggal didefinisikan dengan implementasi.

Definisi:

  • h-char: anggota karakter set karakter apa pun kecuali karakter baris baru dan >

  • q-char: anggota karakter set karakter apa pun kecuali karakter baris baru dan "

piCookie
sumber
108
Relevan: implementasi dalam g ++ dan dalam visual c ++
Alexander Malakhov
27
@piCookie mencari <filename> dan "filename" untuk mencari tempat yang ditentukan implementasi. Jadi apa bedanya?
onmyway133
15
@Stefan, saya hanya mengutip standar yang tidak mengatakan apa-apa tentang INCLUDE_PATH. Implementasi Anda dapat melakukannya, dan milik saya mungkin tidak. Pertanyaan aslinya umumnya C dan tidak spesifik gcc (yang saya pikir tidak menggunakan INCLUDE_PATH) atau Microsoft C (yang menurut saya) atau yang lain, sehingga tidak dapat dijawab secara umum tetapi sebaliknya setiap dokumentasi implementasi harus dirujuk.
piCookie
12
Seperti halnya semua situasi ini, contoh konkret (terutama skenario umum) sangat bermanfaat dan dihargai secara setara. Jawaban generik yang tumpul dan sia-sia tidak memiliki banyak kegunaan praktis.
vargonian
132
"Begini cara standar C bisa menjadi verbose dan tidak menjawab pertanyaan Anda"
anatolyg
287

Urutan karakter antara <dan> merujuk ke header secara unik, yang tidak harus berupa file. Implementasi cukup bebas untuk menggunakan urutan karakter seperti yang mereka inginkan. (Namun, sebagian besar, hanya memperlakukannya sebagai nama file dan melakukan pencarian di jalur sertakan , seperti keadaan posting lainnya.)

Jika #include "file"formulir digunakan, implementasi pertama mencari file dari nama yang diberikan, jika didukung. Jika tidak (didukung), atau jika pencarian gagal, implementasi berperilaku seolah-olah #include <file>formulir other ( ) digunakan.

Juga, bentuk ketiga ada dan digunakan ketika #includearahan tidak cocok dengan salah satu formulir di atas. Dalam bentuk ini, beberapa preprocessing dasar (seperti ekspansi makro) dilakukan pada "operan" dari #includedirektif, dan hasilnya diharapkan sesuai dengan salah satu dari dua bentuk lainnya.

aib
sumber
50
+1, ini mungkin jawaban yang paling ringkas dan benar di sini. Menurut standar (yang dikutip piCookie dari dalam jawabannya), satu-satunya perbedaan nyata adalah "header" versus "file sumber". Mekanisme pencarian didefinisikan dengan cara apa pun. Menggunakan tanda kutip ganda berarti Anda bermaksud menyertakan "file sumber", sedangkan kurung sudut berarti Anda bermaksud menyertakan "header" yang, seperti yang Anda katakan, mungkin bukan file sama sekali.
Dan Moulding
3
Lihat komentar Dan Moulding untuk jawaban quest49; header standar tidak harus dalam bentuk file, mereka bisa built-in.
aib
10
Saya telah membaca ini "header standar tidak harus dalam bentuk file" selama satu dekade. Peduli untuk memberikan contoh dunia nyata?
Maxim Egorushkin
12
@ Maxim Yegorushkin: Saya juga tidak bisa memikirkan contoh dunia nyata yang ada; Namun, tidak ada kompiler C11 lengkap yang bisa ada untuk MS-DOS kecuali header tidak harus berupa file. Ini karena beberapa nama header C11 tidak kompatibel dengan batasan nama file MS-DOS "8,3".
Dan Moulding
18
@ MaximEgorushkin: Kompiler VAX / VMS C menyimpan semua header perpustakaan runtime dalam file perpustakaan teks tunggal (mirip dengan arsip unix), dan menggunakan string antara <dan >sebagai kunci untuk mengindeks ke perpustakaan.
Adrian McCarthy
117

Beberapa jawaban yang baik di sini membuat referensi ke standar C tetapi lupa standar POSIX, terutama perilaku spesifik dari perintah c99 (misalnya C compiler) .

Menurut The Open Group Base Spesifikasi Issue 7 ,

Direktori -I

Ubah algoritme untuk mencari tajuk yang namanya bukan nama path absolut untuk mencari di direktori yang dinamai dengan nama path direktori sebelum mencari di tempat yang biasa. Dengan demikian, tajuk yang namanya terlampir dalam tanda kutip ganda ("") harus dicari terlebih dahulu di direktori file dengan baris #include , kemudian di direktori bernama di -I pilihan, dan terakhir di tempat-tempat biasa. Untuk tajuk yang namanya terlampir dalam kurung sudut ("<>"), tajuk hanya akan dicari dalam direktori yang bernama opsi -I dan kemudian di tempat yang biasa. Direktori yang bernama in- i opsi harus dicari dalam urutan yang ditentukan.c99 command invocation.

Jadi, dalam lingkungan yang sesuai dengan POSIX, dengan kompiler C yang memenuhi syarat POSIX, #include "file.h"kemungkinan besar akan mencari ./file.hterlebih dahulu, di mana .direktori di mana file dengan #includepernyataan, sementara #include <file.h>, kemungkinan akan mencari /usr/include/file.hpertama, di mana /usr/includesistem Anda didefinisikan tempat biasa untuk header (sepertinya tidak ditentukan oleh POSIX).

Yann Droneaud
sumber
1
Apa sumber teks yang tepat? Apakah itu dari bagian normatif IEEE Std 1003.1, 2013?
osgx
7
@osgx: kata-kata itu (atau sesuatu yang sangat mirip) ditemukan dalam spesifikasi POSIX untuk c99- yang merupakan nama POSIX untuk kompiler C. (Standar POSIX 2008 hampir tidak bisa merujuk ke C11; pembaruan 2013 ke POSIX 2008 tidak mengubah standar C yang dimaksud.)
Jonathan Leffler
1
Ini adalah pikiran pertamaku juga. Halaman manual untuk gcc mencakup ini seperti yang dilakukan orang lain. Ada juga hal serupa untuk perpustakaan - -L.
Pryftan
50

Dokumentasi GCC mengatakan hal berikut tentang perbedaan antara keduanya:

File header pengguna dan sistem disertakan menggunakan arahan preprocessing ‘#include’. Ini memiliki dua varian:

#include <file>

Varian ini digunakan untuk file header sistem. Itu mencari file bernama file dalam daftar standar direktori sistem. Anda dapat menambahkan direktori ke daftar ini dengan -Iopsi (lihat Doa ).

#include "file"

Varian ini digunakan untuk file header program Anda sendiri. Itu mencari file bernama file pertama di direktori yang berisi file saat ini, kemudian di direktori kutipan dan kemudian direktori yang sama digunakan untuk <file>. Anda dapat menambahkan direktori ke daftar direktori penawaran dengan -iquoteopsi. Argumen ‘#include’, apakah dibatasi dengan tanda kutip atau tanda kurung sudut, berperilaku seperti konstanta string di mana komentar tidak dikenali, dan nama makro tidak diperluas. Dengan demikian, #include <x/*y>menentukan penyertaan file header sistem bernama x/*y.

Namun, jika garis miring terbalik terjadi dalam file, mereka dianggap sebagai karakter teks biasa, bukan karakter melarikan diri. Tak satu pun dari urutan pelarian karakter yang sesuai dengan konstanta string dalam C diproses. Jadi, #include "x\n\\y"tentukan nama file yang mengandung tiga garis miring terbalik. (Beberapa sistem mengartikan '\' sebagai pemisah pathname. Semua ini juga menginterpretasikan ‘/’dengan cara yang sama. Ini paling portabel untuk digunakan saja ‘/’.)

Ini adalah kesalahan jika ada sesuatu (selain komentar) pada baris setelah nama file.

Suraj Jain
sumber
46

Itu:

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

dengan .menjadi direktori file di mana #includeterkandung dalam, dan / atau direktori kerja saat ini dari kompiler, dan / ataudefault_include_paths

dan

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

Jika ./ada <default_include_paths>, maka tidak ada bedanya.

Jika mypath/myfileada di direktori include lain, perilaku tidak terdefinisi.

Stefan Steiger
sumber
12
Tidak, #include "mypath/myfile"tidak setara dengan #include "./mypath/myfile". Seperti jawaban piCookie mengatakan, tanda kutip ganda memberitahu kompiler untuk mencari dengan cara yang ditentukan implementasi - yang mencakup pencarian di tempat yang ditentukan #include <...>. (Sebenarnya, ini mungkin setara, tetapi hanya karena, misalnya, /usr/include/mypath/myfiledapat disebut sebagai /usr/include/./mypath/myfile- setidaknya pada sistem mirip Unix.)
Keith Thompson
1
@Keith Thompson: Benar, saya memikirkan kotak Linux saya. Jelas itu bisa berbeda. Meskipun dalam praktiknya, Windows sebagai sistem operasi non-Posix juga melakukan interprete / sebagai path separator, dan ./ juga ada.
Stefan Steiger
1
opsi -L dirpath kemudian menambahkan dirpath ke defaultincludepaths, sebagai ganti untuk memberi makna lain pada .(sebagaimana dimaksud di atas). Ini memiliki konsekuensi yang diharapkan baik #include "..."dan #include <...>cari dalam dirpath
Protongun
1
Saya pikir jawaban ini salah, karena itu menyiratkan bahwa header yang disertakan dengan tanda kutip ganda selalu dicari di direktori kerja saat ini. Mekanisme pencariannya jauh lebih rinci; jawaban ini tidak lengkap. Saya tidak menambahkan komentar ini untuk mengeluh atau merengek, tetapi karena sistem meminta saya untuk menambahkan komentar untuk menjelaskan mengapa saya memilih jawaban ini.
Carlo Wood
39

The <file>termasuk memberitahu preprocessor untuk mencari di -Idirektori dan direktori yang telah ditetapkan pertama , kemudian di direktori c file. The "file"termasuk memberitahu preprocessor untuk mencari direktori file sumber ini pertama , dan kemudian kembali ke -Idan telah ditetapkan. Lagi pula, semua tujuan dicari, hanya urutan pencariannya yang berbeda.

Standar 2011 sebagian besar membahas menyertakan file dalam "16.2 Sumber file inklusi".

2 Arahan preprocessing dari formulir

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

mencari urutan tempat yang ditentukan implementasi untuk header yang diidentifikasi secara unik oleh urutan yang ditentukan antara <dan> pembatas, dan menyebabkan penggantian arahan itu dengan seluruh isi header. Bagaimana tempat ditentukan atau tajuk yang diidentifikasi ditentukan oleh implementasi.

3 Arahan preprocessing dari formulir

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

menyebabkan penggantian arahan itu dengan seluruh konten file sumber yang diidentifikasi oleh urutan yang ditentukan antara "pembatas. File sumber yang disebutkan dicari dengan cara yang ditentukan implementasi. Jika pencarian ini tidak didukung, atau jika pencarian gagal , arahan diolah kembali seolah-olah dibaca

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

dengan urutan berisi identik (termasuk> karakter, jika ada) dari arahan asli.

Perhatikan bahwa "xxx"formulir menurunkan <xxx>bentuk jika file tidak ditemukan. Sisanya ditentukan implementasi.


sumber
4
Bisakah Anda memberikan referensi ke mana dalam standar C -Ibisnis ini ditentukan?
juanchopanza
1
Saya tidak melihat referensi -I.
juanchopanza
2
Itulah bagian "yang didefinisikan implementasi".
28

#include <file.h>memberitahu kompiler untuk mencari header di direktori "include" -nya, misalnya untuk MinGW, kompiler akan mencari file.hdi C: \ MinGW \ include \ atau di mana pun kompiler Anda diinstal.

#include "file"memberitahu kompiler untuk mencari direktori saat ini (yaitu direktori tempat file sumber berada) file.

Anda dapat menggunakan -Ibendera untuk GCC untuk memberi tahu bahwa, ketika menemukan tanda kurung siku, ia juga harus mencari header di direktori setelahnya -I. GCC akan memperlakukan direktori setelah bendera seolah-olah itu adalah includesdirektori.

Misalnya, jika Anda memiliki file yang dipanggil myheader.hdi direktori Anda sendiri, Anda bisa mengatakan #include <myheader.h>jika Anda memanggil GCC dengan flag -I .(menunjukkan bahwa itu harus mencari termasuk dalam direktori saat ini.)

Tanpa -Itanda, Anda harus menggunakan #include "myheader.h"untuk memasukkan file, atau pindah myheader.hke includedirektori kompiler Anda.

adrian
sumber
22

Secara standar - ya, mereka berbeda:

  • Arahan preprocessing dari formulir

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

    mencari urutan tempat yang ditentukan implementasi untuk header yang diidentifikasi secara unik oleh urutan yang ditentukan antara <dan >pembatas, dan menyebabkan penggantian direktif tersebut dengan seluruh konten header. Bagaimana tempat ditentukan atau tajuk yang diidentifikasi ditentukan oleh implementasi.

  • Arahan preprocessing dari formulir

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

    menyebabkan penggantian arahan itu dengan seluruh konten file sumber diidentifikasi oleh urutan yang ditentukan antara "pembatas. File sumber yang dinamai dicari dengan cara yang ditentukan implementasi. Jika pencarian ini tidak didukung, atau jika pencarian gagal, arahan diolah kembali seolah-olah dibaca

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

    dengan urutan berisi identik (termasuk >karakter, jika ada) dari arahan asli.

  • Arahan preprocessing dari formulir

    #include pp-tokens new-line

    (yang tidak cocok dengan salah satu dari dua formulir sebelumnya) diizinkan. Token preprocessing setelah includedalam direktif diproses sama seperti pada teks normal. (Setiap pengidentifikasi yang saat ini didefinisikan sebagai nama makro diganti dengan daftar penggantian token pemrosesan sebelumnya.) Arahan yang dihasilkan setelah semua penggantian harus cocok dengan salah satu dari dua formulir sebelumnya. Metode dimana urutan token preprocessing antara a <dan >sepasang token preprocessing atau sepasang "karakter digabungkan ke dalam token preprocessing nama header tunggal didefinisikan dengan implementasi.

Definisi:

  • h-char: anggota karakter set karakter apa pun kecuali karakter baris baru dan >

  • q-char: anggota karakter set karakter apa pun kecuali karakter baris baru dan "

Perhatikan bahwa standar tidak memberi tahu hubungan apa pun antara perilaku yang ditentukan implementasi. Bentuk pertama mencari dalam satu cara yang ditentukan implementasi, dan yang lainnya dengan cara yang mungkin (mungkin lainnya) yang ditentukan implementasi. Standar ini juga menentukan bahwa file yang disertakan tertentu harus ada (misalnya, <stdio.h>).

Secara formal Anda harus membaca manual untuk kompiler Anda, namun biasanya (berdasarkan tradisi) #include "..."formulir mencari direktori file di mana #includeditemukan pertama kali, dan kemudian direktori yang #include <...>dicari bentuknya (jalur sertakan, misalnya header sistem ).

meroket
sumber
2
Ini sebagian besar hanya teks yang sama dengan jawaban piCookie dari tujuh tahun sebelumnya.
Kyle Strand
5
@KyleStrand Itu karena teks yang sama adalah kutipan dari bagian yang relevan dalam standar - teks itu harus identik. Jawaban sebenarnya bukan teks yang sama dan agak berbeda - sementara saya juga mengakui bahwa itu akan ditulis dalam dokumentasi untuk implementasi saya juga mencatat bahwa ada juga cara tradisional ini ditafsirkan (bahwa sebagian besar atau semua kompiler yang saya gunakan dihormati) .
menjulang tinggi
2
IMO ini adalah jawaban terbaik di sini, karena mencakup apa yang dikatakan standar dan apa yang sebenarnya dilakukan oleh sebagian besar penyusun.
plugwash
17

Terima kasih atas jawaban yang bagus, esp. Adam Stelmaszczyk dan piCookie, dan aib.

Seperti banyak programmer, saya telah menggunakan konvensi informal menggunakan "myApp.hpp"formulir untuk file aplikasi spesifik, dan <libHeader.hpp>formulir untuk file sistem perpustakaan dan kompiler, yaitu file yang ditentukan dalam /Idan INCLUDEvariabel lingkungan, selama bertahun-tahun berpikir itu adalah standar.

Namun, standar C menyatakan bahwa urutan pencarian spesifik implementasi, yang dapat membuat portabilitas rumit. Untuk membuat keadaan menjadi lebih buruk, kami menggunakan jam, yang secara otomatis mencari tahu di mana file yang disertakan. Anda dapat menggunakan jalur relatif atau absolut untuk file sertakan Anda. yaitu

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

Versi MSVS yang lebih lama membutuhkan backslash ganda (\\), tetapi sekarang tidak diperlukan. Saya tidak tahu kapan itu berubah. Cukup gunakan garis miring untuk kompatibilitas dengan 'nix (Windows akan menerimanya).

Jika Anda benar - benar khawatir tentang hal itu, gunakan "./myHeader.h"untuk menyertakan file dalam direktori yang sama dengan kode sumber (proyek saya saat ini, sangat besar memiliki duplikat termasuk nama file yang berserakan - benar-benar masalah manajemen konfigurasi).

Berikut penjelasan MSDN yang disalin di sini untuk kenyamanan Anda).

Formulir dikutip

Pra preprosesor mencari file yang disertakan dalam urutan ini:

  1. Di direktori yang sama dengan file yang berisi pernyataan #include.
  2. Dalam direktori file yang saat ini dibuka sertakan, dalam urutan terbalik di mana
    mereka dibuka. Pencarian dimulai di direktori induk termasuk file dan
    terus ke atas melalui direktori kakek termasuk file.
  3. Sepanjang jalur yang ditentukan oleh setiap /Iopsi kompiler.
  4. Sepanjang jalur yang ditentukan oleh INCLUDEvariabel lingkungan.

Bentuk braket sudut

Pra preprosesor mencari file yang disertakan dalam urutan ini:

  1. Sepanjang jalur yang ditentukan oleh setiap /Iopsi kompiler.
  2. Ketika kompilasi terjadi pada baris perintah, di sepanjang jalur yang ditentukan oleh INCLUDE variabel lingkungan.
riderBill
sumber
16

Setidaknya untuk versi GCC <= 3.0, bentuk braket sudut tidak menghasilkan ketergantungan antara file yang disertakan dan yang disertakan.

Jadi, jika Anda ingin membuat aturan dependensi (menggunakan opsi GCC -M untuk contoh), Anda harus menggunakan formulir yang dikutip untuk file yang harus dimasukkan dalam pohon dependensi.

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

Denis Ros
sumber
1
Ya - ada beberapa cara berbeda untuk menghasilkan dependensi. Itu salah satu dari mereka tetapi itu bukan satu-satunya.
Pryftan
15

Untuk #include ""kompiler biasanya mencari folder file yang berisi yang termasuk dan kemudian folder lainnya. Untuk #include <>kompiler tidak mencari folder file saat ini.

Maxim Egorushkin
sumber
1
Tidak yakin mengapa orang tidak setuju.
Maxim Egorushkin
Saya menduga itu karena kebanyakan orang hanya mengkompilasi file dalam CWD mereka. Jika Anda berada di direktori foo, dan Anda sedang mengkompilasi foo / unittest / bar.c, dan itu termasuk bar.h, maka "bar.h" berfungsi dan <bar.h> tidak.
1
@Maxim orang tidak setuju karena perilaku yang Anda jelaskan bukan standar C.
osvein
2
@Spookbuster Kanan, standar mengatakan keduanya <filename>dan "filename"mencari tempat yang ditentukan implementasi.
Maxim Egorushkin
14

Saat Anda menggunakan #include <filename>, pra-prosesor mencari file dalam direktori file header C \ C ++ (stdio.h \ cstdio, string, vektor, dll.). Tapi, ketika Anda menggunakan #include "nama file": pertama, pra-prosesor mencari file di direktori saat ini, dan jika tidak ada di sini - ia mencarinya di direktori file header C \ C ++.

Chayim Friedman
sumber
1
Setelah jawaban sempurna tersedia selama bertahun-tahun, mengapa mengirimkannya, itu salah besar? Meskipun umum, #includearahan tidak sepenuhnya terkait dengan file sama sekali.
IInspectable
@IInspectable tolong jelaskan mengapa itu tidak terkait dengan file sama sekali.
Behrooz Karjoo
11

Tanda kurung #include with angle akan mencari "daftar tempat yang bergantung pada implementasi" (yang merupakan cara yang sangat rumit untuk mengatakan "header sistem") untuk menyertakan file.

Sebuah #include dengan tanda kutip hanya akan mencari file (dan, "dalam cara yang tergantung pada implementasi", bleh). Yang berarti, dalam bahasa Inggris normal, itu akan mencoba menerapkan path / nama file yang Anda lemparkan padanya dan tidak akan menambah alur sistem atau merusaknya.

Juga, jika #include "" gagal, itu dibaca kembali sebagai #include <> oleh standar.

The dokumentasi gcc memiliki (compiler tertentu) deskripsi yang meskipun menjadi spesifik untuk gcc dan tidak standar, adalah jauh lebih mudah dimengerti daripada pengacara gaya bicara dari standar ISO.

Damon
sumber
Namun, menggunakan kurung sudut atau tanda kutip tidak mempengaruhi cara file dimasukkan, itu persis sama: preprocessor secara esensial membuat file sumber besar dengan menyalin'n'pasting kode dari memasukkan file ke file sumber asli, sebelum memberikan ke compiler (preprocessor melakukan hal lain, seperti #define sustainability, #jika evaluasi, dll. tetapi proses #include itu mudah)
Loghorn
Bagaimana dengan konflik? mis. katakan saya ada zlib.hdi jalur pencarian 'pengguna' saya, dan versi yang berbeda ada di jalur pencarian sistem, lalu apakah #include <zlib.h>termasuk versi sistem dan #include "zlib.h"termasuk saya sendiri?
the_mandrill
Aha, jawab pertanyaan saya sendiri: stackoverflow.com/questions/21593/…
the_mandrill
Terima kasih telah mengakui bahwa standar dan konvensi implementasi tipikal keduanya relevan di sini, daripada hanya menyatakan bahwa itu tidak dapat diketahui karena tidak ditentukan oleh standar.
Kyle Strand
10
#include "filename" // User defined header
#include <filename> // Standard library header.

Contoh:

Nama file di sini adalah 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

Dalam implementasi kelas (misalnya,, Seller.cppdan dalam file lain yang akan menggunakan file Seller.h), header yang ditentukan oleh pengguna sekarang harus dimasukkan, sebagai berikut:

#include "Seller.h"
Barbara
sumber
10
  • #include <> untuk file header yang sudah ditentukan sebelumnya

Jika file header sudah ditentukan maka Anda cukup menulis nama file header di kurung sudut, dan akan terlihat seperti ini (dengan asumsi kami memiliki nama file header yang sudah ditentukan sebelumnya iostream):

#include <iostream>
  • #include " " adalah untuk file header yang didefinisikan programmer

Jika Anda (programmer) menulis file header Anda sendiri maka Anda akan menulis nama file header dalam tanda kutip. Jadi, misalkan Anda menulis file header yang disebut myfile.h, maka ini adalah contoh bagaimana Anda akan menggunakan arahan include untuk memasukkan file itu:

#include "myfile.h"
VishalSoni
sumber
2
Ini tidak ada hubungannya dengan file header yang sudah ditentukan sebelumnya. Itu ada hubungannya dengan lokasi untuk mencari.
C Johnson
9

Banyak jawaban di sini fokus pada jalur yang akan dicari oleh kompiler untuk menemukan file. Walaupun ini adalah apa yang dilakukan kebanyakan kompiler, kompiler yang menyesuaikan diizinkan untuk diprogram dengan efek dari header standar, dan untuk memperlakukan, katakanlah, #include <list>sebagai saklar, dan itu tidak perlu ada sebagai file sama sekali.

Ini bukan murni hipotetis. Setidaknya ada satu kompiler yang bekerja seperti itu. #include <xxx>Disarankan hanya menggunakan header standar.

sp2danny
sumber
9
#include <abc.h>

digunakan untuk memasukkan file perpustakaan standar. Jadi kompiler akan memeriksa di lokasi di mana header perpustakaan standar berada.

#include "xyz.h"

akan memberitahu kompiler untuk memasukkan file header yang ditentukan pengguna. Jadi kompiler akan memeriksa file header ini di folder saat ini atau -Ifolder yang ditentukan.

Christy Wald
sumber
7

Dalam C ++, sertakan file dalam dua cara:

Yang pertama adalah #include yang memberi tahu preprocessor untuk mencari file di lokasi default yang telah ditentukan. Lokasi ini sering merupakan variabel lingkungan TERMASUK yang menunjukkan path untuk memasukkan file.

Dan tipe kedua adalah #include "nama file" yang memberi tahu preprocessor untuk mencari file di direktori saat ini terlebih dahulu, kemudian mencarinya di lokasi yang telah ditentukan pengguna.

virat
sumber
7

Formulir 1 - #termasuk <xxx>

Pertama, mencari keberadaan file header di direktori saat ini dari mana direktif dipanggil. Jika tidak ditemukan, maka ia mencari dalam daftar direktori sistem standar yang telah dikonfigurasikan sebelumnya.

Formulir 2 - #termasuk "xxx"

Ini mencari keberadaan file header di direktori saat ini dari mana direktif dipanggil.


Daftar direktori pencarian yang tepat tergantung pada sistem target, bagaimana GCC dikonfigurasi, dan di mana ia diinstal. Anda dapat menemukan daftar direktori pencarian kompiler GCC Anda dengan menjalankannya dengan opsi -v.

Anda dapat menambahkan direktori tambahan ke jalur pencarian dengan menggunakan - I dir , yang menyebabkan dir untuk dicari setelah direktori saat ini (untuk bentuk kutipan dari direktif) dan di depan direktori sistem standar.


Pada dasarnya, bentuk "xxx" hanyalah pencarian di direktori saat ini; jika tidak ditemukan jatuh kembali formulir

Darshan L
sumber
3
Jika Anda memutuskan untuk menjawab pertanyaan yang lebih lama yang sudah mapan dan jawaban yang benar, menambahkan jawaban baru di akhir hari mungkin tidak memberi Anda kredit apa pun. Jika Anda memiliki beberapa informasi baru yang berbeda, atau Anda yakin jawaban lain semuanya salah, tentu saja tambahkan jawaban baru, tetapi 'jawaban lain' memberikan informasi dasar yang sama lama setelah pertanyaan diajukan biasanya dimenangkan ' tidak memberi Anda banyak kredit.
Jonathan Leffler
1
@Jonathan Leffler Bisakah Anda mengarahkan saya ke jawaban "mapan" yang Anda rasa sama ringkas dan akuratnya dengan jawaban Darshan?
personal_cloud
1
Deskripsi #include "header.h"formulir tidak akurat, @personal_cloud. Saya menganggap jawaban piCookie dan Yann Droneaud paling relevan ketika mereka mengidentifikasi dari mana informasi mereka berasal. Saya juga tidak menemukan jawaban terpilih sepenuhnya memuaskan.
Jonathan Leffler
Mengapa jawaban ini ditunjukkan di atas, sementara dua jawaban lebih jauh di sana ada 650+ satu? Jawaban ini membingungkan saya, karena tidak cocok dengan perilaku yang saya amati. Ini mungkin, karena kalimat terakhir rusak karena tidak keluar kurung sudut. Saya tidak yakin apa artinya itu.
Neonit
6

Ini #include <filename>digunakan ketika file sistem sedang dirujuk. Itu adalah file header yang dapat ditemukan di lokasi default sistem seperti /usr/includeatau /usr/local/include. Untuk file Anda sendiri yang perlu dimasukkan dalam program lain, Anda harus menggunakan #include "filename"sintaks.

srsci
sumber
6

"<nama file>" mencari di lokasi perpustakaan C standar

sedangkan "nama file" juga mencari di direktori saat ini.

Idealnya, Anda akan menggunakan <...> untuk pustaka C standar dan "..." untuk pustaka yang Anda tulis dan ada di direktori saat ini.

jigar karangiya
sumber
4
Informasi baru mana yang menambahkan jawaban ini ke yang lain?
Daniel Langr
5

Aturan umum yang sederhana adalah dengan menggunakan tanda kurung siku untuk memasukkan file header yang datang dengan kompiler. Gunakan tanda kutip ganda untuk memasukkan file header lainnya. Kebanyakan kompiler melakukannya dengan cara ini.

1.9 - File header menjelaskan lebih detail tentang arahan pra-prosesor. Jika Anda seorang programmer pemula, halaman itu seharusnya membantu Anda memahami semua itu. Saya mempelajarinya dari sini, dan saya telah mengikutinya di tempat kerja.

Eakan Gopalakrishnan
sumber
4
#include <filename>

digunakan ketika Anda ingin menggunakan file header dari sistem C / C ++ atau perpustakaan kompiler. Perpustakaan ini bisa berupa stdio.h, string.h, math.h, dll.

#include "path-to-file/filename"

digunakan ketika Anda ingin menggunakan file header kustom Anda sendiri yang ada di folder proyek Anda atau di tempat lain.

Untuk informasi lebih lanjut tentang preprosesor dan header. Baca C - Preprosesor .

Hafiz Shehbaz Ali
sumber
3

#include <filename>

  • Pra-prosesor mencari dengan cara yang bergantung pada implementasi. Ini memberitahu kompiler untuk mencari direktori tempat file header sistem diadakan.
  • Metode ini biasanya digunakan untuk menemukan file header standar.

#include "filename"

  • Ini memberitahu kompiler untuk mencari file header di mana program sedang berjalan. Jika gagal itu berperilaku seperti#include <filename> dan mencari file header di mana file header sistem disimpan.
  • Metode ini biasanya digunakan untuk mengidentifikasi file header yang ditentukan pengguna (file header yang dibuat oleh pengguna). Karenanya jangan gunakan ini jika Anda ingin memanggil pustaka standar karena membutuhkan waktu kompilasi lebih banyak daripada #include <filename>.
Kalana
sumber
2

Untuk melihat urutan pencarian di sistem Anda menggunakan gcc, berdasarkan pada konfigurasi saat ini, Anda dapat menjalankan perintah berikut. Anda dapat menemukan detail lebih lanjut tentang perintah ini di sini

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

Apple LLVM versi 10.0.0 (dentang-1000.10.44.2)
Target: x86_64-apple-darwin18.0.0
Model thread: InstalledDir: Library / Developer / CommandLineTools / usr / bin
"/ Library / Developer / CommandLineTools / usr / bin / clang" -cc1 -triple x86_64-apple-macosx10.14.0 -Wdeprecated-objc-isa-use -Werror = usang-objc-isa-use -E -disable-free - disable-llvm-verifier -discard-value-names -main-file-name null -melokasi-model pic -pic-level 2 -mthread-model posix -mdisable-fp-eliminasi -fno-strict-return -masm-verbose - munwind-tables -target-cpu penryn -dwarf-kolom-info -debugger-tuning = lldb -target-linker-versi 409.12 -v -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/10.0.0 - isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -I / usr / local / termasuk -fdebug-kompilasi-dir / Pengguna / hogstrom -ferror-limit 19 -pesan-panjang 80 -stack-protector 1 -block -fencode-extended-block-signature -fobjc-runtime = macosx-10.14.0 -fmax-type-align = 16 -fdiagnostics-show-option -fcolor-diagnostik -traditional-cpp -o - -xc / dev / null
dentang -cc1 versi 10.0.0 (dentang-1000.10.44.2) target default x86_64-apple-darwin18.0.0 mengabaikan direktori tidak ada "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/local/include" mengabaikan nonexistent direktori "/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/Library/Frameworks"
#include "..." pencarian dimulai di sini:
#include <...> pencarian dimulai di sini:
/ usr / local / include
/ Perpustakaan / Pengembang / CommandLineTools / usr / lib / clang / 10.0.0 / termasuk
/ Perpustakaan / Pengembang / CommandLineTools / usr / termasuk
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include
/ Library / Developer / CommandLineTools / SDKs / MacOSX10.14.sdk / System / Library / Frameworks (framework framework)
Akhir dari daftar pencarian.

Hogstrom
sumber
1
#include <file> 

Termasuk file tempat direktori sertakan default.

#include "file" 

Termasuk file di direktori saat ini di mana itu dikompilasi.

IAmAUser
sumber
-2

Ada dua cara untuk menulis pernyataan #include. Ini adalah:

#include"filename"
#include<filename>

Arti setiap bentuk adalah

#include"mylib.h"

Perintah ini akan mencari file mylib.h di direktori saat ini serta daftar direktori yang ditentukan seperti yang disebutkan di l sertakan jalur pencarian yang mungkin telah diatur.

#include<mylib.h>

Perintah ini akan mencari file mylib.hdalam daftar direktori yang ditentukan saja.

Jalur pencarian sertakan tidak lain adalah daftar direktori yang akan dicari file yang disertakan. Kompiler C yang berbeda memungkinkan Anda mengatur jalur pencarian dengan cara yang berbeda.

Noshiii
sumber
1
Jika Anda memutuskan untuk menjawab pertanyaan yang lebih lama yang sudah mapan dan jawaban yang benar, menambahkan jawaban baru di akhir hari mungkin tidak memberi Anda kredit apa pun. Jika Anda memiliki beberapa informasi baru yang berbeda, atau Anda yakin jawaban lain semuanya salah, tentu saja tambahkan jawaban baru, tetapi 'jawaban lain' memberikan informasi dasar yang sama lama setelah pertanyaan diajukan biasanya dimenangkan ' tidak memberi Anda banyak kredit.
Jonathan Leffler