✅ 1. 자료형과 상수
(1) 자료형의 개념
[ 자료형(data type) 이란? ]
- 컴퓨터에서 값의 표현 방법을 정의한 것
- 쉽게말해, 데이터가 어떤 종류의 값이고, 메모리에서 어떻게 저장되고 처리 될지를 정의하는 규칙을 의미한다.
- 값을 저장하거나 계산을 할 때 자료형을 엄격하게 구분하여 처리함
(2) C 언어 자료형의 종류
[ 기본형 (primitive types) ]
- 언어에서 미리 정의되어 있는 가장 기본적인 데이터 저장 단위를 의미한다.
- 즉, 복잡한 구조 없이 하나의 값만 저장할 수 있는 자료형이다.
- 기본 자료형에는 정수형, 문자형, 실수형 세 가지가 존재한다.
[ 열거형 (enumerated type) ]
// 내부적으로 각 이름에는 0부터 시작하는 정수 값이 자동 할당 됨 ( Sunday = 0 ... )
enum Weekday { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
// 값 직접 지정 가능
enum Weekday { Sunday=1, Monday, Tuesday=5, Wednesday, Thursday, Friday, Saturday };
- 관련 있는 상수들의 이름 집합을 정의할 때 사용하는 자료형이다.
- 쉽게말해, 숫자 값에 이름을 붙여서 쓰는 방법
[ 파생형 (derived types) ]
- 그 외의 자료형은 파생형으로 불린다.
- 배열형(array type)
- 구조체형(structure type)
- 공용체형(union type)
- 포인터형(pointer type)
(3) 기본 자료형의 크기와 값의 범위
[ 문자형과 정수형 ]

- signed, unsigned 는 정수형에서 부호(+,-)를 표현할 수 있는지 여부를 정하는 키워드이다.
- signed: 부호 있는 정수로 양수와 음수 모두 표현이 가능함. ( 디폴트라고 생각하면 됨. )
- unsigned: 부호 없는 정수로 0 이상 양수만 표현이 가능하다. ( -는 사용이 불가 대신 바이트 범위가 0 ~ 255로 넓어짐 )
- 두 가지의 차이는 C 언어 정수형 기본 타입의 디폴트는 signed 로, 내부에서 1바이트는 8개의 비트로 이루어져 있지만 범위로는 7비트(-128 ~ 127) 로 사용이 된다. 나머지 1비트는 부호용으로 씌이게 되는 것이다. 하지만 unsigned 키워드 같은 경우에는 음수를 사용하지 않는 조건으로 1비트를 수로 표현을 해 기존 127 을 255로 늘리게 될 수 있는 키워드이다.
#include <stdio.h>
#include <limits.h>
int main() {
int minInt = INT_MIN;
int maxInt = INT_MAX;
printf("int 자료형 범위: %d ~ %d\n", minInt, maxInt);
}
- 표현할 수 있는 값의 범위는 limits.h에 정의된 값으로 확인할 수 있음.
[ 문자형의 사용 예시 ]
#include <stdio.h>
int main() {
char ch1;
ch1 = 'A';
printf("ch = '%c'\n", ch1);
printf("'%c'의 ASCII 코드 = %d\n", ch1, ch1);
char ch2 = 0x42;
printf("ASCII 코드 %d의 문자 = '%c'\n", ch2, ch2);
}
// 출력 결과
// ch = 'A'
// 'A'의 ASCII 코드 = 65
// ASCII 코드 66의 문자 = 'B'
- 문자는 정수값을 가지고 아스키코드표에 맞게 문자로 표현이 된다.
- 즉, 결국은 정수값이 문자랑 매칭이 되어서 표현이 되는 것이다.
[ 실수형 ]
- 부동소수점 표현방식의 수(IEEE754 기준) 를 의미한다.

#include <stdio.h>
#include <float.h>
int main() {
double minDouble = DBL_MIN;
double maxDouble = DBL_MAX;
printf("double 자료형 범위: %e ~ %e\n", minDouble, maxDouble);
}
- 표현할 수 있는 실수형의 값의 범위는 float.h 에 정의된 값으로 확인할 수 있음.
(4) 열거형
[ 열거형 (enumeration type) 이란? ]
// 내부적으로 각 이름에는 0부터 시작하는 정수 값이 자동 할당 됨 ( Sunday = 0 ... )
enum Weekday { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
// 값 직접 지정 가능
enum Weekday { Sunday=1, Monday, Tuesday=5, Wednesday, Thursday, Friday, Saturday };
- 나열된 단어를 값으로 사용하는 자료형이다
- 나열된 순서대로 0부터 시작하는 정수를 표현함
- 관련 있는 상수들의 이름 집합을 정의할 때 사용하는 자료형이다.
- 쉽게말해, 숫자 값에 이름을 붙여서 쓰는 방법
- 즉, 관련 있는 상수들의 집합을 표현하기 위한 도구이다.
- 자바와는 다르게 정수 상수 집합을 만드는 문법이라 문자열을 넣을 순 없으며, 정수만 가능함.
#include <stdio.h>
int main() {
enum day {SUN, MON, TUE, WED, THU, FRI, SAT};
enum fruit {APPLE, PEAR, MANGO=4, GRAPE};
printf("TUE의 값 = %d\n", TUE);
printf("PEAR의 값 = %d\n", PEAR);
printf("GRAPE의 값 = %d\n", GRAPE);
}
// 결과값
// TUE의 값 = 2
// PEAR의 값 = 1
// GRAPE의 값 = 5
- 이렇게 출력을하게 되면, 정수값이 출력이 되는것을 볼 수 있음.
(5) 상수
[ 상수란? ]
- 항상 고정된 값을 갖는 자료를 의미한다.
- C 언어의 상수 표현은 자료형에 따라 정해진 문법에 따라 값을 표기한다.
- 상수(constant) 변경할 수 없는 값 literal 자체도 상수라고 할 수 있고, const 키워드나 #define 등으로 만든 상수도 포함
[ 정수형 상수 ]
- 10진수, 8진수, 16진수로 표현 가능

#include <stdio.h>
int main() {
// 10진수 정수 상수
const int a = 10; // 10
// 8진수 정수 상수 (앞에 0)
const int b = 012; // 10진수로 10
// 16진수 정수 상수 (앞에 0x)
const int c = 0xA; // 10진수로 10
// 부호 없는 정수 상수
const unsigned int d = 100u;
// long long 정수 상수
const long long e = 123456789LL;
}
- const 키워드를 통해서 상수를 표현 할 수 있음. 해당 부분은 정수형 상수임.
[ 실수형 상수 ]
- 부동소수점 형 상수
- double 형이 기본 자료형임

#include <stdio.h>
int main(void) {
// double형 실수 상수 (기본)
const double a = 3.14159;
// float형 실수 상수 (접미사 f/F)
const float b = 3.14f;
// long double형 실수 상수 (접미사 l/L)
const long double c = 1.23e4L; // 1.23 * 10^4
// 지수 표기법
const double d = 2.5e3; // 2.5 * 10^3 = 2500.0
}
- 실수형 또한 const 키워드를 통해 상수 표현도 가능하며, 다양한 표기 방법이 존재함.
- 해당 지수 표기법의 e 는 10을 의미하며 3은 지수 값을 의미함.
[ 문자형 상수 ]
- 작은따옴표로 묶여 있는 1개의 문자를 의미함.
- 영문자: 'a' ~ 'z', 'A' ~ 'Z'
- 숫자: '0' ~ '9'
- 기호: '+' , '-', '@', '#' 등
- 백색문자: 보이지는 않지만 토큰을 구분해주는 역할을 하는 문자임 ( ' ', '\t', '\n', '\r', '\f' 등 )
- 널(null) 문자('\0')
- 문자형 상수는 내부적으로는 해당 문자의 ASCII 코드값을 저장한다.


[ 문자열 상수 ]
- 큰따옴표(" ")로 묶여 있는 일련의 문자를 의미한다.
- 문자열의 끝을 나타내기 위한 C의 문자열 마지막에는 널 문자('\0)가 자동으로 추가됨
[ 정리 ]
- 여기서 보여준 상수들은 리터럴 상수를 의미함. 값 자체가 상수
- 변수에 const를 통해 상수로 만들면 변수 자체가 불변이 되는 상수가 됨.
- 즉, const 는 변수를 상수로 만들어주고 리터럴 값 자체 또한 상수로 볼 수 있음.
✅ 2. 변수
(1) 변수(variables) 정의 및 특징
[ 변수란 ]
#include <stdio.h>
int main() {
// 정수형 변수
int age = 25;
int year; // 선언만 하고 초기화는 나중에
year = 2025; // 나중에 값 대입
// 실수형 변수
float pi = 3.14f;
double e = 2.71828;
// 문자형 변수
char grade = 'A';
// 여러 변수 동시에 선언
int x = 10, y = 20, z;
// 변수 값 변경
x = 15;
grade = 'B';
}
- 프로그램에서 값을 저장하기 위한 기억공간을 의미함.
- 프로그램 실행 도중 값을 변경할 수 있음
- 모든 변수는 사용하기 전에 미리 선언이 되어야 한다.
- C 에서는 여러 변수를 동시에 선언이 가능함
[ 변수의 특징 ]
- 모든 변수는 변수명 이라는 이름이 존재함
- 모든 변수는 정해진 자료형이 있음.
- 모든 변수는 할당된 값을 갖고 있다.
(2) 변수 선언 시 고려해야 할 사항
- 변수에 저장될 값의 크기 즉, 자료형의 맞는 바이트 크기를 생각해야 함.
- 변수의 선언 위치: 함수 안 또는 밖에서 선언할 수 있으며, 어디에 선언함에 따라서 사용 용도가 달라진다.
- 변수의 초기화: 변수 초기화때 의미있는 데이터를 넣어줘야 한다. 초기화 고려
[ 변수에 저장될 값의 크기에 따라 발생할 수 있는 문제 ]
- 오버플로(overflow): 자료형이 표현할 수 있는 값의 범위를 벗어나면 발생하는 문제이다.
- 언더플로(underflow): 실수형 변수가 표현할 수 있는 가장 작은 양수보다 더 작은 값이 되어 0으로 처리되는 현상임. 컵에 남은 물이 너무 적어 0으로 취급되는 것과 비슷합니다.
[ 변수의 선언 위치 ]
- 전역변수: 함수 외부에 선언 된 변수를 의미하며, 모든 함수에서 호출이 가능하다.
- 지역변수: 함수 내부의 선언 된 변수를 의미하며, 해당 함수 내부에서만 사용이 가능함.
✅ 3. 선행처리기
(1) 선행처리(preprocessing) 란?
- 컴파일에 앞서 소스 프로그램을 가공하여 컴파일러가 실제로 번역할 소스 프로그램을 만드는 것
- 즉, C의 선행처리기는 컴파일 과정 이전에 소스 코드를 미리 가공하는 프로그램이다.
- 쉽게말해, 선행처리는 컴파일 전에 미리 처리되는 명령을 의미한다.
- 선행처리 지시어로 지시하며, 선행처리 지시어는 '#' 으로 시작한다.
- 선행처리 지시어 문장은 한 행에 한 개의 문장을 작성할 수 있으며, 문장의 끝에 세미콜론을 사용하지 않는다.
[ 대표적인 선행처리 ]
- 헤더파일 포함: #include
- 매크로 선언 및 해제: #define, #undef
- 조건부 컴파일: #if, #else, #elif, #endif
(2) #include 지시어 - 헤더파일 포함
- 컴파일러가 소스 코드를 컴파일하기 전에, 지정된 파일의 전체 내용을 현재 파일의 해당 위치에 복사해넣는 역할을 함.
- 지정된 파일은 헤더파일 이라고하며 해당 파일을 가져와 #include 지시어 부분에 붙혀 넣게됨.
- 즉, 가장 상단에 배치가 될 수 있게 됨.
// 표준 디렉토리에서 파일을 찾음
#include <파일명>
// 현재 사용 중인 디렉토리, 또는 직접 지정한 경로에서 파일을 찾음
#include "파일명" // #include "aaa/aaa.h
- C에서는 표준 디렉토리를 정해두었기 때문에 해당 폴더에 파일을 넣게되면 찾아서 가져오는게 가능함.
(3) 매크로 정의
[ 매크로(macro) 란? ]
- 특정 코드 패턴으로 치환되도록 정의된 명칭을 의미한다.
- '#define' 지시어를 사용하여 자주 사용되는 명령이나 수식 또는 상수에 이를 대표하는 이름(매크로 이름)을 붙여 사용함.
- 결론은 컴파일전 약속된 이름인 매크로를 실제 코드나 값으로 바꾸는 것이며, 이것은 컴파일 전 상수 정의나 함수 정의로 볼 수 있지만, 예시로 #define Max_SIZE 100 이라고 define 지시어를 이용하게 될 때 컴파일러가 소스 코드를 읽기 전에 전처리기가 먼저 작동하여 약속된 이름을 실제 코드로 교체하는 작업을 해주게 된다. 이 작업은 소스 코드에 있는 모든 MAX_SIZE 를 찾아 100으로 바꾸는 작업이다.
- 즉, 컴파일 될 원본 문서인 소크 코드를 컴파일 전에 수정하여 컴파일러가 더 효율적이고 완전하게 컴파일 할 수 있도록 해주는 것이다.
- 그리고 매크로는 상수 형태의 매크로, 함수 형태의 매크로 총 두 가지로 나눠진다.
[ 매크로 상수 정의 ]
#include <stdio.h>
// 상수 매크로 정의
#define MAX_NUM 100
int main() {
int score = 85;
// 정의된 매크로 사용
if (score < MAX_NUM) {
printf("점수가 최고 점수(%d)보다 낮습니다.\n", MAX_NUM);
}
return 0;
}
- 컴파일전에 해당 매크로 상수로 정의된 MAX_NUM 의 값을 모두 100으로 치환을 해준다.
- [ #undef 매크로명 ] 을 통해서 매크로 상수를 해제 할 수 있음.
[ 매크로 함수 정의 ]
#include <stdio.h>
// 함수 매크로 정의: #define 매크로명(인스리스트) (수식)
#define C_AREA(X) (3.141592 * (X) * (X))
int main() {
double r = 5.0;
printf(%lf\n", C_AREA(r + 5));
// 내부적으로 이런식으로 치환해서 이용이됨.
//printf("%lf\n", (3.141592 * (r + 5) * (r + 5)));
}
- 인스리스트: 1개 이상의 인수 지정 가능
- 매크로 확장: 인수를 수식에 반영하여 매크로명을 치환한다.
- 주의: 매크로명이 수식의 텍스트로 치환되는 것이므로 적절히 괄호를 사용할 필요가 있음
- 예시 코드와 같이 매크로 함수 사용하는 곳이 컴파일 전에 해당 매크로 함수의 수식으로 치환이 되기 때문에, 함수 값으로 만약 수식을 사용하게 된다면, 괄호가 필요해지게 됨. 즉, 값이 어떤식으로 값이 들어올지 몰라서 괄호를 적절히 사용을 해줘야함.
(4) 조건부 컴파일
[ 조건부 컴파일이란? ]
- 조건에 따라 컴파일할 코드를 선택할 수 있게 하는 것을 의미한다.
- 쉽게말해, 소스 코드를 컴파일할 때 특정 조건에 따라 일부 코드를 포함하거나 제외하는 기능을 의미한다.
- 즉, 조건문이 참인 경우 컴파일될 소스코드에 조건문의 문장이 포함이 되게 할 수 있는것이다.
- 주의: 조건문은 선행처리과정에서 진위 여부를 판단할 수 있어야 하기 때문에 변수 지정이나 함수 호출이 불가능함.
- 조건부 컴파일은 조건으로 씌이는 값 자체가 필요하기 때문에 매크로 기능을 반드시 활용을 하게 된다.
[ 조건부 컴파일 활용 예 ]
#include <stdio.h>
#define DEBUG_MODE 1 // 1은 참으로도 씌임
int main() {
int a = 10, b = 20;
#if DEBUG_MODE
printf("평균을 구할 값: %d, %d\n", a, b);
#endif
printf("평균 = %f\n", (a + b)/2.0);
}
// 조건에 맞게 될 경우 해당 코드로 컴파일이 진행 됨.
int main() {
int a = 10, b = 20;
printf("평균을 구할 값: %d, %d\n", a, b);
printf("평균 = %f\n", (a + b)/2.0);
}
- 조건에 맞을 경우 해당 조건에 맞는 코드로 치환이 되며, 해당 코드가 이후에 컴파일이 되게 됨.
'공부 > ⚙️C' 카테고리의 다른 글
| [C언어] 함수와 기억 클래스(1) (0) | 2025.10.15 |
|---|---|
| [C언어] 선택 제어문과 반복 제어문 (0) | 2025.10.13 |
| [C언어] 입출력 함수와 연산자(2) (0) | 2025.10.03 |
| [C언어] 입출력 함수와 연산자(1) (0) | 2025.09.05 |
| [C언어] C 언어의 개요 (1) | 2025.08.18 |