İki ayrı kavramı birbirinden ayırmanız gerekir: işlev tanımı ve sembol bildirimi. "extern" bir bağlantı modifiye edicisidir, derleyiciye daha sonra değinilen sembolün nerede tanımlandığı hakkında bir ipucudur (ipucu "burada değil").
Yazarsam
extern int i;
bir C dosyasındaki dosya kapsamında (bir fonksiyon bloğunun dışında) "değişken başka bir yerde tanımlanabilir" diyorsunuz.
extern int f() {return 0;}
hem f işlevinin bir açıklaması hem de f işlevinin bir tanımıdır. Bu durumda tanım extern'i geçersiz kılar.
extern int f();
int f() {return 0;}
önce bir deklarasyon, ardından tanım.
extern
Dosya kapsamı değişkenini bildirmek ve aynı anda tanımlamak istiyorsanız , kullanımı yanlıştır. Örneğin,
extern int i = 4;
derleyiciye bağlı olarak bir hata veya uyarı verecektir.
extern
Bir değişkenin tanımından açıkça kaçınmak istiyorsanız , kullanımı yararlıdır.
Açıklamama izin ver:
Diyelim ki ac dosyası şunları içeriyor:
#include "a.h"
int i = 2;
int f() { i++; return i;}
Ah dosyası şunları içerir:
extern int i;
int f(void);
ve bc dosyası şunları içerir:
#include <stdio.h>
#include "a.h"
int main(void){
printf("%d\n", f());
return 0;
}
Üstbilgideki extern kullanışlıdır, çünkü derleyiciye bağlantı aşamasında "bu bir tanımdır, bir tanım değildir" der. İ'yi tanımlayan, bunun için yer ayıran ve ona bir değer atayan ac satırını kaldırırsam, program tanımsız bir başvuru ile derlenemez. Bu, geliştiriciye bir değişkenden bahsettiğini ancak henüz tanımlanmadığını bildirir. Öte yandan, "extern" anahtar kelimesini atlar ve int i = 2
satır kaldırırsanız , program hala derler - i 0 varsayılan değeri ile tanımlanacaktır.
Dosya kapsamı değişkenleri, bir işlevin üstünde bildirdiğiniz blok kapsamı değişkenlerinin aksine, onlara açıkça bir değer atamazsanız, varsayılan 0 veya NULL değeriyle örtülü olarak tanımlanır. Extern anahtar sözcüğü bu örtülü tanımdan kaçınır ve böylece hataların önlenmesine yardımcı olur.
İşlevler için, işlev bildirimlerinde, anahtar sözcük gerçekten gereksizdir. İşlev bildirimlerinin üstü kapalı bir tanımı yoktur.