2012-10-19 12 views
18

W książce C jest napisane:Czy ktoś może wyjaśnić nazwy zmiennych wewnętrznych/zewnętrznych?

Co najmniej pierwsze 31 znaków nazwy wewnętrznej jest znaczące. W przypadku nazw funkcji i zmiennych zewnętrznych liczba może być mniejsza niż 31, ponieważ nazwy zewnętrzne mogą być używane przez asemblery i ładowarki, nad którymi język nie ma kontroli. W przypadku nazw zewnętrznych standard gwarantuje unikalność tylko dla 6 znaków i jednego przypadku. Słowa kluczowe, takie jak if, else, int, float itd., Są zarezerwowane: nie można ich używać jako nazw zmiennych. Muszą być pisane małymi literami.

Czy ktoś może wyjaśnić, co to jest "nazwa wewnętrzna", "nazwy zewnętrzne", "zmienne zewnętrzne"? Byłoby lepiej, gdybyś mógł zrobić przykład.

+1

Która "książka C"? Czy faktycznie nazywa się "ANSI C"? – asteri

+0

@Jeff Jest książka "The C Book" - http://www.amazon.com/The-Book-Featur-Standard-Instruction/dp/0201544334 Podejrzewam, że właśnie to odnosi się do PO. –

+0

To jest standardowy limit C89/C90; standard C99 podnosi te limity (_63 znaczących znaków początkowych w identyfikatorze wewnętrznym lub nazwie makra ... 31 znaczących znaków początkowych w zewnętrznym identyfikatorze ..._) z pewnymi zastrzeżeniami dotyczącymi uniwersalnych nazw znaków w nazwach. Limity są takie same dla C2011. Zauważ, że standard C99 wymaga dużej czułości w przypadku, gdy oryginalny standard C89 nie. –

Odpowiedz

1

"Nazwy wewnętrzne" to nazwy identyfikatorów w obrębie funkcji (skutecznie nazwy zmiennych lokalnych).

"Nazwy zewnętrzne" to nazwy innych identyfikatorów, w tym nazwy funkcji i wszelkie identyfikatory zadeklarowane w zakresie globalnym lub zadeklarowane za pomocą klasy zewnętrznej.

Zasadniczo wszystko, co musi być "widoczne z zewnątrz", ma tylko 6 unikalnych znaków, co jest bardzo ograniczone.

W praktyce nie stanowi to już problemu. C99 zwiększyło te limity, a większość współczesnych kompilatorów usuwa lub znacznie zwiększa te limity. Na przykład, Visual C++ allows 247 characters for uniqueness we wszystkich identyfikatorów (wewnętrznego lub zewnętrznego) podczas kompilowania C

+0

Zakres nie ma znaczenia. Standard C określa cztery zakresy: prototyp funkcji, pliku, bloku i funkcji. Żadne z nich nie ma charakteru globalnego. Właściwą koncepcją jest powiązanie, które może być wewnętrzne, zewnętrzne lub żadne. Identyfikatory w pliku i zakresie bloku mogą mieć powiązania zewnętrzne (lub nie). –

25

głaszcząc moją białą brodę i mówienie w szałwii i pompatycznym głosem, mówię:

W dawnych czasach, kiedy FORTRAN i COBOL wykluczyć świat informatyczny, język C na początek musiał dopasować się do istniejących łańcuchów narzędzi. Te łańcuchy narzędzi zawierały edytory link (a/k/a linkers, a/k/a loader) i asemblery, które przetwarzały tylko krótkie 6-znakowe nazwy symboli (zmiennych i funkcji).

Kompilatory C dla tych łańcuchów narzędzi musiały udawać, że nazwy zmiennych i funkcji były krótkie, gdy wypisywały pliki obiektów, które mają być używane przez edytory linków. To była zła wiadomość. Dobrą wiadomością było to, że w programach C istnieje wiele symboli, które nie muszą pojawiać się w plikach obiektów.

Na przykład nazwy funkcji ... np. "main" i "sqrt" ... muszą pojawiać się w modułach obiektowych, więc kod z innych modułów obiektowych mógłby z nich korzystać. Podobnie nazwano globalne zmienne stylu "zewnętrznego". To są nazwy zewnętrzne.

Jednak wszystkie inne nazwy w programie C, na przykład nazwy zmiennych w zakresie funkcji, nazwy członków struktur i tak dalej, nie musiały być wprowadzane do modułów obiektów. Te są nazywane "nazwami wewnętrznymi".

Tak więc, na przykład, można mieć tych zmiennych C w funkcji

int myFavoriteItem; 
int myFavoriteThing; 

i że będzie dobrze. Ale można je zadeklarować jako zmienne zewnętrzne, tak jak poniżej:

extern int myFavoriteItem; 
extern int myFavoriteThing; 

