분할 컴파일 관련된 소스코드끼리 묶어서 .h 파일과 .c 파일로 나눈다 그리고 그 파일들을 각각 컴파일한다 (분할 컴파일) 컴파일 결과인 .o 파일들을 한데 묶어서 빌드하는 방식이다 분할 컴파일 원리 빌드 프로세스에서 컴파일 단계까지는 각각의 .c 파일이 따로 컴파일된다 링크 단계에서 컴파일 완료된 .o 파일들을 묶어서 빌드한다 링킹 단계 전까지는 함수의 정의는 알 수 없다 선언부만으로 컴파일된다 링크 단계에서 각 함수의 정의 부분이 모여서 실행파일이 만들어진다 그래서 예를들어, 정의 부분 add() 함수의 매개변수 자료형이 서로 다르다면 컴파일 에러가 아닌 링크 에러가 발생한다 라이브러리(Library) 오브젝트 파일들을 모아서 묶어 놓은 파일을 라이브러리 파일이라고 한다 즉, 이 라이브러리 파일은 다..
조건부 컴파일 조건에 따라 특정 부분의 소스코드를 컴파일에 포함 혹은 배제시키는 문법이다 #ifndef NULL #define NULL (0) #endif /* NULL이 정의 안되어있다면, 값이 0인 NULL을 정의. */ #if !defined(NULL) #define NULL (0) #endif /* NULL이 정의 안되어있다면, 값이 0인 NULL을 정의. */ #if defined(NULL) #undef NULL #endif /* NULL이 정의되어 있다면, 그 정의를 해제시킴. */ #define NULL (0) /* 값이 0인 NULL을 정의. */ 조건부 컴파일 주의점 #define A #if defined (A) // 참 #define LENGTH (10) #endif #if A // 거..
전처리기(Preprocessor) 프로그래머가 작성한. c 파일을 전처리기는 아래와 같은 전처리 작업을 수행한다 1. 주석 삭제 2. 매크로 처리 (매크로된 것을 모두 복사 붙여 넣기) 3. include 되어 있는 .h 헤더파일 처리 (헤더파일 모두 복사 붙여 넣기) 위와 같은 작업을 통해 만들어진 파일이 Translation unit 파일이다 전처리기 지시자 (#) 전처리기 지시자가 붙은 문을 전처리기 지시문이라고 부른다 ex) #include, #define, #ifndef, #endif, … 전처리기 지시문의 활용 1. 매크로 문법을 통해 텍스트 대체 #define 구문이 대표적이다 소스코드 상의 특정 텍스트를 대체한다 이외에도 #undef 구문 혹은 전처리기 연산자 #, ##을 활용. 2. 다른..
입출력 리디렉션 표준 입력 또는 표준 출력의 소스 또는 대상을 변경하는 기술을 의미한다 이를 통해 프로그램은 사용자 입력이나 출력 대신 파일, 다른 프로세스의 출력 등을 사용할 수 있다 리디렉션은 주로 커맨드 라인 인터페이스(Command Line Interface)에서 사용된다 명령어를 실행할 때 기호를 사용하여 표준 입력 및 표준 출력을 파일로 리디렉션 할 수 있다 입출력 리디렉션 방법 stdin: 문자 stderr: 2> 문자(2번째 출력 ex. 에러 내용 출력) ex) a.exe output.txt 2> error.txt 입출력 리디렉션 예시 #define _CRT_SECURE_NO_WARNINGS #include int main(void) { int ans; scanf("%d", &a..
파일 접근 모드 파일 모드 한정자 파일 접근 모드와 같이 작성해서 사용한다 ex. rb, wt, … 파일 접근 모드, 파일 모드 한정자 예시 with. fwrite() #define _CRT_SECURE_NO_WARNINGS #include enum { LENGTH = 5 }; int main(void) { int data[LENGTH] = { 11, 22, 33, 44, 55 }; size_t count; FILE* out = fopen("output.txt", "wb"); count = fwrite(data, sizeof(data[0]), LENGTH, out); // fwrite() 함수는 binary file을 적을 때 쓰는 함수 // out에 LENGTH개 sizeof(data[0])만큼씩 da..
스트림 데이터 스트림의 약자이다 데이터가 흘러들어오는 선을 의미하며, 다양한 선이 존재한다 데이터 스트림의 종류 stdin 스트림: 키보드를 통한 입력 데이터 스트림 stdout 스트림: 콘솔(콘솔 창)을 통한 출력스트림 File 스트림: 입출력이 가능한 파일스트림 String 스트림: 입출력이 가능한 문자열 스트림 stdin > stdout 일반적으로 많이 사용하는 스트림 형태이다 stdin을 통해서 데이터를 받아서 stdout으로 데이터를 출력한다 스트림 (stdin, stdout, file, string 등)은 경계선 너머의 장치이다 따라서, 버퍼를 통해서 한꺼번에 가져오는 동작이 필요하다 여기서 버퍼는 데이터를 일시적으로 저장하는 메모리 영역이다 만약, 키보드를 잡고 있는 사람이 의도적으로 “cl..
열거형(Enummeration) 매크로 상수와 유사하며 비슷한 종류의 매크로 상수를 여러 개를 동시에 정의하는 것이다 문자열이나 int를 직접적으로 사용하는 것은 가독성에 좋지 않아서 열거형을 사용한다 enum ASCII { ASCII_A = 65, ASCII_B, ASCII_C, ASCII_D }; 열거형 vs. 매크로 상수 매크로 상수는 디버깅에 취약하다 전처리기 단계에서 매크로 상수가 모두 값으로 치환되어 버리기 때문이다 반면에, 열거형은 상수로 치환되지 않고 변수명 그대로 디버깅이 가능하다 또한, 열거형은 메모리를 차지하지 않으면서 동시에 디버깅까지 가능하기 때문에 매크로 상수보다는 열거형을 사용하는 것이 좋다 공용체(Union) 어떤 메모리 주소를 어떤 방식으로 읽을 것인가와 관련된 구조체이다 ..
비트필드(bit field)기본 자료형 중 가장 작은 자료형이 1바이트(8비트)이다하지만, 비트 단위로 사용을 하고 싶다면비트필드를 사용하면 된다일련의 비트를 멤버로 가지는 구조체이다 unsigned char b0 : 1;// unsigned char는 2바이트 자료형이지만 // 1비트만 사용하겠다는 비트 필드가 적용되었다 비트 플래그(bit flag)비트필드 문법을 가지고 비트 플래그를 구현할 수 있다#include struct bitflags{ unsigned char c0 : 1; unsigned char c1 : 1; unsigned char c2 : 1; unsigned char c3 : 1; unsigned char c4 : 1; unsigned char c5..
바이트 정렬 요구사항 시스템 별로 메모리에 효율적으로 접근하기 위해서 n 바이트 배수인 시작 주소에서만 메모리 접근이 가능하게끔 한다 예를 들어, x86 시스템은 4바이트 단위로 읽어오고 4바이트마다 정렬(aligned)되어 있다 따라서 각 컴파일러가 알아서 각 멤버의 시작 위치를 그 경계에 맞춰준다 그렇다면, 안 쓰는 바이트를 덧붙이는 경우가 발생하고 이를 패딩(padding)이라고 한다 서로 다른 시스템에서 저장한 파일을 서로 읽으려 할 때, 바이트 정렬 요구사항이 다르면 전혀 다른 데이터가 읽어질 수도 있다 구조체 바이트 정렬 방식 구조체에서 바이트 정렬은 2가지 규칙을 따른다 1. 각각의 자료형 크기의 배수에 해당하는 위치에만 들어간다 2. 끝이나는 구간은 반드시 구조체에서 가장 큰 바이트 배수로..