หลายปีต่อมาฉันค้นพบคำถามนี้ หลังจากอ่านคำตอบและความคิดเห็นทุกครั้งฉันคิดว่าฉันสามารถอธิบายรายละเอียดบางอย่างได้ ... นี่อาจเป็นประโยชน์สำหรับผู้ที่มาที่นี่ผ่านการค้นหาของ Google
คำถามนั้นเกี่ยวกับการใช้ฟังก์ชั่น "extern" ดังนั้นฉันจะไม่สนใจการใช้ "extern" กับตัวแปรทั่วโลก
ลองกำหนด 3 ฟังก์ชันต้นแบบ:
//--------------------------------------
//Filename: "my_project.H"
extern int function_1(void);
static int function_2(void);
int function_3(void);
ไฟล์ส่วนหัวสามารถใช้งานได้โดยซอร์สโค้ดหลักดังนี้:
//--------------------------------------
//Filename: "my_project.C"
#include "my_project.H"
void main(void){
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 1234;
ในการรวบรวมและลิงก์เราต้องกำหนด "function_2" ในไฟล์ซอร์สโค้ดเดียวกับที่เราเรียกใช้ฟังก์ชันนั้น สามารถกำหนดฟังก์ชันอื่นอีกสองฟังก์ชันในซอร์สโค้ด " .C" ที่แตกต่างกันหรืออาจอยู่ในไฟล์ไบนารี่ใด ๆ ( .OBJ, * .LIB, * .DLL) ซึ่งเราอาจไม่มีซอร์สโค้ด
ลองรวมส่วนหัว "my_project.H" อีกครั้งในไฟล์ "* .C" อื่นเพื่อเข้าใจความแตกต่างได้ดียิ่งขึ้น ในโครงการเดียวกันเราเพิ่มไฟล์ต่อไปนี้:
//--------------------------------------
//Filename: "my_big_project_splitted.C"
#include "my_project.H"
void old_main_test(void){
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 5678;
int function_1(void) return 12;
int function_3(void) return 34;
คุณสมบัติสำคัญที่ควรแจ้งให้ทราบ:
เมื่อฟังก์ชั่นถูกกำหนดเป็น "คงที่" ในไฟล์ส่วนหัวคอมไพเลอร์ / ลิงเกอร์จะต้องค้นหาอินสแตนซ์ของฟังก์ชั่นที่มีชื่อในแต่ละโมดูลซึ่งใช้ที่มีไฟล์
ฟังก์ชั่นซึ่งเป็นส่วนหนึ่งของไลบรารี C สามารถแทนที่ได้ในโมดูลเดียวโดยการกำหนดต้นแบบใหม่ด้วย "คงที่" เฉพาะในโมดูลนั้น ตัวอย่างเช่นแทนที่การเรียกไปที่ "malloc" และ "ฟรี" เพื่อเพิ่มคุณสมบัติการตรวจจับการรั่วไหลของหน่วยความจำ
ตัวระบุ "extern" ไม่จำเป็นสำหรับฟังก์ชั่น เมื่อไม่พบ "คงที่" ฟังก์ชันจะถือว่าเป็น "ภายนอก" เสมอ
อย่างไรก็ตาม "extern" ไม่ใช่ค่าเริ่มต้นสำหรับตัวแปร โดยปกติไฟล์ส่วนหัวใด ๆ ที่กำหนดตัวแปรที่จะมองเห็นได้ในหลาย ๆ โมดูลจำเป็นต้องใช้ "extern" ข้อยกเว้นเพียงอย่างเดียวคือหากไฟล์ส่วนหัวรับประกันว่าจะรวมอยู่ในหนึ่งโมดูลและโมดูลเดียวเท่านั้น
ผู้จัดการโครงการหลายคนจะต้องการให้ตัวแปรนั้นถูกวางไว้ที่จุดเริ่มต้นของโมดูลไม่อยู่ในไฟล์ส่วนหัวใด ๆ โครงการขนาดใหญ่บางอย่างเช่นโปรแกรมจำลองวิดีโอเกม "Mame" จำเป็นต้องมีตัวแปรดังกล่าวที่ปรากฏเหนือฟังก์ชันแรกที่ใช้งาน