Extern의 문제점은 이 키워드가 나타날 때 선언인지 정의인지 알 수 없다는 것입니다.
기억하세요: 선언은 여러 번 할 수 있지만 정의는 한 번만 할 수 있습니다.
함수 자체가 수정되지 않은 extern이기 때문에 함수 선언에서 extern 키워드는 선택 사항입니다. 하지만 인용할 때는 여전히 선언해야 합니다.
전역 변수를 외부에서 선언할 때 extern 키워드가 필요하며, 변수가 extern 수정되지 않고 명시적으로 초기화되지 않으면 변수의 정의도 되므로 이때 extern을 추가해야 합니다. 컴파일러 여기에 표시된 저장 공간은 실행 시 메모리에 로드되고 0으로 초기화됩니다. 지역 변수의 선언은 extern으로 수정할 수 없으며, 지역 변수는 런타임 시 스택 부분에만 메모리를 할당합니다.
참조문, 정의문
강한 기호, 약한 기호
는 Linux gcc 링크 분석에 나타나 링크 이해를 심화할 수 있습니다. .
전역 변수나 함수 사이에는 본질적으로 차이가 없습니다. 함수 이름은 함수 바이너리 블록의 시작 부분을 가리키는 포인터입니다. 전역 변수는 함수 외부에서 선언된 변수입니다. 함수 이름도 함수 외부에 있으므로 함수도 전역적입니다.
사용시 스타일을 만들어 보세요.
헤더 파일
먼저 헤더 파일에 대해 이야기해 보겠습니다. 사실 헤더 파일은 컴퓨터에 아무런 영향을 미치지 않습니다. 사실 헤더 파일은 주로 다른 사람이 볼 수 있는 파일입니다.
헤더 파일의 접미사를 xxx.txt로 변경하고
#include "xxx.txt"
를 사용하여 실험을 해보았는데 컴파일과 링크가 원활하게 진행되었습니다. . 헤더 파일은 코드 읽기 전용이며 다른 기능은 없음을 알 수 있습니다!
C이든 C++이든 함수, 변수, 구조체, 클래스 등을 .c 또는 .cpp 파일에 넣습니다. 그런 다음 lib, dll, obj, .o 등으로 컴파일한 다음 가장 기본적인 gcc hisfile.cpp yourfile.o|obj|dll|lib 등을 사용합니다.
하지만 우리 프로그래머들은 lib, dll에 무엇이 있는지 어떻게 알 수 있나요...? 헤더 파일에 따라 다릅니다. 헤더 파일은 사용자에 대한 설명입니다. 기능, 매개변수 및 다양한 인터페이스에 대한 설명입니다.
설명이기 때문에 헤더 파일에 들어가는 것은 당연히 함수, 변수, 클래스에 대한 '선언'입니다. 이는 "정의"가 아니라 "진술"임을 기억하십시오.
그러니까 여러분 모두 선언과 정의의 차이점을 알고 계시리라 믿습니다. 그러므로 헤더 파일에 어리석게 아무것도 정의하지 않는 것이 가장 좋습니다. 예를 들어 전역 변수는 다음과 같습니다.
#ifndef _XX_header.H
#define _XX_header.H
int A;
#endif
글쎄요. 안 좋은 점은, 여기서 int A는 전역 변수의 정의이므로 이 헤더 파일이 여러 번 참조되면 A가 반복적으로 정의됩니다.
분명히 구문이 잘못되었습니다. 하지만 이 #ifndef 조건부 컴파일을 사용하면 헤더 파일이 한 번만 참조되도록 할 수 있지만 여전히 잘못될 수 있습니다. 그러나 여러 c 파일에 이 헤더 파일이 포함되어 있으면 매크로 이름의 유효 범위가 이기 때문에 오류가 계속 발생합니다. 이 C 소스 파일에 국한되어 있어서 이런 여러 개의 C 파일을 컴파일하면 에러가 나지 않으나, 링크를 하면 같은 변수를 여러 곳에 정의했다고 에러가 난다,
링크. ..
incl2.obj : 오류 LNK2005: incl1.obj에 이미 정의된 "int glb"(?glb@@3HA)
Debug/incl.exe : 치명적인 오류 LNK1169: 하나 이상의 다중 정의 기호가 발견되었습니다
주목! ! !
extern
이 키워드는 정말 혐오스럽습니다. 선언할 때 이 extern을 생략할 수 있어서 선언인지 정의인지 헷갈리게 됩니다. 함수에는 두 가지 유형이 있습니다.
(1) 변수
특히 변수의 경우.
extern int a;//전역 변수 a 선언
int a; //전역 변수 a 정의
extern int a =0;//전역 변수 a를 정의하고 이니셜을 제공합니다. 값 .
int a =0;//전역 변수 a를 정의하고 초기값을 지정합니다.
네 번째는 세 번째와 동일하며 둘 다 외부에서 사용할 수 있는 전역 변수를 정의합니다. 초기값을 줍니다.
헷갈리시네요. 둘이 정말 비슷하네요. 그러나 정의는 한 곳에서만 나타날 수 있습니다. 즉, int a; 또는 extern int a=0; 또는 int a=0;인지 여부에 관계없이 한 번만 나타날 수 있지만 extern int a는 여러 번 나타날 수 있습니다.
전역 변수를 참조하려면 extern int a를 선언해야 합니다. 이때 extern은 생략할 수 없습니다. 생략하면 int a가 되기 때문입니다. .
(2) 함수
함수, 함수도 마찬가지로 정의하고 선언합니다. 정의할 때 이 함수를 외부에서 참조할 수 있음을 나타내기 위해 extern을 사용합니다. 이것이 진술이라는 것입니다. 그러나 함수 정의에는 함수 본문이 있어야 하고, 함수 선언에는 함수 본문이 없으므로 어쨌든 함수를 정의하고 선언할 때 extern을 생략할 수 있습니다. 다른 파일도 이 함수가 다른 곳에 정의되어 있다는 것을 알고 있으므로 extern을 추가하지 않아도 괜찮습니다. 둘은 너무 다르기 때문에 extern을 생략해도 문제가 없습니다.
예:
int fun(void)
{
return 0;
}
좋습니다. 전역 함수를 정의했습니다.
int fun(void);
에 대한 선언을 한 다음 나중에 사용할 수 있습니다
extern을 추가하는지 여부는 중요하지 않습니다
fun 선언을 header file , 최종적으로 다음과 같이 됩니다
int fun(void);//함수 선언이므로 extern은 생략되고 전체 버전은 extern int fun(void);
int fun입니다. (void)
{
return 0;
}//완전한 전역 함수 정의, 함수 본문이 있으므로 extern도 생략됩니다.
그런 다음 여러분의 재미를 이용하려는 클라이언트가 이 헤더 파일, 즉 전역 명령문을 포함합니다. 괜찮아요.
그러나 이에 따라 이 고객이 전역 변수를 사용하려면 특정 변수를 외부로 사용해야 하며 그렇지 않으면 정의가 됩니다.
요약하자면:
변수의 경우 이 소스 파일에서 다른 소스 파일의 변수를 사용하려면 사용 전 extern으로 변수를 선언하거나 헤더 파일에서 변수를 선언해야 합니다. extern을 사용하여 변수를 선언합니다.
함수의 경우 이 소스 파일에서 다른 소스 파일의 함수를 사용하려면 사용하기 전에 변수를 선언해야 합니다. extern이 있든 없든 상관없습니다. 따라서 헤더 파일의 함수에 extern을 추가할 필요가 없습니다.
선언은 각 식별자에 대한 공간을 미리 저장하지 않고 각 식별자의 의미를 설명하는 데 사용됩니다. 예약된 저장 공간의 선언을 정의라고 합니다. 선언 형식은 다음과 같습니다. 선언 지정자 declarator 선언자는 저장 클래스 지정자와 유형 지정자로 구성됩니다.
1. 변수를 선언할 때 두 가지 상황이 있습니다. 하나는 저장 공간을 만들어야 합니다.
예: int a는 선언될 때 이미 저장 공간을 생성했습니다.
2. 또 하나는 저장공간을 만들 필요가 없다는 점입니다.
예: extern int a 여기서 변수 a는 다른 파일에 정의되어 있습니다.
예 1:
선언.
속성을 변수 이름이나 함수에 연결하는 구성입니다. 저장 공간이 예약되어 있지 않습니다. 예:
extrn int a;
extrn char c ;
변수 선언 구조 선언은 다음과 같습니다.
정의.
변수 정의는 저장소 할당이 포함된 선언입니다.
struct per_rec
{
int age;
char *surname;
char *firstname;
};
int a;
char c;
struct per_rec person;
함수의 이름, 매개변수 및 반환 유형을 지정하는 구성입니다. 예를 들어 함수 정의는 다음과 같습니다.
long sqr(int num)
{
return(num*num);
}
전자는 "정의 선언" " 또는 "참조 선언"인 "정의"입니다. 넓은 관점에서 보면 선언에는 정의가 포함되어 있지만 모든 선언이 정의인 것은 아닙니다. 예를 들어 int a는 선언이자 정의입니다. 그러나 extern a의 경우 이는 선언일 뿐 정의가 아닙니다. 동일한 소스 프로그램이나 다른 소스 프로그램에서 반복적으로 선언할 수 있습니다. 일반적인 상황에서는 공간을 생성하는 명령문을 "정의"라고 부르고, 저장 공간 생성이 필요하지 않은 명령문을 "선언"이라고 부르며 이렇게 설명하는 경우가 많습니다. 분명히 우리가 여기서 언급하는 진술은 상대적으로 범위가 좁은 진술, 즉 비정의 진술입니다.
예: 메인 함수에서
int main()
{
int a //여기에 정의가 있습니다(할당 공간 선언). ), 반복적으로 나타날 수 없습니다.
//여기에 extern int a; 또는 int a;를 쓰면 VC6.0에서 컴파일할 때 오류가 보고됩니다
//(재정의)
//여기에 int a를 작성하고 DEV-C++에서 오류를 보고합니다. 선언 반복(재선언)
//DEV에서 extern int a를 작성합니다. -C++ , 문제 없이 실행됩니다
extern int A; //이것은 정의가 아니라 선언입니다. 선언 A는 이미 정의된 외부 변수입니다
//참고: 외부 변수를 선언할 때 변수 유형을 제거할 수 있습니다. extern A;
dosth(); //함수 실행
}
int A; //A를 정수형의 외부 변수로 정의하는 정의입니다.
정의할지 선언할지는 때로는 컴파일러의 처리와 관련이 있을 수 있습니다.
외부 변수의 "정의"는 외부 변수의 "선언"과 다릅니다. 외부 변수는 한 번만 정의할 수 있으며 해당 위치는 모든 함수 외부에 있지만 동일한 파일의 외부 변수는 다음과 같습니다. 변수 선언은 여러 번 이루어질 수 있으며, 함수 내에서(사용해야 하는 함수는 모두 해당 함수에서 선언되어야 함) 또는 함수 외부(외부 변수의 정의 지점 이전)에 있을 수 있습니다. 시스템은 외부 변수의 선언이 아닌 외부 변수의 정의에 따라 저장 공간을 할당합니다. 외부 변수의 경우 초기화는 "선언"이 아닌 "정의"에서만 수행할 수 있습니다.
소위 "선언"의 기능은 해당 변수가 나중에 정의된 외부 변수임을 선언하는 것입니다. 이는 해당 변수를 "미리" 참조하기 위해 만든 "선언"일 뿐입니다. extern은 설명만 할 뿐 어떤 정의도 하지 않습니다.
static을 사용하여 변수를 선언하면 두 가지 효과가 있습니다.
(1) 지역 변수를 static으로 선언하면 변수에 할당된 공간은 프로그램 실행 기간 내내 항상 존재합니다.
(2) 외부 변수가 정적으로 선언되면 변수의 역할은 이 파일 모듈로 제한됩니다.
#include "stdafx.h"
1.extern은 변수 선언에 자주 사용됩니다. *.c 파일에서 전역 변수를 선언합니다. *.h에 넣고 extern으로 선언하세요.
2. 함수 선언에 extern 키워드가 포함된 경우 해당 함수가 다른 소스 파일에 정의될 수 있다는 의미일 뿐이며 다른 효과는 없습니다. 즉, 다음 두 함수 선언 사이에는 차이가 없습니다:
extern int f(); 및 int f();
=========== === ===============
함수를 정의하는 c/cpp 파일이 해당 헤더 파일에 정의된 함수를 선언하는 경우 다음에서 사용해야 합니다. 기타 c/cpp 파일 이러한 함수에는 이 헤더 파일만 포함하면 됩니다.
헤더 파일을 포함하지 않으려면 c/cpp에서 함수를 선언하세요. 일반적으로 "extern"은 이 파일에 정의된 함수를 선언하는 데 사용되지 않고 "extern"은 다른 파일에 정의된 함수를 선언하는 데 사용됩니다. 이렇게 하면 이 파일에서 다른 파일에 정의된 함수를 호출할 때 필요가 없습니다. 헤더 파일을 포함하려면
include "*.h"를 사용하여 함수를 선언하고, 선언 후에 바로 사용하세요.
=========================================================== ================================================= ================================================
예:
//extern.cpp 콘텐츠는 다음과 같습니다.
// extern.cpp : 콘솔 애플리케이션의 진입점을 정의합니다.
//
#include "stdafx.h"
extern print(char *p);
int main(int argc, char* argv[] )
{
char *p="hello world!";
print(p);
return 0;
}
//print.cpp의 내용은 다음과 같습니다
#include "stdafx.h"
#include "stdio.h"
print(char *s)
{
printf("The string is %sn ",s);
}
결과 프로그램은 정상적으로 실행되어 결과를 출력할 수 있습니다. "extern"을 제거해도 프로그램은 계속 정상적으로 실행될 수 있습니다.
함수 선언에 "extern"이 필요하지 않음을 알 수 있습니다. 이는 해당 함수가 이 파일에 정의되어 있는지 아니면 다른 파일에 정의되어 있는지를 나타내는 데에만 사용됩니다. 함수를 사용하기 전에 선언했다면 헤더 파일을 포함할 필요가 없습니다.
C 언어에서 extern 수정자는 변수나 함수 선언 앞에 사용되어 "이 변수/함수는 다른 곳에 정의되어 있으며 여기에서 참조되어야 함"을 나타냅니다.
0. 외부 수정 변수 선언. 예를 들어 파일 a.c가 b.c의 변수 int v를 참조해야 하는 경우 a.c에서 extern int v를 선언한 다음 변수 v를 참조할 수 있습니다. 여기서 주목해야 할 점은 참조되는 변수 v의 링크 속성이 외부 링크(external)여야 한다는 것입니다. 즉, a.c가 v를 참조하려면 a.c에서 extern int v의 선언에만 의존하는 것이 아니라, 그러나 변수 v 자체에 따라 달라질 수도 있습니다. 여기에는 C 언어의 또 다른 주제인 변수 범위가 포함됩니다. extern 수정자를 사용하여 다른 모듈에서 참조할 수 있는 변수는 일반적으로 전역 변수입니다. 또 다른 매우 중요한 점은 extern int v가 a.c의 어느 위치에나 배치될 수 있다는 것입니다. 예를 들어 a.c에서 fun 함수 정의의 시작 부분에 extern int v를 선언한 다음 변수 v를 참조할 수 있습니다. 그게 전부입니다. fun 함수 범위에서만 v를 참조할 수 있습니다. 이는 여전히 변수 범위의 문제입니다. 이에 대해 많은 분들이 사용시 고민을 하십니다. extern 문은 파일 범위에서만 사용할 수 있는 것 같습니다.
1. extern 수정된 함수 선언. 본질적으로 변수와 함수 사이에는 차이가 없습니다. 함수 이름은 함수의 이진 블록 시작 부분을 가리키는 포인터입니다. 예를 들어 파일 a.c가 b.c의 함수를 참조해야 하는 경우 bc의 프로토타입은 int fun(int mu)이면 a.c에서 extern int fun(int mu)을 선언할 수 있으며 fun을 사용하여 무엇이든 할 수 있습니다. 변수 선언과 마찬가지로 extern int fun(int mu)은 a.c의 어느 위치에나 배치할 수 있으며 반드시 a.c의 파일 범위에 배치할 필요는 없습니다. 다른 모듈의 함수를 참조하는 가장 일반적인 방법은 해당 함수의 선언이 포함된 헤더 파일을 이용하는 것입니다. 함수를 참조하기 위해 extern을 사용하는 것과 헤더 파일을 포함하는 것의 차이점은 무엇입니까? 외부 참조 방법은 헤더 파일을 포함하는 것보다 훨씬 간단합니다! extern을 사용하는 방법은 간단합니다. 참조할 함수를 선언하려면 extern을 사용하세요. 이것은 아마도 KISS 원칙의 표현일 것입니다! 이렇게 하면 분명한 이점은 프로그램 컴파일 프로세스(정확히 말하면 전처리) 속도가 빨라지고 시간이 절약된다는 것입니다. 이 차이는 대규모 C 프로그램을 컴파일하는 동안 매우 분명해집니다.
2. 또한 extern 수정자를 사용하여 C 또는 C++ 함수의 호출 사양을 나타낼 수 있습니다. 예를 들어 C++에서 C 라이브러리 함수를 호출하려면 extern "C"를 사용하여 C++ 프로그램에서 참조할 함수를 선언해야 합니다. 이는 링커가 링크할 때 C 함수 사양을 사용하도록 링커에 지시하는 데 사용됩니다. 주된 이유는 C++과 C 프로그램을 컴파일한 후 대상 코드의 명명 규칙이 다르기 때문입니다.
관련 기사 더 보기 외부 사용법 요약, PHP 중국어 웹사이트를 주목해주세요!