คุณต้องแยกความแตกต่างระหว่างแนวคิดที่แยกกันสองแนวคิด: นิยามฟังก์ชันและการประกาศสัญลักษณ์ "extern" เป็นตัวดัดแปลงการเชื่อมโยงคำใบ้ของคอมไพเลอร์เกี่ยวกับตำแหน่งที่มีการอ้างถึงสัญลักษณ์หลังจากนั้น (คำใบ้คือ "ไม่ใช่ที่นี่")
ถ้าฉันเขียน
extern int i;
ในขอบเขตไฟล์ (นอกบล็อกฟังก์ชั่น) ในไฟล์ C จากนั้นคุณกำลังพูดว่า "ตัวแปรอาจถูกกำหนดที่อื่น"
extern int f() {return 0;}
เป็นการประกาศฟังก์ชัน f และนิยามของฟังก์ชัน f คำจำกัดความในกรณีนี้มากเกินไปที่จะขับ extern
extern int f();
int f() {return 0;}
เป็นการประกาศครั้งแรกตามด้วยคำจำกัดความ
การใช้extern
ผิดถ้าคุณต้องการประกาศและกำหนดตัวแปรขอบเขตไฟล์พร้อมกัน ตัวอย่างเช่น,
extern int i = 4;
จะให้ข้อผิดพลาดหรือคำเตือนขึ้นอยู่กับคอมไพเลอร์
การใช้งานextern
จะมีประโยชน์หากคุณต้องการหลีกเลี่ยงการนิยามตัวแปรอย่างชัดเจน
ให้ฉันอธิบาย:
สมมติว่าไฟล์ ac มี:
#include "a.h"
int i = 2;
int f() { i++; return i;}
ไฟล์ ah รวมถึง:
extern int i;
int f(void);
และไฟล์ bc มี:
#include <stdio.h>
#include "a.h"
int main(void){
printf("%d\n", f());
return 0;
}
extern ในส่วนหัวมีประโยชน์เพราะมันบอกคอมไพเลอร์ในระหว่างขั้นตอนการเชื่อมโยง "นี่เป็นการประกาศและไม่ใช่คำจำกัดความ" หากฉันลบบรรทัดใน ac ซึ่งกำหนด i ให้จัดสรรพื้นที่สำหรับมันและกำหนดค่าให้กับมันโปรแกรมควรจะคอมไพล์ด้วยการอ้างอิงที่ไม่ได้กำหนด สิ่งนี้บอกผู้พัฒนาว่าเขาได้อ้างถึงตัวแปร แต่ยังไม่ได้กำหนด หากตรงกันข้ามฉันละเว้นคำหลัก "extern" และลบint i = 2
บรรทัดโปรแกรมยังคงคอมไพล์ - ฉันจะถูกกำหนดด้วยค่าเริ่มต้นเป็น 0
ตัวแปรขอบเขตไฟล์ถูกกำหนดโดยปริยายด้วยค่าเริ่มต้นที่ 0 หรือ NULL หากคุณไม่ได้กำหนดค่าให้กับพวกเขาอย่างชัดเจน - ซึ่งแตกต่างจากตัวแปรขอบเขตบล็อกที่คุณประกาศที่ด้านบนของฟังก์ชั่น คำหลักภายนอกหลีกเลี่ยงคำจำกัดความที่ชัดเจนนี้และช่วยหลีกเลี่ยงข้อผิดพลาด
สำหรับฟังก์ชั่นในการประกาศฟังก์ชั่นคำหลักซ้ำซ้อนแน่นอน ประกาศฟังก์ชั่นไม่ได้มีความหมายโดยนัย