
여러 소스 파일을 분할 컴파일하여 하나의 실행 파일을 만드는 과정에 대해 알아봅시다.
.obj / 리눅스 기준 .o.exe / 리눅스 기준 확장자 없음main.c, input_num.c, times.c는 동일 폴더에 위치함// main.c
#include <stdio.h>
void input_num(int *, int *); // 두 정수를 입력
int times(int, int); // 첫 정수를 두번째 정수로 곱함
int main(void){
int a, b, result;
input_num(&a, &b);
result = times(a, b); // 계산 결과를 result에 저장
printf("%d와 %d의 곱: %d\n", a, b, result);
return 0;
}
main 함수를 정의. input_num, times 함수는 선언만 하고 정의하지 않음.// input_num.c
#include <stdio.h>
void input_num(int *pa, int *pb){
printf("곱할 두 정수를 입력하시오: ");
scanf("%d%d", pa, pb);
}
input_num 함수를 정의.// times.c
#include <stdio.h>
int times(int a, int b){
return a * b;
}
times 함수를 정의.# gcc -c 소스파일명 -o 목적파일명
gcc -c main.c -o main.obj
gcc -c times.c -o times.obj
gcc -c input_num.c -o input_num.obj
# gcc (목적파일명 여러개) -o 실행파일명
gcc main.obj times.obj input_num.obj -o times_program.exe
# gcc (소스파일명 여러개) -o 실행파일명
gcc main.c times.c input_num.c -o times_program.exe
./times_program
곱할 두 정수를 입력하시오: 13 20
13와 20의 곱: 260
extern과 static의 용도extern: 다른 파일에 선언된 전역 변수를 사용한다.extern 사용 없이 다른 파일의 전역 변수와 같은 이름으로 변수를 선언하면, 이름이 중복되는 다른 변수로 인식되어 오류가 발생할 수 있음extern 선언과 동시에 값을 초기화할 수 없음 (e.g., extern a = 5; -> 불가능)static: 다른 파일에서 전역 변수를 공유하지 못하게 한다.extern으로 사용할 수 없음main.c, input_data.c, average.c는 동일 폴더에 위치함// main.c
#include <stdio.h>
// 함수 선언
int input_data(void); // 양수 입력 -> 합 반환
double average(void); // 평균을 구함
void print_data(double); // 출력
int count = 0; // 입력 양수의 수
static int total = 0; // 입력 양수의 합
int main(void){
double avg; // 입력 양수의 평균
total = input_data();
avg = average();
print_data(avg);
return 0;
}
void print_data(double avg){
printf("입력 양수의 수: %d\n", count);
printf("전체 합과 평균: %d, %.1lf\n", total, avg);
}
count 선언: 다른 파일에서 extern 선언을 사용해 사용할 수 있음.total 선언: 다른 파일에서 사용할 수 없음.total이라는 이름의 다른 변수를 만들 수 있음.// input_data.c
#include <stdio.h>
extern int count; // main.c 파일의 전역변수 count 공유
int total = 0;
int input_data(void){
int num;
while (1){
printf("양수 입력: ");
scanf("%d", &num);
if (num < 0) break;
count++;
total += num;
}
return total;
}
extern 선언을 사용해 main.c 파일의 전역 변수 count를 사용.total은, main.c에서 선언된 정적 전역 변수 total과 별도의 저장 공간을 가짐.// average.c
extern int count; // main.c의 전역 변수 count 공유
extern int total; // input.c의 전역 변수 total 공유
double average(void){
return total / (double)count;
}
extern 선언을 사용해 main.c 파일의 전역 변수 count를 사용.extern 선언을 이용해 input_num.c 파일의 전역 변수 total을 사용.main.c의 정적 전역 변수 total이 아닌, input_num.c의 일반 전역 변수 total임에 유의하기.extern 선언 없이도 다른 파일과 공유 가능.extern 없이 함수 선언만으로, 다른 파일에서 정의된 함수를 사용할 수 있음extern int input_data(void){...}와 같이, 명시적으로 extern을 함수 앞에 붙일 수도 있음.static 키워드로 함수를 정의하면, 함수는 정의된 파일 내부에서만 사용 가능static int input_data(void){....}와 같이 정의할 수 있음extern 변수명을 각 파일에서 선언해야 함extern / 구조체 선언을 헤더 파일로 만들어, 각 파일에 인클루드하면 쉽게 공유 가능extern 선언은 여러 번 중복돼도 상관없지만, 구조체가 중복 선언될 시 오류 발생// point.h
#ifndef _POINT_H_ // _POINT_H_ 매크로 상수가 정의되지 않은 경우
#define _POINT_H_ // _POINT_H_ 매크로 상수 정의
// 점을 나타내는 구조체 (x, y좌표)
typedef struct{
int x;
int y;
} Point;
#endif // #ifndef문의 끝
_POINT_H_ 매크로 상수가 정의되어 있지 않을 때만, _POINT_H_ 매크로 상수를 정의하고, Point 구조체를 정의// line.h
#include "point.h"
// 두 점을 연결하는 선을 정의하는 구조체
typedef struct{
Point first;
Point second;
} Line;
Line 구조체는 "point.h" 파일의 Point 구조체를 멤버로 가지므로, "point.h"를 인클루드// main.c
#include <stdio.h>
#include "point.h"
#include "line.h"
int main(void){
// 점 (1, 3), (5, 11)을 연결하는 선
Line l = {{1, 3}, {5, 11}};
Point p; // 선의 중간점을 나타내는 구조체
p.x = (l.first.x + l.second.x) / 2;
p.y = (l.first.y + l.second.y) / 2;
printf("중간점: (%d, %d)\n", p.x, p.y);
return 0;
}
"point.h"와 "line.h"를 모두 인클루드함"line.h"에서도 "point.h"를 인클루드하므로, Point 구조체가 두 번 선언되는 문제가 발생할 수 있음// point.h
#ifndef _POINT_H_ // _POINT_H_ 매크로 상수가 정의되지 않은 경우
#define _POINT_H_ // _POINT_H_ 매크로 상수 정의
// 점을 나타내는 구조체 (x, y좌표)
typedef struct{
int x;
int y;
} Point;
#endif // #ifndef문의 끝
_POINT_H_를 정의_POINT_H_가 정의되었으므로 #ifndef _POINT_H_는 거짓Point가 정의되지 않음다음 중
extern과static을 사용한 전역 변수에 대한 설명 중 옳지 않은 것을 고르세요.
static을 쓰면 둘 이상의 파일에서 같은 이름의 전역 변수를 각각 선언할 수 있다.
static으로 선언한 정적 전역 변수는 다른 파일에서 사용할 수 없으므로, 다른 파일에서 동일 이름으로 지어도 상관없다.
static을 사용한 전역 변수를 다른 파일에서extern선언으로 공유할 수 없다.
extern선언은 중복이 가능하므로 헤더 파일에 넣어 사용하는 것이 좋다.
extern 선언, 함수 선언은 중복 선언이 가능함. 단 구조체는 중복 선언이 안 되므로, 매크로 상수 선언 등을 통해 중복 선언을 방지해야 함.
- 다른 파일에 있는
static전역 변수를 공유할 때는static선언이 필요하다.
static으로 선언한 전역 변수는 공유할 수 없음.
공부 왜함? velog 보면 되는데