C파일 정리
나는 모든 코딩을 하나의 C 파일로 하는 것에 익숙합니다.하지만 그렇게 하기에는 현실성이 없을 정도로 큰 프로젝트를 진행하고 있습니다.저는 그 파일들을 함께 포함해서 #작업을 해왔지만 여러 번 파일들을 포함해서 #작업을 하는 경우 등을 겪었습니다..h 파일은 들어봤는데 기능이 뭔지 잘 모르겠어요.(아니면 파일이 2개인 이유가 1개인 것보다 더 나은 이유는 무엇인가요?)
코드를 정리하려면 어떤 전략을 사용해야 합니까?특정 파일에 대해 "공개" 기능과 "비공개" 기능을 분리할 수 있습니까?
이 질문이 나의 질문을 촉발시켰습니다.tea.h 파일은 tea.c 파일을 참조하지 않습니다.컴파일러는 모든 .h 파일에 해당하는 .c 파일이 있다는 것을 "알고" 있습니까?
.h 파일을 .c 파일의 인터페이스 파일로 간주해야 합니다.모든 .c 파일은 어느 정도의 기능을 가진 모듈을 나타냅니다..c 파일의 함수를 다른 모듈(즉, 다른 .c 파일)에서 사용하는 경우 함수 프로토타입을 .h 인터페이스 파일에 넣습니다.인터페이스 파일을 원래 modules .c 파일과 필요한 다른 모든 .c 파일에 포함시킴으로써 이 기능을 다른 모듈에서 사용할 수 있도록 합니다.
특정 .c 파일에만 함수가 필요한 경우(다른 모듈에는 없음), 범위를 정적으로 선언합니다.이것은 정의된 c 파일 내에서만 호출할 수 있음을 의미합니다.
여러 모듈에 걸쳐 사용되는 변수도 마찬가지입니다.헤더 파일에 들어가 키워드 'extern(외부)'로 표시해야 합니다.참고: 기능의 경우 'extern' 키워드는 선택 사항입니다.함수는 항상 '외부'로 간주됩니다.
헤더 파일의 포함 가드는 동일한 헤더 파일을 여러 번 포함하지 않도록 도와줍니다.
예를 들어,
모듈 1.c:
#"Module 1"을 포함합니다.h"정적 void My Local Function(void);MyLocalVariable에서 서명되지 않은 정적;MyExternalVariable에서 서명되지 않음;void My External 기능(void){My LocalVariable = 1u;/* 뭘 좀 해봐요 */내 로컬 함수();}static void MyLocalFunction(void){/* 뭘 좀 해봐요 */내 외부 변수 = 2u;}
모듈 1.h:
#ifndef __MODULE1.h#정의 __MODULE1.hMyExternalVariable에서 서명되지 않은 외부;void My External Function(void);#엔디프
모듈2.c
#"Module.1.h" 포함정적 void My Local Function(void);static void MyLocalFunction(void){MyExternalVariable = 1u;내 외부 함수();}
각 .c가 특정한 기능 영역에 초점을 맞추도록 합니다.해당 .h 파일을 사용하여 이러한 기능을 선언합니다.
각 .h 파일에는 내용 주변에 '헤더' 가드가 있어야 합니다.예를 들어,
#ifndef ACCOUNTS_H
#define ACCOUNTS_H
....
#endif
이렇게 하면 "계정"을 포함할 수 있습니다.h" 원하는 횟수만큼, 특정 컴파일 단위에서 처음으로 볼 수 있는 것은 해당 콘텐츠를 실제로 가져오는 유일한 방법일 것입니다.
컴파일러
이 항목에서 C '모듈'의 예를 볼 수 있습니다. 헤더 tea.h와 코드 tea.c의 두 파일이 있습니다.헤더에서 다른 프로그램이 액세스할 수 있도록 하는 모든 공용 정의, 변수 및 함수 프로토타입을 선언합니다.메인 프로젝트에서 #를 포함하고 해당 코드는 이제 헤더에 언급된 티 모듈의 기능과 변수에 액세스할 수 있습니다.
그 이후로 좀 더 복잡해집니다.Visual Studio 및 빌드를 관리하는 여러 IDE를 사용하는 경우에는 이 부분을 무시합니다. 즉, 개체를 컴파일하고 연결하는 작업을 수행합니다.
링커
두 개의 C 파일을 컴파일하면 컴파일러는 개별 개체 파일을 생성합니다. 따라서 main.c는 main.o가 되고 tea.c는 tea.o가 됩니다.링커의 작업은 모든 개체 파일(메인.o 및 tea.o)을 보고 참조를 일치시키는 것입니다. 따라서 메인에서 티 함수를 호출하면 링커가 해당 호출을 수정하여 실제로 티에서 올바른 함수를 호출합니다.링커는 실행 파일을 생성합니다.
이 주제에 대해 더 자세히 설명하는 훌륭한 튜토리얼이 있습니다. 여기에는 여러분이 마주치게 될 범위 및 다른 문제들도 포함되어 있습니다.
행운을 빕니다.
-아담
시작하기 위한 몇 가지 간단한 규칙:
- "공개"할 선언을 작성 중인 C 구현 파일의 헤더 파일에 넣습니다.
- #만 C 파일을 구현하는 데 필요한 헤더 파일을 C 파일에 포함합니다.
헤더 파일 내의 선언에 필요한 경우에만 헤더 파일을 헤더 파일에 포함합니다.
- Andrew OR에서 설명한 include guard 메서드를 사용하거나 컴파일러가 지원하는 경우 #pragma를 한 번 사용합니다(같은 작업을 수행하는 경우도 있습니다).
추가 질문에 대한 답변:
이 질문이 나의 질문을 촉발시켰습니다.tea.h 파일은 tea.c 파일을 참조하지 않습니다.컴파일러는 모든 .h 파일에 해당하는 .c 파일이 있다는 것을 "알고" 있습니까?
컴파일러는 주로 헤더 파일과 관련이 없습니다.컴파일러를 호출할 때마다 소스(.c) 파일을 개체(.o) 파일로 컴파일합니다.뒤에서 (즉,)make
file or project file) 이에 해당하는 명령줄이 생성됩니다.
compiler --options tea.c
원본 파일#include
참조하는 리소스의 모든 헤더 파일을 컴파일러가 헤더 파일을 찾는 방법입니다.
(여기 세부사항을 얼버무리고 있습니다.C 프로젝트 구축에 대해 배울 점이 많습니다.)
위에 제시된 답뿐만 아니라 코드를 모듈(개별 파일)로 분할할 때 얻을 수 있는 작은 이점 하나는 전역 변수가 필요한 경우 'static'이라는 키워드를 사용하여 해당 범위를 단일 모듈로 제한할 수 있다는 것입니다(기능에 적용할 수도 있음).이러한 'static'의 사용은 함수 내부에서의 사용과는 다릅니다.
당신의 질문은 당신이 그다지 진지한 발전을 하지 않았다는 것을 분명히 해줍니다.일반적으로 코드가 너무 커서 하나의 파일에 들어가지 않는 경우가 많습니다.좋은 규칙은 기능을 논리적 단위(.c 파일)로 나누고 각 파일에는 한 번에 쉽게 머릿속에 담을 수 있는 것 이상이 포함되지 않아야 한다는 것입니다.
주어진 소프트웨어 제품은 일반적으로 많은 다른 .c 파일의 출력을 포함합니다.일반적으로 컴파일러는 수많은 객체 파일을 생성합니다(유닉스 시스템 ".o" 파일에서는 VC가 .obj 파일을 생성합니다).이러한 개체 파일을 출력(공유 라이브러리 또는 실행 파일)에 구성하는 것이 "링크러"의 목적입니다.
일반적으로 구현 파일(.c)에는 실제 실행 코드가 포함되어 있는 반면, 헤더 파일(.h)에는 해당 구현 파일에 공용 기능이 선언되어 있습니다.구현 파일보다 헤더 파일을 더 쉽게 가질 수 있으며, 헤더 파일에 인라인 코드가 포함될 수도 있습니다.
구현 파일이 서로 포함되는 것은 일반적으로 매우 드문 일입니다.각 구현 파일을 다른 파일과 구분하여 사용하는 것이 좋습니다.
리눅스 커널의 소스를 다운로드해서 확인해보는 것을 추천합니다.C 프로그램 치고는 꽤 방대하지만, 별도의 기능 영역으로 잘 구성되어 있습니다.
.h 파일을 사용하여 기능의 프로토타입을 정의해야 합니다.이것은 필요한 모든 기능을 하나의 파일에 선언하지 않고 필요한 프로토타입을 C 파일에 포함할 수 있도록 해야 합니다.
예를 들면, 당신이.#include <stdio.h>
, 이를 통해 printf 및 기타 IO 기능의 프로토타입을 제공합니다.이러한 함수의 기호는 기본적으로 컴파일러에 의해 로드됩니다.이러한 파일과 관련된 일반 관용구에 관심이 있는 경우 /usr/include 아래에서 시스템의 .h 파일을 확인할 수 있습니다.
기능이 많지 않은 사소한 애플리케이션만 작성하는 경우에는 모든 것을 논리적인 절차 그룹으로 모듈화할 필요가 없습니다.그러나 대규모 시스템을 개발할 필요가 있는 경우 각 기능을 정의할 위치를 고려해야 합니다.
언급URL : https://stackoverflow.com/questions/47919/organization-of-c-files
'programing' 카테고리의 다른 글
CLion으로 MariaDB의 소스 코드 검색 (0) | 2023.11.04 |
---|---|
yii2에서 데이터베이스에 연결하지 않습니다. (0) | 2023.11.04 |
'utf8' 코덱이 바이트 0 xf3을 디코딩할 수 없습니다. (0) | 2023.11.04 |
알려진 두 문자열 사이의 문자열을 선택하는 SQL 쿼리 (0) | 2023.11.04 |
추가 문자 입력 금지 (0) | 2023.11.04 |