4. 상수의 개념
1) 상수란?
- 상수(Constant)는 프로그램 실행 중 변하지 않는 값을 의미한다.
- 변수(variable)와 달리, 한 번 정해지면 바꿀 수 없다.
- 상수는 데이터의 안정성과 가독성을 높이기 위해 사용한다.
- 종류는 다음과 같다:
· 정수형 상수 (예: 10, -3)
· 실수형 상수 (예: 3.14, -0.5)
· 문자형 상수: 'A'처럼 작은 따옴표로 묶은 한 글자
· 문자열 상수: "A", "Hello"처럼 큰 따옴표로 묶은 글자들의 집합
· 기호 상수: #define 또는 const를 사용해 정의하는 이름 있는 상수
✅ 문자형 vs 문자열 상수 주의!
⚠️ 'A'는 문자형이고, "A"는 문자열이다.
문자형은 한 글자, 문자열은 문자 배열로 처리된다.
2) 정수형 상수
2-1) 정수형 상수란?
- 정수형 상수는 정수 자료형(int, long 등) 변수에 대입할 수 있는 값이다.
- +, - 부호를 붙일 수 있으며, 부호가 없으면 양수로 간주한다.
- C 언어에서는 진법에 따라 다양한 형태의 정수 상수를 사용할 수 있다.
2-2) 진법에 따른 정수 표현
| 진법 | 형태 | 예시 | 설명 |
| 10진수 | 그냥 숫자 | 123 | 기본 정수 표현 |
| 8진수 | 숫자 앞에 0 | 012 | 8진수 10 |
| 16진수 | 숫자 앞에 0x | 0xA, 0XFF | 16진수 10, 255 |
- long형 상수: 숫자 뒤에 L 또는 l을 붙인다. 예: 123L, 0xFFl
- unsigned형 상수: 숫자 뒤에 U 또는 u를 붙인다. 예: 10U, 0xFFu
- 조합 가능: 10UL, 0xffLu
2-3) 정수형 상수의 자료형 접미사 표
| 자료형 | 접미사 | 예시 |
| unsigned int | U, u | 1U, 1u |
| long | L, l | 4L, 4l |
| unsigned long | UL, ul | 7UL, 7ul |
2-4) 10진수 → 2진수 변환
- 방법: 2로 계속 나누고, 나머지를 아래에서 위로 읽는다.
⭕ 예시: 10을 2진수로 변환
1️⃣ 10 ÷ 2 = 5 ... 0
2️⃣ 5 ÷ 2 = 2 ... 1
3️⃣ 2 ÷ 2 = 1 ... 0
4️⃣ 1 ÷ 2 = 0 ... 1
✅ 2진수 결과: 1010
2-5) 2진수 → 10진수 변환
- 각 자릿수 × 2의 제곱으로 계산한다.
⭕ 예시: 1010 (2진수)을 10진수로 변환
1️⃣ (1×2³) + (0×2²) + (1×2¹) + (0×2⁰)
2️⃣ = 8 + 0 + 2 + 0 = ✅ 10 - 8421 방식: 각 자리수에 8,4,2,1 가중치를 곱해 계산하는 방식
⭕ 예시: 1001 → (1×8) + (0×4) + (0×2) + (1×1) = ✅ 9
2-6) 8진수 ↔ 10진수 변환
- 8진수는 0~7까지의 숫자만 사용한다.
- 보통 2진수로부터 3비트씩 묶어서 변환한다.
⭕ 예시: 10진수 65 → 8진수
1️⃣ 65 ÷ 8 = 8 ... 1
2️⃣ 8 ÷ 8 = 1 ... 0
3️⃣ 1 ÷ 8 = 0 ... 1
✅ 8진수 결과: 0101 → 101
⭕ 예시: 8진수 101 → 10진수
(1×8²) + (0×8¹) + (1×8⁰) = 64 + 0 + 1 = ✅ 65
2-7) 16진수 ↔ 10진수 변환
- 16진수는 0
9, AF까지의 숫자를 사용한다.
⛏️ A = 10, B = 11, ..., F = 15 - 소문자 대문자 구분하지 않는다.
⭕ 예시: 10진수 255 → 16진수
1️⃣ 255 ÷ 16 = 15 ... 15
2️⃣ 15 ÷ 16 = 0 ... 15
✅ 결과: 0xFF
⭕ 예시: 16진수 0x1A → 10진수
(1×16¹) + (10×16⁰) = ✅ 26
2-8) 2진수 → 8진수 / 16진수 변환
- 2진수 ➡️ 3자리씩 묶으면 8진수, 4자리씩 묶으면 16진수
⭕ 예시: 2진수 110101
- 8진수: 000 110 101 → 065
- 16진수: 0001 1010 1 → 0x1A (맨 앞에 0 추가해서 4자리 맞춤)
✅ 마무리 정리
1️⃣ 상수는 변하지 않는 값으로, 정수/실수/문자/문자열/기호 상수가 있다.
2️⃣ 문자형 상수는 작은 따옴표('), 문자열 상수는 큰 따옴표(")를 사용한다.
3️⃣ 정수형 상수는 진법에 따라 10진수, 8진수(0), 16진수(0x)로 구분한다.
4️⃣ long형, unsigned형은 접미사(L, U)를 사용한다.
5️⃣ 2진수 변환 시 나머지를 아래서 위로 읽는다.
6️⃣ 8진수는 3자리씩, 16진수는 4자리씩 2진수를 묶는다.
7️⃣ 상수의 표현은 자료형과 목적에 따라 달라진다.
💻 예제 코드
#include <stdio.h>
int main() {
// 정수형 상수 출력
printf("10진수: %d\n", 10); // 기본 10진수
printf("8진수: %o\n", 012); // 8진수 10 (10진수 10)
printf("16진수: %x\n", 0xA); // 16진수 A (10진수 10)
// 부호 없는 상수 (unsigned)
printf("unsigned: %u\n", 10U); // 부호 없는 10
// long형 상수
printf("long: %ld\n", 100000L); // long형 상수
// unsigned long형 상수
printf("unsigned long: %lu\n", 100000UL); // unsigned long 상수
return 0;
}
3) 실수형 상수
3-1) 부동 소수점 상수(Floating Point Literal)
- 실수형 상수는 소수점이 포함된 숫자이며, float형 또는 double형 변수에 대입한다.
- 소수점의 위치가 고정되어 있지 않기 때문에 부동(Floating) 소수점 상수라고 부른다.
3-2) 지수 형식 (Exponential Form)
- 지수 형식은 숫자를 더 간결하게 표현할 수 있는 방법이다.
- 알파벳 e 또는 E를 사용해, **가수부(앞 부분)**와 **지수부(뒤 부분)**로 나눠 표현한다.
- 지수 앞의 + 기호는 생략 가능하다.
⭕ 예시
3.14e2 // 3.14 × 10^2 = 314.0
6.022E23 // 과학 상수(아보가드로 수)
3-3) float형 상수
- 실수 뒤에 f 또는 F를 붙여서 float형 상수로 만든다. (⚠️ 생략하면 double로 처리됨)
- float형은 32bit로 구성되며 구조는 다음과 같다:
⛏️ 부호 1bit, 지수부 8bit, 가수부 23bit
✅ 양수: 부호 0 / 음수: 부호 1
💻 예제 코드
#include <stdio.h>
int main() {
float num = 3.14e2f; // float형 지수 표현
printf("float형 상수 출력: %e\n", num);
return 0;
}
3-4) double형 상수
- 실수형 상수에 아무것도 붙이지 않으면 기본적으로 double형으로 처리된다.
- double형은 64bit 구조로, 저장 범위가 넓다.
⛏️ 부호 1bit, 지수부 11bit, 가수부 52bit
❗ 저장 가능 범위: 2.2E-308 ~ 1.08E+308
💻 예제 코드
#include <stdio.h>
int main() {
double dnum = 6.022E23;
printf("double형 상수 출력: %e\n", dnum);
return 0;
}
4) 문자형 상수
- 문자형 상수는 **작은 따옴표('')**로 감싸서 표현한다.
- 메모리에는 해당 문자의 아스키 코드값이 저장된다.
- 한글은 2byte를 차지하므로 문자형 상수로는 저장되지 않는다.
💻 예제 코드
#include <stdio.h>
int main() {
char ch = 'A';
printf("문자: %c, 아스키코드: %d\n", ch, ch);
return 0;
}
5) 문자열 상수
- C 언어는 문자열 자료형을 직접 지원하지 않는다.
- 문자열은 문자 배열 또는 문자 포인터를 사용하여 처리한다.
- 문자열은 반드시 **큰따옴표(" ")**로 묶어야 하며, 끝에는 자동으로 **'\0' (널 문자)**가 포함된다.
- 문자열 입력 시, scanf()는 공백 전까지만 읽는다.
✅ 공백 포함 문자열 입력은 아래 방법 중 하나를 사용한다:
⭕ scanf("%[^\n]s", str);
⭕ gets(str); (⚠️ 사용 지양, 보안 이슈 존재)
💻 예제 코드
#include <stdio.h>
int main() {
char str[100];
printf("문자열을 입력하세요: ");
scanf("%[^\n]s", str);
printf("입력된 문자열: %s\n", str);
return 0;
}
5-1) 포인터 변수로 문자열 상수 처리
- 포인터 변수는 메모리 주소를 저장하는 변수이다.
- 문자열을 동적 메모리(heap)에 저장할 경우 malloc() 함수로 공간을 확보하고 free()로 해제한다.
💻 예제 코드
#include <stdio.h>
#include <stdlib.h>
int main() {
char *str = (char *)malloc(100 * sizeof(char)); // 메모리 동적 할당
if (str == NULL) {
printf("메모리 할당 실패\n");
return 1;
}
printf("문자열을 입력하세요: ");
scanf("%[^\n]s", str);
printf("입력된 문자열: %s\n", str);
free(str); // 메모리 해제
return 0;
}
6) 기호 상수 (Symbolic Constant)
- 리터럴 상수(직접 입력된 숫자, 문자 등)는 소스 수정이 번거롭다.
- 기호 상수를 사용하면 유지보수가 쉬워진다.
- #define 명령어 사용
- main() 함수 외부에 선언한다.
- 세미콜론(;)을 사용하지 않는다.
- **선행처리기(Preprocessor)**가 컴파일 전 모든 해당 상수를 찾아 대체한다.
- 메모리에 할당되지 않으며 컴파일 시 치환된다.
💻 예제 코드
#include <stdio.h>
#define PI 3.141592
int main() {
printf("원주율: %f\n", PI);
return 0;
}
6-1) const 키워드 사용
- main() 함수 내부에서 사용한다.
- 세미콜론(;)을 반드시 붙인다.
- 변수로 메모리에 저장되며, 값은 변경 불가능하다.
- 자료형을 지정할 수 있어 디버깅에 유리하다.
💻 예제 코드
#include <stdio.h>
int main() {
const float PI = 3.141592; // 상수 선언
printf("원주율: %f\n", PI);
return 0;
}
6-2) #define과 const를 함께 사용
- 두 가지 방식을 함께 사용할 수 있으며, 상수 관리의 유연성을 높인다.
💻 예제 코드
#include <stdio.h>
#define SIZE 100
int main() {
const int max = SIZE; // 기호 상수를 const 변수로 할당
printf("최대 크기: %d\n", max);
return 0;
}
✅ 마무리 정리
1️⃣ 실수형 상수는 float, double로 나뉘며 e/E를 통해 지수 표현이 가능하다.
2️⃣ float형은 f/F를 붙이며, double은 기본값이다.
3️⃣ 문자형 상수는 작은 따옴표, 문자열 상수는 큰 따옴표를 사용한다.
4️⃣ 문자열은 배열 또는 포인터로 처리하고, 동적 할당 시 malloc/free를 사용한다.
5️⃣ 기호 상수는 #define 또는 const로 선언하며 용도에 따라 선택한다.
'Language > C' 카테고리의 다른 글
| 📌 Chapter 05 - 연산자 - 수식과 연산자 (0) | 2025.05.19 |
|---|---|
| 📌 Chapter 04 - 변수와 자료형 - 자료형변환 (0) | 2025.05.17 |
| 📌 Chapter 04 - 변수와 자료형 - 변수의 사용 (0) | 2025.05.17 |
| 📌 Chapter 04 - 변수와 자료형 - 자료형 (0) | 2025.05.17 |
| 📌 Chapter 04 - 변수와 자료형 - 변수의 기초 (0) | 2025.05.17 |