Niektóre systemy napisze te nazwy się do plików obiektowych, jak gdyby były długie sześć liter (ponieważ pliki obiekt nie wiedział, co zrobić z dłuższe nazwy). Następnie spoglądają na plik obiektowy tak, jakby zostały zadeklarowane w ten sposób.

extern int myFavo; 
extern int myFavo; 

To byłyby duplikaty deklaracji. Kompilator języka C był wymagany do przechwytywania tego typu rzeczy i zgłaszania błędu, zamiast zapisywania duplikatu deklaracji do pliku obiektu. To była wielka pomoc dla programistów: zduplikowane deklaracje w plikach obiektowych generowały naprawdę niejasne komunikaty o błędzie edytora link.

Cytowany fragment określa, że ​​kompilatory muszą rozpoznawać co najmniej 31 znaków nazwy wewnętrznej i 6 nazwy zewnętrznej. Nowoczesne kompilatory i biblioteki narzędzi nie mają już innych ograniczeń długości nazwy.

+7

+1 za odpowiedź i faktycznie o białą brodę! – Spevy

+3

+1: Pamiętam kodowanie w C dla kodu wywoływanego z Fortran ... 6 znaków monocase.Ułatwiło to znaczące nazwy (zwłaszcza, że ​​istniały reguły dotyczące przestrzeni nazw, więc wszystkie nazwy zaczynały się "g", a wewnętrzne funkcje musiały zaczynać się "gk", a następne dwa były zarezerwowane dla "sterownika urządzenia" (tak " gk0p ',' gk1t ', etc, pozostawiając wielką sumę dwóch liter lub cyfr dostępnych dla znaczącego mnemonika!). –

+0

Więcej historii: [Radix-50] (http://en.wikipedia.org/wiki/ DEC_Radix-50) wydaje się być jednym z winowajców.Może to również wyjaśnić, dlaczego $ jest dozwolone w nazwach symboli –

0

Zewnętrzna nazwa to identyfikator z zewnętrznym powiązaniem. Aby identyfikator posiadał powiązanie zewnętrzne, musi to być niestatyczny zakres pliku lub wyraźnie określony jako "zewnętrzny". Przykład:

int global_variable; 

int main(void) 
{ 
    int local_variable; 
    extern int extern_variable; 
    return 0; 
} 

W powyższym przykładzie, identyfikatory global_variable i extern_variable są nazwami zewnętrzne. local_variable to nazwa wewnętrzna.

Należy zauważyć, że w praktyce, ilość znaczących znaków jest większa niż tylko 31 i kompilator C 6. Microsoft na przykład używa 247 znaczących znaków zarówno wewnętrznych, jak i zewnętrznych nazw domyślnie. GCC traktuje wszystkie znaki nazw wewnętrznych jako istotne. Znaczące znaki nazw zewnętrznych zależą od łącznika (a na większości platform obowiązuje ta sama reguła, co w przypadku nazw wewnętrznych, wszystkie znaki są znaczące.)

Standard ANSI określa minimalną liczbę znaczących znaków, aby standartowy.

+0

Zakres jest nieistotny Standard C określa cztery zakresy: prototyp funkcji, pliku, bloku i funkcji. są one globalne pojęcie to powiązanie, które może być wewnętrzne, zewnętrzne lub żadne. Identyfikatory w pliku i zakresie bloku mogą mieć powiązania zewnętrzne (lub nie). –

+0

@EricPostpischil Czy opis podany [tutaj] (http://msdn.microsoft.com/en-us/library/e7f8y25b (v = vs.80) .aspx) jest nieprawidłowy? W szczególności: "Zewnętrzne identyfikatory (zadeklarowane w zasięgu globalnym lub zadeklarowane z klasą pamięci zewnętrznej)". –

+0

Tak, ten tekst jest nieprawidłowy. Autorytatywnym punktem odniesienia dla C jest standard ISO/IEC C, a nie Microsoft. Jak już zauważyłem, nie ma globalnego zasięgu. Ale weź pod uwagę identyfikator zadeklarowany w największym możliwym zakresie, zakresie pliku, przy użyciu 'static int x;'. Ten identyfikator ma zasięg pliku, ale wewnętrzne powiązanie. Nie ma zakresu, który gwarantowałby powiązanie zewnętrzne. –

4

Nazwy zewnętrzne:

nazwy „zewnętrzne” są te, które są widoczne dla innych jednostek kompilacji, takich jak funkcje non-statycznych i zmiennych zadeklarowanych z „extern” słowo kluczowe. Nazwy te muszą być wystawione na łączniki i ładowarki. W Ye Olden Days niektóre łączniki i programy ładujące mogły obsługiwać tylko bardzo krótkie nazwy.

Nazwy wewnętrzne:

nazwy „wewnętrzne” są te, które nie są widoczne na zewnątrz modułu jest kompilowany - w zasadzie nic z zakresu „statyczne”, lub cokolwiek lokalnej do funkcji. Kompilatory C muszą obsługiwać te nazwy, ale nic poza tym.

Powiązane problemy