C언어 - 통합 예제 (프로그래밍 언어의 5가지 문법 요소)
1. 통합 예제
다음의 예제는 C 프로그래밍 언어의 5가지 문법 요소(변수·연산·문장·제어·함수)를 모두 사용하고, C90 표준 기준 예약어 32개와 전처리 지시자 12개를 하나의 컴파일 가능한 소스 파일에 담은 종합 예제이다.
- from C언어 - 프로그래밍 언어의 문법
exam.c
/*
* exam.c - C 언어 문법 종합 예제
*
*/
// #include - C 헤더 포함
#include <stdio.h>
#include <stdlib.h>
// #define - 매크로 정의
#define MAX_COUNT 5
#define BUF_SIZE 64
#define DEBUG_LEVEL 0
// #undef - 매크로 정의 해제
#undef DEBUG_LEVEL
#define DEBUG_LEVEL 1
// #ifndef / #endif - 매크로가 정의되지 않은 경우에만 컴파일
#ifndef RELEASE
#define RELEASE
#endif
// #if / #elif / #else / #endif - 조건부 컴파일
#if DEBUG_LEVEL == 0
#define BUILD_TYPE "Release"
#elif DEBUG_LEVEL == 1
#define BUILD_TYPE "Debug"
#else
#define BUILD_TYPE "Unknown"
#endif
// #ifdef / #error / #endif - 특정 매크로가 정의된 경우 컴파일 오류 발생
#ifdef DEBUG_MODE
#error "DEBUG_MODE must not be defined in production builds"
#endif
// #line - 컴파일러 줄 번호를 100으로 재설정
#line 100
// #pragma - 컴파일러 지시문
// 다음 예제는 의도적으로 사용하지 않은 변수 경고를 무시하도록 처리
#pragma GCC diagnostic ignored "-Wunused-variable"
/* ------------------------------------------------------------------ */
/* Type definitions (typedef struct enum union) */
/* ------------------------------------------------------------------ */
// typedef + struct
typedef struct {
int x;
int y;
} Point;
// typedef + union
typedef union {
int i;
float f;
} Number;
// typedef + enum
typedef enum {
STATUS_IDLE = 0,
STATUS_RUNNING = 1,
STATUS_DONE = 2
} Status;
/* ------------------------------------------------------------------ */
/* File-scope storage class keywords */
/* ------------------------------------------------------------------ */
// extern - 다른 .c 파일에 있는 함수를 여기서 사용한다고 알림
extern void external_log(const char *msg);
// static - 내부 연결; 호출 간 값 유지
static int call_count = 0;
// volatile - 일반 흐름 밖에서 값이 바뀔 수 있음
volatile int interrupt_flag = 0;
/* ------------------------------------------------------------------ */
/* Function prototypes */
/* ------------------------------------------------------------------ */
int increase(int value);
void print_info(const char *label, int value);
double compute_average(int *arr, unsigned int size);
void demonstrate_types(void);
/* main 함수 */
int main(void)
{
// auto - 자동(지역) 저장 기간
auto int count = 0;
// const - 읽기 전용 변수
const int LIMIT = 3;
// register - CPU 레지스터 저장 힌트
register int i;
// 기본 자료형 키워드
short s = 10;
long l = 100000L;
unsigned int u = 255u;
signed char sc = -1;
char grade = 'A';
float ratio = 0.75f;
double pi = 3.14159265358979;
// 복합 타입
Point p = {10, 20};
Number num;
Status status = STATUS_IDLE;
int arr[MAX_COUNT];
// static 지역 변수
static int run_count = 0;
// #pragma 동작을 보여주기 위한 의도적 미사용 변수
int unused_var;
// 연산: 산술, 비교, 논리
count = count + 1; // + (산술)
count = count - 1; // - (산술)
u = u / 5; // / (산술)
s = (short)(s * 2); // * (산술)
num.i = (int)pi % 3; // % (산술)
run_count++;
call_count++;
// sizeof 연산자
printf("sizeof(int) = %u bytes\n", (unsigned)sizeof(int));
printf("sizeof(double) = %u bytes\n", (unsigned)sizeof(double));
printf("sizeof(Point) = %u bytes\n", (unsigned)sizeof(Point));
// control: while
while (count < MAX_COUNT) {
if (count == LIMIT) { // if
break; // break
} else { // else
count = increase(count);
}
}
// control: do-while + continue
do {
call_count++;
if (call_count % 2 == 0) {
continue; // continue
}
print_info("call_count", call_count);
} while (call_count < 4); // while
// control: for
for (i = 0; i < MAX_COUNT; i++) {
arr[i] = i + 1;
}
// control: switch / case / default
switch (status) {
case STATUS_IDLE:
status = STATUS_RUNNING;
break;
case STATUS_RUNNING:
status = STATUS_DONE;
break;
default:
break;
}
// control: goto
if (interrupt_flag != 0) {
/*
`goto`는 프로그래밍의 흐름 추적을 어렵게 하므로 예외적
오류 처리 구간을 처리 외에는 가급적 사용하지 않는다.
*/
goto error_exit;
}
// statements: 함수 호출, 입출력
demonstrate_types();
print_info("count", count);
print_info("LIMIT", LIMIT);
print_info("status", (int)status);
printf("build = %s\n", BUILD_TYPE);
printf("grade = %c\n", grade);
printf("ratio = %.2f\n", ratio);
printf("pi = %.5f\n", pi);
printf("short = %d\n", s);
printf("long = %ld\n", l);
printf("uint = %u\n", u);
printf("schar = %d\n", (int)sc);
printf("point = (%d, %d)\n", p.x, p.y);
printf("num.i = %d\n", num.i);
{
double avg = compute_average(arr, MAX_COUNT);
printf("avg = %.1f\n", avg);
}
return 0; /* 반환 */
error_exit:
fprintf(stderr, "Error: interrupt detected.\n");
return 1;
}
/* increase - 값을 1 증가시켜 반환 */
int increase(int value)
{
return value + 1;
}
/* print_info - 문자열 레이블과 정수값 출력 */
void print_info(const char *label, int value)
{
printf("%-6.6s = %d\n", label, value);
}
/* compute_average - int 배열의 산술 평균 계산 */
double compute_average(int *arr, unsigned int size)
{
int sum = 0;
unsigned int j;
for (j = 0; j < size; j++) {
sum += arr[j];
}
return (double)sum / size;
}
/* demonstrate_types - C90 기본 자료형 사용 예시 */
void demonstrate_types(void)
{
signed int si = -10;
unsigned int ui = 10;
short int sh = 5;
long int li = 1000L;
char c = 'Z';
float f = 1.5f;
double d = 2.5;
printf("[types] si=%d ui=%u sh=%d li=%ld c=%c f=%.1f d=%.1f\n",
si, ui, sh, li, c, f, d);
}
exam_func.c
/*
* exam.c에서 extern으로 선언한 함수 구현 파일
*/
#include <stdio.h>
/* extern 함수 예시 */
void external_log(const char *msg)
{
printf("[log] %s\n", msg);
}
- 포함 범위: 변수, 연산, 문장, 제어문, 함수
- 구성 요소: C90 키워드, 전처리 지시자, 구조체/공용체/열거형, 함수 호출 흐름
1.1. 실행 결과
$ gcc -Wall -std=c11 -o exam exam.c exam_func.c $ ./exam sizeof(int) = 4 bytes sizeof(double) = 8 bytes sizeof(Point) = 8 bytes call_c = 3 [types] si=-10 ui=10 sh=5 li=1000 c=Z f=1.5 d=2.5 count = 3 LIMIT = 3 status = 1 build = Debug grade = A ratio = 0.75 pi = 3.14159 short = 20 long = 100000 uint = 51 schar = -1 point = (10, 20) num.i = 0 avg = 3.0
1.2. 제어 흐름
main() starts
│
├─ while (count < MAX_COUNT)
│ ├─ if (count == LIMIT) → break ← exits loop when count becomes 3
│ └─ else → count = increase(count)
│
├─ do-while (call_count < 4)
│ ├─ if (call_count % 2 == 0) → continue ← skips output on even values
│ └─ print_info(...)
│
├─ for (i = 0; i < MAX_COUNT; i++)
│ └─ arr[i] = i + 1 ← initializes to {1, 2, 3, 4, 5}
│
├─ switch (status)
│ ├─ STATUS_IDLE → STATUS_RUNNING
│ ├─ STATUS_RUNNING → STATUS_DONE
│ └─ default → break
│
├─ if (interrupt_flag != 0) → goto error_exit
│
├─ output statements
│
└─ return 0
error_exit:
└─ fprintf(stderr, ...) → return 1