2009-06-25 2 views
7

나는 C가 처음이다. 나는 샘플 코드를 포함하여 C의 "파일 범위"를 설명하는 책을 가지고있다. 그러나 코드는 파일 범위 변수 만 선언하고 초기화합니다. 예를 들어 불법적 인 방식으로 변수에 액세스하려고 시도하여 변수 범위를 확인하지 않습니다. 그래서! 과학 정신으로 실험을했습니다.C에서 전역 변수의 범위를 선언 된 파일로 어떻게 제한합니까?

파일 bar.c :

static char fileScopedVariable[] = "asdf"; 

파일 foo.c :

#include <stdio.h> 
#include "bar.c" 

main() 
    { 
    printf("%s\n", fileScopedVariable); 
    } 
내 책에 따르면

, 구글에, printf()에 대한 호출이 실패 -하지만 그렇지 않습니다. foo.exe은 "asdf"문자열을 출력하고 정상적으로 종료됩니다. 나는 파일 스코핑을 사용하고 싶다. 내가 뭘 놓치고 있니?

+4

static 'file scoped'로 정의 된 변수를 호출하는 것은 잘못된 이름입니다. #included 파일을 모두 재귀 적으로 붙여 넣은 결과로 단일 번역 단위로 제한됩니다. – Eric

답변

15

bar.c를 #include하면 컴파일러가 접하지 전에 전처리 기가 bar.c의 내용을 문자 그대로 foo.c로 복사하는 효과가 있습니다.

포함을 없애고 컴파일러에게 두 파일 (예 : gcc foo.c bar.c)을 컴파일하고 예상대로 불만을 지켜 보도록 안내합니다.

편집 : 컴파일러와 전처리 기가 가장 많이 혼동한다고 생각합니다. 언어 규칙은 컴파일러에 의해 시행됩니다. 선행 처리기는 컴파일러보다 먼저 실행되고 #이 접두어로 붙은 명령에 대해 작동합니다. 모든 전 처리기는 일반 텍스트를 조작합니다. 그것은 코드를 구문 분석하지 않거나 어떤 식 으로든 코드의 의미를 해석하려고 시도하지 않습니다. "#include"지시어는 매우 리터럴입니다.이 지시어는 전 처리기에 "이 파일의 내용을 여기에 삽입하십시오"라고 알려줍니다. 따라서 일반적으로 .h (헤더) 파일에 #include 만 사용하고 헤더 파일에는 함수 프로토 타입과 extern 변수 선언 만 넣습니다. 그렇지 않으면 동일한 함수를 컴파일하거나 동일한 변수를 여러 번 정의하는 결과를 낳을 수 있습니다.

+0

감사합니다. 나는 그것을 작동 시켰어. – Metaphile

0

두 번째 include 명령어를 제거하십시오. 위에서 말했듯이 ...

코드를 컴파일하기 전에 컴파일러에서 사전 처리합니다. 이 단계에서는 #include, #define 등 '#'으로 시작하는 모든 명령어를 처리합니다.

그 단계의 결과를 보려면 gcc -E를 실행하면됩니다 (gcc를 사용하는 경우) .

6

이것은 혼동되는 용어 때문에 발생합니다. C의 file scope은 하나의 번역 단위에만 식별자의 연결을 제한하는 것을 의미하지 않습니다. 또한 범위가 하나의 실제 파일로 제한된다는 것을 의미하지는 않습니다. 대신 file scope은 귀하의 식별자가 전역임을 의미합니다. 여기서 file이라는 용어는 모두 #include, #define 및 기타 사전 처리기 지정 문을 처리 한 텍스트를 나타냅니다.

일반적으로 범위는 하나의 번역 단위에서 적용되는 개념 일뿐입니다. 여러 개의 컴파일이 포함되면 링키지가 시작됩니다.

파일 범위 변수 static을 선언하면 변수 내부 연결이 제공됩니다. 즉, 해당 번역 단위 외부에 표시되지 않습니다.

정적으로 명시 적으로 선언하지 않거나 파일 범위 변수 extern을 선언하면 다른 번역 단위에서 볼 수 있습니다. 즉, 동일한 식별자를 사용하여 파일 범위 변수를 선언하면 해당 식별자 을 동일한 변수에 추가하십시오.

귀하의 경우, foo.cbar.c을 삽입하면 fileScopeVariable의 정의가 컴파일되는 번역 단위에 삽입됩니다. 따라서, 그것은 그 단위에서 볼 수 있습니다.

2

당신이 거기에서하는 것처럼 .c 파일을 #include하지 마십시오. 언어는 그것을 허용하지만, C 코더는 그렇게하지 않습니다. 그렇게하면 사람들의 혼란을 혼란스럽게 할 것입니다. 자신을 포함 할 가능성이 큽니다.

"#include"는 "컴파일러는 다른 파일로 이동하여 코드 컴파일을 시작하기 전에이 파일 앞에 붙여 놓으십시오."라는 의미입니다.

vxWorks 소스 파일 중 하나가이 작업을 수행했기 때문에 하루 종일 혼란에 빠졌습니다. 나는 아직도 그들에 대해 POed되어있다.

+0

고마워, 이제 알 겠어. :-) – Metaphile

+0

"PO 그들"은 무엇입니까? – ziyuang

+0

나는 미래의 모든 헤더 파일들이 C에서 완전히 사라져 버렸다고 믿는다. 그것들은 C가 헤더 포함 typedef와 매크로의 범위를 제어 할 수단이 없기 때문에 존재합니다. C는 typedef가 이미 수행하므로 매크로가 선언 된 범위에서만 매크로를 볼 수있게해야합니다. 헤더는 대부분의 C 코드가 이해할 수없는 이유입니다. 중복 포함은 제어 흐름을 따르는 것을 매우 어렵게하며, 무엇을 포함하고 모든 범위가 관련없는 전역 정의 및 typedef로 오염되어 있습니다. – Dmitry

관련 문제