Tôi bắt đầu đặt câu hỏi về tính hữu ích của từ khóa "extern" được sử dụng để truy cập các biến/hàm trong các mô-đun khác (trong các tệp khác). Chúng ta không làm điều tương tự khi chúng ta đang sử dụng #include preprocessor để nhập một tệp tiêu đề với các biến/hàm nguyên mẫu hoặc định nghĩa hàm/biến?Sự khác nhau giữa việc sử dụng tệp extern và #including header là gì?
Trả lời
extern
là cần thiết vì nó tuyên bố rằng biểu tượng tồn tại và thuộc một loại nhất định và không phân bổ dung lượng lưu trữ cho nó.
Nếu bạn làm:
int foo;
Trong một tập tin header được chia sẻ giữa nhiều file nguồn, bạn sẽ nhận được một lỗi mối liên kết bởi vì mỗi nguồn sẽ có bản sao riêng của mình foo tạo và các mối liên kết sẽ không thể để giải quyết biểu tượng.
Thay vào đó, nếu bạn có:
extern int foo;
Trong phần đầu, nó sẽ khai báo một biểu tượng được định nghĩa ở đâu đó trong mỗi tập tin nguồn.
One (và chỉ một) file nguồn sẽ chứa
int foo;
mà tạo ra một trường hợp duy nhất của foo cho mối liên kết để giải quyết.
No. #include là lệnh tiền xử lý cho biết "đặt tất cả văn bản từ tệp khác ngay tại đây". Vì vậy, tất cả các hàm và biến trong tệp được bao gồm được xác định trong tệp hiện tại.
- 1. Sự khác biệt giữa biến động & extern là gì?
- 2. Sự khác nhau giữa tệp .xib và .storyboard là gì?
- 3. Sự khác nhau giữa: = và + = trong tạo tệp là gì?
- 4. Sự khác nhau giữa việc sử dụng onclick của jQuery và thuộc tính onclick là gì?
- 5. Sự khác nhau giữa việc truyền và sử dụng "như" trong C# là gì?
- 6. Sự khác nhau giữa việc sử dụng mẫu @Transactional và Spring là gì?
- 7. Sự khác nhau giữa việc sử dụng MD5.Create và MD5CryptoServiceProvider là gì?
- 8. Sự khác nhau giữa việc sử dụng chuyển hướng Django và HttpResponseRedirect là gì?
- 9. Sự khác nhau giữa việc sử dụng int [] [] và int [,] là gì?
- 10. Sự khác nhau giữa từ điển và mảng là gì?
- 11. Sự khác nhau giữa TCHAR và WCHAR là gì?
- 12. Sự khác nhau giữa việc sử dụng AppDomain và ConfigurationManager khi nhận đường dẫn đến tệp cấu hình là gì?
- 13. Sự khác nhau giữa @id và @ + id là gì?
- 14. Sự khác nhau giữa Href và Url.Content là gì?
- 15. Sự khác nhau giữa NaN và None là gì?
- 16. Sự khác nhau giữa "nonce" và "GUID" là gì?
- 17. Sự khác nhau giữa Phing và PHPUnderControl là gì?
- 18. Sự khác nhau giữa hg quên và hg là gì?
- 19. Sự khác nhau giữa NSImage và UIImage là gì?
- 20. Sự khác nhau giữa AssemblyVersion, AssemblyFileVersion và AssemblyInformationalVersion là gì?
- 21. Sự khác nhau giữa BaseAdapter và ArrayAdapter là gì?
- 22. Sự khác nhau giữa .bashrc, .bash_profile và .environment là gì?
- 23. Sự khác nhau giữa TFS, SVN và GIT là gì?
- 24. Sự khác nhau giữa System.Drawing.Point và System.Windows.Point là gì?
- 25. Sự khác nhau giữa osql, isql và sqlcmd là gì?
- 26. Sự khác nhau giữa CreateObject và Wscript.CreateObject là gì?
- 27. Sự khác nhau giữa Server.MapPath và HostingEnvironment.MapPath là gì?
- 28. Sự khác nhau giữa InputStream và ByteArrayInputStream là gì?
- 29. Sự khác nhau giữa pls_integer và binary_integer là gì?
- 30. Sự khác nhau giữa FileStream.Flush() và FileStream.Flush (True) là gì?
Nhưng bạn vẫn không thể truy cập int foo mà không khai báo với extern int foo miễn là bạn bao gồm tệp tiêu đề chứa định nghĩa của nó? –
Như jcopenha đã đề cập, #include chỉ chèn văn bản từ tệp được bao gồm vào tệp nguồn - trình biên dịch không thực sự nhận thức được tệp bao gồm và không xử lý chúng đặc biệt. Vì vậy, nếu bạn có A.c, B.c, và C.c, mỗi người có "int foo" và bạn liên kết chúng với nhau, làm thế nào để bạn giải quyết foo? Nó tồn tại ở 3 nơi khác nhau. extern chỉ có nghĩa là, biểu tượng tồn tại ở một nơi khác. Bạn có thể sử dụng nó, nhưng ai đó có trách nhiệm tạo ra nó. – Michael
Bạn sẽ thấy rằng đối với các hàm chỉ có một thể hiện của các chương trình foo_fun() với các mô-đun gọi foo_fun() sẽ làm việc có hoặc không có extern. Vì vậy, trong những trường hợp đó, bạn nên cố gắng rõ ràng về nó. Khi bạn nhận được vào một biến toàn cầu được chia sẻ, bạn cần phải thực sự rõ ràng, một số trình biên dịch con số nó ra, một số thì không. –