Chcę zrozumieć powiązanie zewnętrzne i wewnętrzne oraz ich różnicę.
Chcę też poznać znaczenie
const
zmienne są wewnętrznie połączone domyślnie, chyba że zadeklarowano inaczej jakoextern
.
Kiedy piszesz plik realizacji ( .cpp
, .cxx
itp) kompilator generuje jednostkę tłumaczeniową . To jest plik źródłowy z twojej implementacji plus wszystkie nagłówki #include
w nim zawarte.
Powiązanie wewnętrzne odnosi się do wszystkiego tylko w zakresie jednostki tłumaczeniowej .
Zewnętrzne powiązanie odnosi się do rzeczy, które istnieją poza określoną jednostką tłumaczeniową. Innymi słowy, dostępny przez cały program , który jest kombinacją wszystkich jednostek tłumaczeniowych (lub plików obiektowych).
const
zmiennych (a także o jej cel) jest tutaj całkowicie pominięte.Jak powiedział dudewat, zewnętrzne połączenie oznacza, że symbol (funkcja lub zmienna globalna) jest dostępny w całym programie, a wewnętrzne połączenie oznacza, że jest dostępne tylko w jednej jednostce tłumaczeniowej .
Możesz jawnie kontrolować powiązanie symbolu za pomocą słów kluczowych
extern
istatic
. Jeśli połączenie nie jest określone, wówczas domyślne połączenie jestextern
dlaconst
symboli niebędących symbolami istatic
(wewnętrzne) dlaconst
symboli.Zauważ, że zamiast używać
static
wewnętrznego połączenia, lepiej jest używać anonimowych przestrzeni nazw, w których możesz również umieścićclass
es. Łączenie anonimowych przestrzeni nazw zmieniło się między C ++ 98 i C ++ 11, ale najważniejsze jest to, że są one nieosiągalne dla innych jednostek tłumaczeniowych.źródło
extern
deklarację w drugim pliku.static
. Mówi się, że takie zmienne mają wewnętrzne powiązanie .Rozważ następujący przykład:
1. cpp
f
deklaruje sięf
jako funkcję z zewnętrznym łącznikiem (domyślnie). Jego definicja musi zostać podana w dalszej części tego pliku lub w innej jednostce tłumaczeniowej (podanej poniżej).max
jest zdefiniowany jako stała całkowita. Domyślne połączenie dla stałych jest wewnętrzne . Jego powiązanie zostało zmienione na zewnętrzne za pomocą słowa kluczowegoextern
. Terazmax
można uzyskać dostęp do innych plików.n
jest zdefiniowany jako zmienna całkowita. Domyślne powiązanie dla zmiennych zdefiniowanych poza ciałami funkcji jest zewnętrzne .2. cpp
max
jest zadeklarowany jako zewnętrzny link . Wmax
jakimś pliku musi pojawić się pasująca definicja (z zewnętrznym powiązaniem). (Jak w 1.cpp)n
jest zadeklarowany jako zewnętrzny link .z
jest zdefiniowany jako zmienna globalna z wewnętrznym sprzężeniem .nCall
określa,nCall
że jest zmienną, która zachowuje swoją wartość między wywołaniami funkcjif()
. W przeciwieństwie do zmiennych lokalnych z domyślną automatyczną klasą pamięci,nCall
będą inicjowane tylko raz na początku programu, a nie raz dla każdego wywołaniaf()
. Specyfikator klasy pamięcistatic
wpływa na czas życia zmiennej lokalnej, a nie na jej zakres.Uwaga: słowo kluczowe
static
odgrywa podwójną rolę. W przypadku definicji zmiennych globalnych określa powiązanie wewnętrzne . Kiedy jest używany w definicjach zmiennych lokalnych, określa, że czas życia zmiennej ma być czasem trwania programu, a nie czasem trwania funkcji.Mam nadzieję, że to pomaga!
źródło
static
pozwala na leniwe pojedyncze inicjowanie (co może być przydatne, jeśli potrzebujesz obiektu globalnego, ale musisz kontrolować, kiedy jest on budowany z powodu problemów z globalnym porządkiem konstrukcji i nie może dynamicznie przydzielić go używanienew
bardziej szczegółowych schematów inicjalizacji może wykraczać poza to, co jest konieczne dla danego obiektu; w konsekwencji jest to głównie problem w systemach wbudowanych korzystających z C ++).Pod względem „C” (ponieważ słowo kluczowe ma inne znaczenie między „C” i „C ++”)
Porozmawiajmy o innym zakresie w „C”
ZAKRES: Zasadniczo to jak długo mogę coś zobaczyć i jak daleko.
Zmienna lokalna: Zakres jest tylko wewnątrz funkcji. Znajduje się w obszarze STOSOWANIA RAM. Co oznacza, że za każdym razem, gdy funkcja jest wywoływana, wszystkie zmienne wchodzące w skład tej funkcji, w tym argumenty funkcji, są tworzone na nowo i niszczone, gdy kontrola wyjdzie z funkcji. (Ponieważ stos jest opróżniany za każdym razem, gdy funkcja powraca)
Zmienna statyczna: zakres tego dotyczy pliku. Jest dostępny w każdym miejscu pliku,
w którym został zadeklarowany. Znajduje się w segmencie danych RAM. Ponieważ można to uzyskać tylko w pliku, a tym samym połączenie wewnętrzne. Każdy
inne pliki nie widzą tej zmiennej. W rzeczywistości słowo kluczowe STATIC jest jedynym sposobem, w jaki możemy wprowadzić pewien poziom danych lub funkcji
ukrywających się w „C”
Zmienna globalna: zakres tego dotyczy całej aplikacji. Jest dostępny z każdego miejsca aplikacji. Zmienne globalne znajdują się również w segmencie DANYCH, ponieważ można uzyskać do nich dostęp w każdym miejscu aplikacji, a tym samym powiązanie zewnętrzne
Domyślnie wszystkie funkcje są globalne. W przypadku, gdy chcesz ukryć niektóre funkcje w pliku z zewnątrz, możesz poprzedzić funkcję statycznym słowem kluczowym. :-)
źródło
Zanim zaczniesz mówić o tym pytaniu, lepiej dokładnie znać termin jednostka tłumacząca , program i kilka podstawowych pojęć C ++ (tak naprawdę łączenie jest ogólnie jednym z nich). Musisz także wiedzieć, jaki jest zakres .
Podkreślę kilka kluczowych punktów, zwłaszcza. brakujące w poprzednich odpowiedziach.
Powiązanie jest właściwością nazwy , która jest wprowadzana przez deklarację . Różne nazwy mogą oznaczać ten sam byt (zazwyczaj obiekt lub funkcję). Zatem mówienie o powiązaniu jednostki jest zwykle nonsensem, chyba że masz pewność, że do jednostki będzie odwoływała się tylko unikalna nazwa z niektórych konkretnych deklaracji (zazwyczaj jednak jedna deklaracja).
Zauważ, że obiekt jest bytem, ale zmienna nim nie jest. Mówiąc o powiązaniu zmiennej, w rzeczywistości chodzi o nazwę oznaczonego bytu (wprowadzoną przez określoną deklarację). Połączenie nazwy znajduje się w jednym z trzech: brak połączenia, połączenie wewnętrzne lub połączenie zewnętrzne.
Różne jednostki tłumaczeniowe mogą współdzielić tę samą deklarację poprzez dołączenie nagłówka / pliku źródłowego (tak, to sformułowanie standardu). Możesz więc odwoływać się do tej samej nazwy w różnych jednostkach tłumaczeniowych. Jeśli zadeklarowana nazwa ma powiązanie zewnętrzne, tożsamość encji, do której odnosi się nazwa, jest również wspólna. Jeśli zadeklarowana nazwa ma powiązanie wewnętrzne, ta sama nazwa w różnych jednostkach tłumaczeniowych oznacza różne jednostki, ale można odwoływać się do jednostki w różnych zakresach tej samej jednostki tłumaczeniowej. Jeśli nazwa nie ma powiązania, po prostu nie można skierować obiektu z innych zakresów.
(Ups ... Odkryłem, że to, co wpisałem, było po prostu powtórzeniem standardowego sformułowania ...)
Istnieją również inne mylące punkty, które nie są uwzględnione w specyfikacji języka.
__attribute__
__declspec
Zasada powiązania z zakresu nazw
const
zmiennej jest coś specjalnego (a szczególnie różni się odconst
obiektu zadeklarowanego w zakresie plików w języku C, który ma również koncepcję powiązania identyfikatorów). Ponieważ ODR jest wymuszony przez C ++, ważne jest, aby zachować nie więcej niż jedną definicję tej samej zmiennej lub funkcji występującą w całym programie, z wyjątkieminline
funkcji . Jeśli nie ma takiej specjalnej zasadyconst
, najprostsza deklaracjaconst
zmiennej z inicjalizatorami (np.= xxx
) W nagłówku lub pliku źródłowym (często „plik nagłówka”) zawarta w wielu jednostkach tłumaczeniowych (lub w tej samej jednostce więcej niż jeden raz, choć rzadko) w programie naruszy ODR, co sprawia, że warto go używaćconst
zmienna, ponieważ niemożliwe jest zastąpienie niektórych makr obiektowych.źródło
Myślę, że wewnętrzne i zewnętrzne powiązania w C ++ dają jasne i zwięzłe wyjaśnienie:
źródło
Połączenie określa, czy identyfikatory o identycznych nazwach odnoszą się do tego samego obiektu, funkcji lub innej jednostki, nawet jeśli identyfikatory te występują w różnych jednostkach tłumaczeniowych. Połączenie identyfikatora zależy od tego, jak zostało zadeklarowane. Istnieją trzy rodzaje powiązań:
Tylko C ++ : możesz również mieć powiązanie między fragmentami kodu C ++ i innych niż C ++, co nazywa się łączeniem języka .
Źródło: IBM Program Linkage
źródło
Gruntownie
extern linkage
zmienna jest widoczna we wszystkich plikachinternal linkage
zmienna jest widoczna w jednym pliku.Wyjaśnij: stałe zmienne domyślnie łączą się wewnętrznie, chyba że zadeklarowano inaczej jako zewnętrzne
external linkage
const
zmienna globalna tointernal linkage
extern const
zmienna globalna toexternal linkage
Całkiem niezły materiał o linkowaniu w C ++
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
źródło
W C ++
Każda zmienna o zasięgu pliku, która nie jest zagnieżdżona w klasie lub funkcji, jest widoczna we wszystkich jednostkach tłumaczeniowych w programie. Nazywa się to łączem zewnętrznym, ponieważ w czasie łączenia nazwa jest widoczna dla łącznika wszędzie, poza jednostką tłumaczeniową.
Zmienne globalne i funkcje zwykłe mają powiązanie zewnętrzne.
Nazwa obiektu statycznego lub funkcji w zakresie pliku jest lokalna dla jednostki tłumaczącej. To się nazywa jako wewnętrzne połączenie
Powiązanie odnosi się tylko do elementów, które mają adresy w czasie łączenia / ładowania; dlatego deklaracje klas i zmienne lokalne nie są powiązane.
źródło