## 목차
1- 선언 & 정의 개념
2- 전방선언 개념
3- static & extern 개념
4- enum, union 개념
5- 빌드 과정 총정리 (컴파일 언어)
## 선언& 정의
/ 선언 : 이런 변수/함수/타입이 어딘가에 있다 알려주는 것
- 메모리 할당 X
- 보통 <.h> 헤더파일에 들어감 (**헤더파일 : 다른 파일에 제공할 기능 알리는 설명서 역할)
// 선언 예)
int x;
int fn(int a);
/ 정의 : 실제 메모리를 할당하거나 함수 내용 구현
- 보통 <.c> 소스파일에 들어감 (** 소스파일: 알려준 기능들로 실제 작동 구현 담은 파일)
//정의 예)
int x = 10; //메모리 생성됨
int fn(int a) {
return a+1;
}
## 전방선언 forward declaration
: 컴파일러에게 어떤 식별자(함수/구조체)가 나중에 정의될 거라고 미리 알려주는 행위
void print_hello(); // forward-declare
int main(){
print_hello();
}
void print_hello(){
printf("hello!");
}
## static / extern
/ static (정적)
: 해당 파일 내부에서만 접근가능한 함수/변수 선언할 때 붙는 키워드 (제한 및 유지)
- 주 용도: 해당 파일만의 비공개 함수/변수 만들 때
- 특정 함수 내부에서 변수 앞에 붙이면, 해당 변수 내에서만 접근 가능
(but. 메모리 할당은 전역변수처럼 프로그램 종료시까지 유지됨)
static int priv_val = 10;
static void priv_func(){ .... };
void counter(){
int norm_count = 0;
static int stat_count = 0; #프로그램 시작 시 0으로 초기화, 값 유지(다시 실행 안되는 코드)
norm_count++;
stat_count++;
printf("norm: %d, stat: %d", norm_count, stat_count);
}
counter(); >> norm: 1, stat: 1
counter(); >> norm: 1, stat: 2
/ extern (외부)
: 다른 소스파일에 정의되어 있는 변수/함수를 현재 파일에서 사용하겠다는 것을 컴파일러에게 알리는 키워드(공유 및 선언)
- 주 용도: 분할 컴파일 환경에서 다른 .c파일에 정의된 전역변수를 현재 파일에서 참조할 때
- 정의가 아닌 선언 역할만 함 (메모리 할당X , 단순히 해당 이름의 함수/변수가 어딘가에 정의되어있다 알려주기만)
## file_1.c ========
int shared_d = 50;
## file_2.c ========
extern int shared_d;
void access_shared_d(){
printf("shared data: %d", shared_d); # 50
}
## enum, union
/ enum (열거형)
: 정수형 상수들에 의미있는 이름 부여하는 키워드
- 주 용도: 가독성 높이기, 실수 줄이기
- 자료형: 정수형 상수로 처리됨
- 값 할당: 첫번재요소 0 ~ (1씩 증가) // 사용자가 값 지정 가능
enum Weekday {
SUN, // 0
MON, // 1
TUE, // 2
WED = 5, # 사용자 지정
THU, // 6 (이전 값에서 1 증가)
FRI, // 7
SAT // 8
}
## >> 0,1,5 등의 숫자 대신 SUN,MON 같은 의미있는 이름 사용 가능
enum Weekday today = MON
if (today == WED) {...}
/ union (공용체)
: 여러 멤버 변수가 같은 메모리 공간을 공유하는 특수 자료형
- 주 용도 : 메모리 절약 / 하나의 메모리 영역을 여러 방식으로 해석할 때
- 특징: * union의 크기는 멤버 중 가장 큰 자료형의 크기
* 한 번에 오직 하나의 멤버만 유효한 값 가짐 (한번 저장 시, 다른 멤버 값은 덮어씌어짐/오염됨)
union Data {
int i;
float f;
char c;
}
# union Data 크기: 4Byte (가장 큰 멤버 크기)
## union 사용 ========
union Data my_d;
my_d.i = 10;
print("i 값: %d", my_d.i); # >> i 값: 10
my_d.f = 3.14; # >> f에 값 저장하면, 이전에 저장된 i값은 사라짐
## [소스코드 --> 실행코드] 생성 과정 (컴파일 언어)
# 빌드 과정
1-전처리(Preprocessing)
2-컴파일(Compiling)
3-링킹(Linking)
** cf. 인퍼트리어언어(파이썬 등) - 과정: 소스코드 -> 바이트코드 -> PVM 해석/실행
============
1) 전처리 과정
: ((전처리기))--- 소스코드 수정,확장 작업 (단순 텍스트 치환,조작)
- #include 처리 (헤더파일(.h) 내용을 소스파일에 그대로 "삽입")
- #define 처리 (정의된 매크로를 실제 값/코드로 "치환")
- 주석 제거 (//, /* */ 붙은 텍스트 "삭제")
''' C언어_<매크로> 개념 '''
-역할: 코드 치환, 상수 정의
-구현: #define, #include 등
-처리: 전처리 단계에서 실제 값/코드로 치환됨
-(ex): #define PI 3.14 / #define SQUARE(x) ((x) * (x))
''' 일상_<매크로> 개념 '''
-역할: 반복작업/자동화 프로그램
-구현: python script, AutoHotKey 등의 매크로 프로그램
-처리: 런타임(실행중에)
-(ex): 채팅 매크로(미리 입력한 멘트 자동 반복전송), 티켓팅 메크로(예매버튼 초단위로 자동 클릭) 등
2) 컴파일 과정
: 전처리된 소스파일 --- ((컴파일러, 어셈블러)) ---> 기계어코드
- 컴파일러: 소스코드 문법 오류 검사, 이를 어셈블리어 코드로 번역
- 어셈블러: 어셈블러 코드를 이진 기계어로 최종 변환
3) 링킹
: 기계어코드 --- ((링커)) ---> 최종 실행파일
- 목적파일 병합 (프로젝트의 모든 목적파일들 하나로 합침)
- 심볼 해결 (각 목적파일에 남아있는 외부 참조 심볼의 실제 정의 찾아 연결)
- 라이브러리 연결 (printf()나 scanf() 같은 표준 라이브러리 함수들의 기계어코드 찾아 연결시킴)
- 주소 재배치
> 최종실행파일 내에서 모든 코드와 데이터의 상대적인 위치 결정
> 각 함수/변수가 프로그램 내에서 가지게 될 최종 주소정보 확정
'''C_ 심볼 Symbol'''
# 의미 : 코드 구성하는 식별자(이름)
# 종류 : 함수 이름, 전역변수 이름, 정적변수 이름
# 분류 : 정의 심볼 / 참조 심볼(외부 모듈에서 정의 찾아와야하는 심볼)
-정의 심볼 ex) phase_1()함수를 정의한 phases.c 파일의 phase_1
-참조 심볼 ex) main.c 파일에서 호출하는 phase_1() / printf()
>> 모든 과정을 거쳐 실행 파일이 만들어지면,
모든 함수,변수의 주소가 확정 되어있고 외부 라이브러리함수까지 연결된 완벽한 기계어 프로그램 완성됨
>> os의 로더(loader)에 의해 메모리에 로드되어 바로 실행 가능해짐
'Programming' 카테고리의 다른 글
| [C] 함수 포인터 (개념간단정리) (0) | 2025.10.10 |
|---|---|
| [C] C언어 특성 정리 (4) - 배열,가변인자,전처리명령어 (0) | 2025.10.09 |
| [C] C언어 특성 정리 (2) - 포인터 (0) | 2025.10.08 |