외부 연결과 내부 연결 및 차이점을 이해하고 싶습니다.
나는 또한의 의미를 알고 싶다
const
로 달리 선언되지 않는 한 변수는 기본적으로 내부적으로 링크됩니다extern
.
답변
당신이 (구현 파일을 쓸 때 .cpp
, .cxx
등) 컴파일러는 생성 번역 단위를 . 이것은 구현의 소스 파일과 그 안에있는 모든 헤더 #include
입니다.
내부 연결 은 번역 단위의 범위에있는 모든 항목을 나타냅니다 .
외부 연결 은 특정 번역 단위를 넘어 존재하는 것들을 말합니다. 다시 말해, 모든 번역 단위 (또는 객체 파일)의 조합 인 전체 프로그램을 통해 액세스 할 수 있습니다 .
답변
으로 dudewat 말했다 외부 연결은 기호 (함수 나 전역 변수) 프로그램 및 전체에 액세스 할 수있는 의미 내부 가 하나 개에서만 액세스 할 수 있다는 연계 수단 번역 단위 .
extern
및 static
키워드 를 사용하여 심볼의 연결을 명시 적으로 제어 할 수 있습니다 . 연계가 지정되지 않은 경우 기본 연계는 extern
비 const
기호 및 static
(내부) const
심볼에 대한 것 입니다.
// in namespace or global scope
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static
// the same goes for functions (but there are no const functions)
int foo(); // extern by default
static int bar(); // explicitly static
사용하는 대신 주 static
내부 연결을 위해 사용하는 것이 좋습니다 익명의 네임 스페이스 당신도 넣을 수 있습니다되는 class
말이지. 익명 네임 스페이스에 대한 연결은 C ++ 98과 C ++ 11 사이에서 변경되었지만 가장 중요한 것은 다른 번역 단위에서 접근 할 수 없다는 것입니다.
namespace {
int i; // external linkage but unreachable from other translation units.
class invisible_to_others { };
}
답변
- 전역 변수에는 기본적으로 외부 연결 이 있습니다.
extern
다른 파일에 일치하는 선언 을 제공하여 범위를 포함하지 않는 범위로 확장 할 수 있습니다 . - 전역 변수의 범위는 선언 앞에 키워드를 붙여 선언을 포함하는 파일로 제한 할 수 있습니다
static
. 이러한 변수는 내부 연결 이 있다고합니다 .
다음 예제를 고려하십시오.
1.cpp
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
- 함수의 서명은 외부 연결을 가진 함수로
f
선언합니다 (기본값). 이 파일의 정의는이 파일 또는 다른 번역 단위 (아래에 제공됨)에서 나중에 제공해야합니다.f
max
정수 상수로 정의됩니다. 상수의 기본 연결은 internal 입니다. 키워드와의 연결이 외부로 변경되었습니다extern
. 이제max
다른 파일에서 액세스 할 수 있습니다.n
정수 변수로 정의됩니다. 함수 본문 외부에 정의 된 변수의 기본 연결은 external 입니다.
2.cpp
#include <iostream>
using namespace std;
extern const int max;
extern int n;
static float z = 0.0;
void f(int i)
{
static int nCall = 0;
int a;
//...
nCall++;
n++;
//...
a = max * z;
//...
cout << "f() called " << nCall << " times." << endl;
}
max
외부 연결 을 갖도록 선언되었습니다 .max
일부 파일 에 (외부 링크가있는)에 대한 일치하는 정의 가 나타나야합니다. (1.cpp에서와 같이)n
외부 연결 을 갖도록 선언되었습니다 .z
되고 정의 와 전역 변수로 내부 링크 .- 의 정의는 function 호출에 대한 값을 유지하는 변수가되도록
nCall
지정nCall
합니다f()
. 기본 자동 스토리지 클래스가있는 로컬 변수와 달리nCall
, 프로그램 시작시 한 번만 초기화되고을 호출 할 때마다 한 번만 초기화됩니다f()
. 스토리지 클래스 지정자는static
범위가 아닌 로컬 변수의 수명에 영향을줍니다.
주의 : 키워드 static
는 두 가지 역할을합니다. 글로벌 변수의 정의에 사용될 때 내부 연결을 지정합니다 . 지역 변수의 정의에 사용될 때 변수의 수명이 함수의 지속 시간이 아닌 프로그램의 지속 시간이되도록 지정합니다.
희망이 도움이됩니다!
답변
‘C’와 관련하여 (정적 키워드는 ‘C’와 ‘C ++’사이에서 다른 의미를 갖기 때문에)
‘C’의 다른 범위에 대해 이야기 할 수 있습니다
범위 : 기본적으로 얼마나 오래 볼 수 있고 얼마나 멀리 있습니다.
-
지역 변수 : 범위는 함수 안에 만 있습니다. RAM의 STACK 영역에 있습니다. 즉, 함수가 호출 될 때마다 함수 인수를 포함하여 해당 함수의 일부인 모든 변수가 새로 만들어 져서 컨트롤이 함수를 벗어나면 소멸됩니다. (함수가 반환 될 때마다 스택이 플러시되므로)
-
정적 변수 : 이것의 범위는 파일입니다.
선언 된 파일의 모든 위치에 액세스 할 수 있습니다 . RAM의 DATA 세그먼트에 상주합니다. 파일 내부에서만 액세스 할 수 있으므로 내부 링크가 가능합니다. 모든
다른 파일이 변수를 볼 수 없습니다. 사실 STATIC 키워드는
‘C’에 일정 수준의 데이터 또는 함수 숨기기를 도입 할 수있는 유일한 방법입니다. -
전역 변수 : 이것의 범위는 전체 응용 프로그램을위한 것입니다. 응용 프로그램의 모든 곳에서 액세스 할 수 있습니다. 전역 변수도 DATA 세그먼트에 상주합니다. 응용 프로그램의 모든 위치에 액세스 할 수 있으므로 EXTERNAL Linkage
기본적으로 모든 기능은 전역입니다. 파일 외부에서 일부 함수를 숨겨야하는 경우 정적 키워드를 함수 앞에 붙일 수 있습니다. 🙂
답변
질문에 대해 이야기하기 전에 번역 단위 , 프로그램 및 C ++의 기본 개념 (실제로 연결은 일반적으로 그중 하나임) 이라는 용어를 정확하게 아는 것이 좋습니다 . 또한 범위 가 무엇인지 알아야합니다 .
몇 가지 핵심 사항을 강조하겠습니다. 이전 답변에서 누락 된 사람들.
연결 은 이름 의 속성이며 선언에 의해 소개됩니다 . 다른 이름은 동일한 개체 (일반적으로 개체 또는 함수)를 나타낼 수 있습니다 . 따라서 엔터티의 연결 에 대해 말하는 것은 일반적으로 엔터티가 특정 선언 (일반적으로 하나의 선언)에서 고유 한 이름으로 만 참조된다고 확신하지 않는 한 무의미합니다.
주 목적은 실체이지만, 변수는 아니다. 변수의 연결에 대해 이야기하는 동안 실제로 표시된 엔티티 (특정 선언에 의해 도입 된)의 이름이 관련됩니다. 이름의 연결은 연결 없음, 내부 연결 또는 외부 연결 중 하나에 속합니다.
다른 번역 단위는 헤더 / 소스 파일 (예, 표준 문구) 포함으로 동일한 선언을 공유 할 수 있습니다. 따라서 다른 번역 단위에서 동일한 이름을 참조 할 수 있습니다. 선언 된 이름에 외부 연결이있는 경우 해당 이름으로 참조 된 엔티티의 ID도 공유됩니다. 선언 된 이름에 내부 연결이있는 경우 다른 번역 단위에서 동일한 이름이 다른 엔터티를 나타내지 만 동일한 번역 단위의 다른 범위에서 엔터티를 참조 할 수 있습니다. 이름에 연결이없는 경우 다른 범위의 엔터티를 참조 할 수 없습니다.
(죄송합니다 … 입력 한 내용이 다소 표준 문구를 반복 하는 것으로 나타났습니다 …)
언어 사양에 포함되지 않는 다른 혼란스러운 점들도 있습니다.
- 가시성 (이름). 또한 선언 된 이름의 속성이지만 linkage와 다른 의미를 갖습니다 .
- 가시성 (부작용) . 이것은이 주제와 관련이 없습니다.
- 가시성 (기호). 이 개념은 실제 구현에서 사용할 수 있습니다 . 그러한 구현들에서, 객체 (이진) 코드에서 특정 가시성을 갖는 심볼은 일반적으로 소스 (C ++) 코드에서 동일한 특정 링크를 갖는 엔티티 정의로부터 매핑 된 대상이다. 그러나 일대일 보장은 아닙니다. 예를 들어, 동적 라이브러리 이미지의 기호는 소스 코드에서 내부적으로 해당 이미지에서만 공유되도록 지정할 수 있습니다 (일부 확장 프로그램과 함께
__attribute__
또는__declspec
) 또는 컴파일러 옵션을 사용할 수 있으며 이미지가 전체 프로그램 또는 번역 단위에서 번역 된 객체 파일이 아니므로 표준 개념으로 정확하게 설명 할 수 없습니다. C ++에서 symbol은 규범적인 용어가 아니기 때문에 관련 방언의 확장이 널리 채택되어 있어도 구현 세부 사항 일뿐입니다. - 접근성. C ++에서 이것은 일반적 으로 클래스 멤버 또는 기본 클래스의 속성에 관한 것으로, 주제와 관련이없는 다른 개념입니다.
- 글로벌 C ++에서 “글로벌”은 글로벌 네임 스페이스 또는 글로벌 네임 스페이스 범위를 의미합니다. 후자는 C 언어의 파일 범위 와 거의 같습니다 . C와 C ++에서 연결 (linkage)과 같은 범위는 식별자 (C) 또는 이름 (C ++)과 밀접하게 관련되어 있지만 범위와는 아무런 관련이 없습니다.
네임 스페이스 범위 const
변수 의 연결 규칙은 특별합니다 (특히 const
C 언어로 파일 범위에서 선언 된 객체 와 다르며 식별자 연결이라는 개념이 있습니다). ODR 은 C ++에 의해 시행 되므로 함수를 제외하고 전체 프로그램에서 동일한 변수 또는 함수의 정의를 두 개 이상 유지하지 않는 것이 중요 inline
합니다 . 특별한 규칙이 없다면 const
, 여러 번역 단위 (또는 하나의 번역 단위로 여러 번 포함 된 헤더 또는 소스 파일 (종종 “헤더 파일”)에 const
이니셜 라이저 (예 :)가 포함 된 가장 간단한 변수 선언 = xxx
, 그러나 드물게) 프로그램에서 ODR을 위반하여 사용하게됩니다.const
일부 객체와 유사한 매크로를 대체 할 수 없습니다.
답변
C ++의 내부 및 외부 링크 는 명확하고 간결한 설명을 제공 한다고 생각 합니다.
변환 단위는 구현 (.c / .cpp) 파일 및 포함 된 모든 헤더 (.h / .hpp) 파일을 나타냅니다. 이러한 변환 단위 내의 개체 나 함수에 내부 연결이있는 경우 해당 변환 기호 내에서만 링커가 해당 심볼을 볼 수 있습니다. 개체 나 함수에 외부 연결이있는 경우 링커는 다른 변환 단위를 처리 할 때이를 볼 수도 있습니다. 글로벌 네임 스페이스에서 사용될 때 static 키워드는 심볼에 내부 링크가 있도록합니다. extern 키워드는 외부 링크가있는 심볼을 생성합니다.
컴파일러는 기본적으로 심볼 연결을 다음과 같이 지정합니다.
비 const 전역 변수에는 기본적으로 외부 연결이 있습니다
Const 전역 변수에는 기본적으로 내부 연결이 있습니다
함수에는 기본적으로 외부 연결이 있습니다
답변
연결은 식별자가 다른 변환 단위로 표시 되더라도 동일한 이름을 가진 식별자가 동일한 객체, 함수 또는 다른 엔터티를 참조하는지 여부를 결정합니다. 식별자의 연결은 선언 방법에 따라 다릅니다. 연계에는 세 가지 유형이 있습니다.
- 내부 연결 : 식별자는 번역 단위 내에서만 볼 수 있습니다.
- 외부 연결 : 다른 번역 단위에서 식별자를 볼 수 있습니다.
- 연계 없음 : 식별자는 정의 된 범위에서만 볼 수 있습니다. 연결은 범위에 영향을 미치지 않습니다
C ++ 전용 : C ++과 비 C ++ 코드 단편 ( 언어 연계 라고 함)을 연계 할 수도 있습니다.
출처 : IBM 프로그램 연계