IT 프로그래밍/오픈소스소프트웨어

[오픈소스 소프트웨어] 10-2 프로그램 개발

기술1 2024. 10. 15. 01:07
반응형

다수의 소스 파일로 구성된 프로그램 개발

c프로그램은 여러 개의 소스 파일로 구성됩니다. 관습적으로 각각의 소스 파일은 확장자.C를 가집니다. 하나의 소스파일은 main이라는 함수를 가져야 하며, 거기가 프로그램 실행의 하나지점입니다.

 

프로그램을 여러 개의 소스 파일로 분할할 경우 장점

  • 서로 연관된 함수들과 변수들이 하나의 파일에 있음으로써 프로그램의 구조가 좀 더 알기 쉽고 명료해진다.
  • 각각의 소스 파일들을 개별적으로 컴파일 할 수 있다.
  • 소프트웨어 재사용에 유리하다.

 

압출풀기

 

 

이러면 소스파일을 컴파일해서 실행파일을 만들어줍니다.

 

후위 연산식

posftfix로 바뀌어진 다음에는 어떻게 계산하느냐

  1. 입력 수식에서 연산자 혹은 피연산자를 한번에 하나씩 읽습니다.
  2. 피연산자는 스택에 push합니다.
  3. 연산자가 들어오면 스택으로부터 두 개의 피연산자를 pop하여, 연산자를 계산하고, 그 결과를 다시 스택에 push합니다.
  4. 입력의 끝에 도달하면 스택에는 오직 하나의 값이 남아 있어야 하며, 그것이 계산 결과이다.

Header Files

프로그램을 여러 개의 소스 파일로 분할할 경우 해결해야 할 문제점

  • 어떻게 다른 파일에 정의되어 있는 함수를 호출할 수 있을까?
  • 어떻게 다른 파일에 정의되어 있는 변수를 사용할 것인가?
  • 어떻게 서로 다른 파일들이 매크로나 타입 정의를 공유할 것인가?

해답은 #include에 있습니다. #include 지시어는 여러 개의 소스파일들이 정보를 공유할 수 있게 해줍니다.

 

#include 지시어는 전처리기로 하여금 지정된 파일을 삽입하도록 합니다. 따라서 여러 소스 파일이 고유해야 하는 정보를 헤더 파일에 저장하고, include 지시어를 이용해 그 내용이 소스 파일에 포함되도록 만듭니다.

 

이런 식으로 다른 파일에 소스 코드가 삽입되는 파일을 header 파일이라고 부르며 확장자 .h를 가집니다.

 

<> 와  " "  의 차이는 전처리기는 시스템이 제공하는 헤더파일 디렉토리는 <>를 씁니다. " " 는 현재 디렉토리를 먼저 검사하고 시스템 header파일 디렉토리를 검사합니다. 

 

Macro 와 Type 정의의 공유

대부분의 큰 프로그램들에서는 매크로와 타입을 정의해 사용하며 이를 여러 소스파일이 공유해야 합니다. 이렇게 공유할 정의들은 header파일에 위치해야 합니다.

 

예를들어 boolean.h 파일에서 아래와 같이 매크로 및 타입을 정의

typedef int Bool;
#define TRUE 1
#define FALSE 0

 

 

위의 매크로를 필요로 하는 소스 파일은 다음과 같이 header 파일을 include

#include "boolean.h"

 

두 소스 파일이 boolean.h를 include하는 예

 

함수 프로토타입의 공유

소스 파일에서 다른 파일(foo.c)에서 정의된 함수 f를 호출하는 경우

  • 헤더파일 foo.h에 함수 f의 선언을 넣고, f를 호출하는 파일에서는 헤더파일 foo.h를 include합니다.

또한 foo.c에도 foo.h를 include합니다. 이것은 컴파일러로 하여금 함수 f의 선언과 정의가 일치하는 것을 확인할 수 있도록 하기 위함입니다. 

 

즉 foo.c에 정의된 함수들 중에서 다른 파일에서 호출되는 모든 함수들을  foo.h에서 선언합니다. foo.c 파일 내부에서만 호출되는  함수는 헤더 파일에 선언할 필요 없습니다.

 

서로 다른 파일 간의 변수의 공유

변수의 선언과 정의의 구분

  • 선언 : 컴파일러에게 변수의 존재를 알려줌
  • 정의 : 실제로 메모리를 할당

변수는 여러 번 선언될 수 있습니다. 하지만 정의는 한번만 해야합니다.

 

선언과 정의를 동시에 하는 방법:

int i

키워드 extern을 이용하여 변수를 정의하지 않고 선언만 하는 방법:

extern int i;

extern int a[];

 

즉 선언이랑 컴파일러에게 변수 i와 배열 a 존재(이름과 타입)를 다른 파일에 알려주는 용도

 

  • 전역 변수의 선언은 헤더 파일에 둡니다.
  • 전역 변수를 사용하는 모든 소스 파일은 헤더 파일을 include합니다.
  • 소스 파일 중 오직 한 곳에서 전역 변수를 정의합니다.
file.h
extern int global_variable;

file.c
#include "file.h"

int global_variable;
...
	printf("%d\n", global_variable++);
    
file2.c
#include "file.h"
...
	printf("%d\n", global_variable++);

 

중첩된 include

  • 헤더 파일이 다른 헤어 파일을 include 할 수 있습니다.
  • 예를 들어 stack에서 다음과 같이 bool 타입을 쓰고 싶다면 

동일한 내용이 두 번 include 될 수도 있다는 것입니다. 이는 항상 오류인 것은 아닙니다. 매크로 정의, 함수 프로토타입, 외부 변수의 선언은 여러번 중복되어도 상관 없습니다.

 

하지만 타입 정의가 중복되는 것은 컴파일러 오류를 야기합니다.

 

전통적인 방법

중복된 헤더 파일 문제를 해결하기 위해 #ifndef - #endif지시어를 이용합니다.

 

예)boolean.h 파일이 중복 include되는 것을 방지하기 위해서

#ifndef BOOLEAN_H
#define BOOLEAN_H
#define TRUE 1
#define FALSE 0
typedef int Bool;
#endif

 

혹은

 

pragma 지시어를 사용

  • 헤더의 맨 위에 다음과 같은 전처리 지시어를 추가
  • #pragma once

 

 

반응형