C언어 - 프로그래밍 언어의 문법
1. 언어의 문법
- 인간이 사용하는 언어에는 매우 다양한 문법이 존재하며, 이를 익히는 데에는 많은 시간이 필요하다.
- 명사, 동사, 시제, 어순 등 매우 많은 문법을 익혀야 한다.
- 프로그래밍 언어는 컴퓨터에게 무엇을 어떻게 할지 지시하기 위한 명확한 목적을 가진 언어이다.
- 비교적 적은 수의 문법 요소만으로도 의미의 표현과 실행이 가능하다.
- 사람이 쓰는 언어와 달리 프로그래밍 언어는 몇 가지 핵심 문법만 이해하면 바로 사용이 가능하다.
2. C언어 문법
프로그래밍 언어는 다음과 같이 다섯 가지로 구성되어 있다.
- 변수 - 값을 저장한다.
- 연산 - 값을 계산한다.
- 문장 - 내용을 실행한다.
- 제어 - 실행 순서를 변경한다.
- 함수 - 여러 문장을 하나로 묶는다.
이 다섯 가지만의 문법만 이해해도 프로그램의 기본 구조를 이해할 수 있다.
2.1. 변수 (Variable)
- 변수는 값(value)을 저장하는 메모리 공간에 이름을 부여한 것이다.
- 프로그램은 변수를 통해 데이터를 기억하고, 참조하고, 변경한다.
2.1.1. 변수 타입(Type)
- 변수 타입은 변수가 어떤 종류의 값을 저장하며, 그 값을 어떻게 해석할지를 결정하는 규칙이다.
- 변수 타입에 의하여 저장 가능한 값의 형태, 메모리 사용 방식, 그리고 허용되는 연산의 종류가 결정된다.
int count;
count = count + 1; // int type stores integer values.
char grade = 'A'; // char type stores a single character or small integer values.
float ratio = 0.75f;
ratio = ratio * 100.0f; // float type stores floating-point (real) values.
2.1.2. 상수
- 상수는 값이 바뀌지 않는 변수이다.
- C언어에서 변경되지 않는 변수를 문법적으로 보장하는 방법은
const이다. const로 선언된 변수는 초기화 이후 값의 변경이 허용되지 않는다.- 컴파일러는 해당 변수에 대한 값 변경 시도를 문법 오류로 탐지한다.
const int limit = 10;
limit = 20; // error: assignment of read-only variable
2.1.3. 자료 구조
- 자료 구조는 여러 개의 값을 하나로 묶어 저장하는 방법이다.
int arr[10]; // array
struct Point { // structure
int x;
int y;
};
자료 구조는 하나의 값이 아니라 여러 값을 담기 위해 변수를 구조적으로 구성한 것이다.
2.1.4. 매크로 상수
- 매크로 상수는 이름을 값으로 바꾸는 규칙이다.
- 컴파일이 시작되기 전에, 정의된 이름이 소스 코드 내의 지정된 값으로 단순 치환된다.
다음의 정의는 컴파일 이전에 소스 코드 내의 MAX_COUNT를 모두 5로 치환한다.
#define MAX_COUNT 5
매크로 상수의 특징은 다음과 같다.
- 타입 개념이 없다.
- 단순 문자열 치환 방식이다.
- 어디서 선언했는지 구분하지 않고, 코드 전체에서 그대로 적용된다.
- 컴파일 이전 전처리 단계에서 동작한다.
2.2. 연산 (Operation)
- 연산은 값을 계산해서 새로운 값을 만드는 과정이다.
- 숫자를 더하거나 비교해서 하나의 결과를 만든다.
2.2.1. 산술 연산
count + 1
count - 1
count * 2
count / 2
값을 더하거나 빼고, 곱하고 나눈다.
2.2.2. 비교 연산
count < MAX_COUNT
count == LIMIT
count != 0
두 값을 비교해서 참 또는 거짓을 만든다.
2.2.3. 논리 연산
count > 0 && count < MAX_COUNT
count == LIMIT || count == 0
여러 조건을 묶어 하나의 결과를 만든다.
2.3. 문장 (Statement)
- 문장은 실제로 실행되는 최소 단위이다.
- 프로그램은 문장의 모음이다.
- C언어에서 문장은 반드시 세미콜론(;)으로 끝난다.
- 세미콜론은 하나의 실행 단위가 끝났음을 컴파일러에게 알리는 문법 요소이다.
2.3.1. 주석(Comment)
- 주석은 프로그램의 실행에는 영향을 주지 않으며, 코드에 대한 설명을 남기기 위한 문법 요소이다.
- 컴파일 과정에서 주석은 모두 제거된다.
한 줄 주석 (Single-line Comment)
// 이후의 내용은 해당 줄의 끝까지 주석으로 처리된다.
int count = 0; // Initialize counter
여러 줄 주석(Multi-line Comment)
/* 와 */ 사이에 있는 모든 내용은 여러 줄 주석으로 처리된다.
/*
This function increases the input value by one.
The input value is not modified directly.
The result is returned to the caller.
*/
int increase(int value) {
return value + 1;
}
2.3.2. 대입문
- 대입문은 계산한 값을 변수에 저장하는 문장이다.
count = count + 1;
계산된 결과를 변수에 반영하라는 실행 명령이다.
2.3.3. 호출문
- 함수를 실행하라는 문장이다.
increase(count);
2.3.4. 입출력 문
- 입력과 출력은 함수 호출 형태로 실행된다.
printf("%d\n", count);
scanf("%d", &count);
입출력은 연산이 아니며, 표준 함수를 호출하여 실행되는 하나의 문장이다.
2.4. 제어 (Control)
- 제어는 어떤 문장을 언제 실행할지 결정한다.
- 제어는 조건과 반복으로 나뉜다.
2.4.1. 조건
- 조건은 특정 상황에서만 문장을 실행한다.
if (count == LIMIT) {
break;
}
실행 흐름에 분기를 만든다.
2.4.2. 반복
- 반복은 같은 동작을 여러 번 실행한다.
2.4.2.1. while
while 반복문은 조건을 먼저 검사한 뒤, 조건이 참일 때만 문장을 실행한다.
while (count < MAX_COUNT) {
count = count + 1;
}
2.4.2.2. do-while
do-while 반복문은 문장을 먼저 실행한 뒤, 그 결과를 바탕으로 조건을 검사한다.
do {
count = count + 1;
} while (count < MAX_COUNT);
2.4.2.3. for
for 반복문은 반복 조건과 제어 요소를 한 곳에 모아 표현한다
for (int i = 0; i < MAX_COUNT; i++) {
count = count + 1;
}
2.5. 함수 (Function)
- 함수는 여러 문장을 하나의 기능으로 묶은 것이다.
- 같은 동작을 다시 사용할 수 있게 해준다.
2.5.1. 함수 블록
- 함수의 본문은 { }로 둘러싸인 블록(block)으로 구성된다.
int increase(int value) {
return value + 1;
}
블록은 여러 문장을 하나의 실행 단위로 묶는 문법 구조이다.
2.5.2. 함수 인자
- 함수 인자는 외부에서 함수로 전달되는 값이다.
int printValue(const int value) {
printf("%d\n", value);
return value;
}
const 함수 인자는 함수 안에서 해당 값을 바꾸지 않고 사용만 하겠다는 약속을 문법으로 표현한 것이다.
2.5.3. 함수 반환값
- 함수 반환값은 함수가 실행을 마친 후, 계산한 결과를 호출한 곳으로 돌려주는 값이다.
int increase(int value) {
return value + 1;
}
int count = increase(10);
함수 인자 10을 전달받아 1을 더한 결과를 반환하며, 반환값 11은 count 변수에 저장된다.
2.6. 예제
다음 예제는 변수, 연산, 문장, 제어, 함수의 다섯 문법 요소를 모두 포함한다.
#include <stdio.h>
#define MAX_COUNT 5
int increase(int value) {
return value + 1;
}
int main() {
const int LIMIT = 3;
int count = 0;
while (count < MAX_COUNT) {
if (count == LIMIT) {
break;
}
count = increase(count);
}
printf("%d\n", count);
return 0;
}
값을 저장하고 → 계산하고 → 실행하고 → 흐름을 바꾸고 → 기능으로 묶는다.
3. C언어 구성
3.1. 예약어
C90 (ANSI C, ISO C90) 기준 C언어 예약어는 32개이다.
autobreakcasecharconst
continuedefaultdodoubleelse
enumexternfloatforgoto
ifintlongregisterreturn
shortsignedsizeofstaticstruct
switchtypedefunionunsignedvoid
volatilewhile
C90 이후 C99와 C11에서는 _Bool, _Complex, inline, _Thread_local, _Alignas, _Static_assert 등의 예약어가 확장되어 자료 표현, 최적화, 멀티스레딩, 정렬, 컴파일 타임 검증을 지원하고 있다.
3.2. 전처리 지시자
C90 (ANSI C, ISO C90) 에서 정의된 전처리 지시자는 12개이다.
#include#define#undef#if#ifdef
#ifndef#elif#else#endif#line
#error#pragma
C90 이후 C99와 C11에서는 새로운 전처리 지시자가 추가되지는 않았으나, #define LOG(fmt, ...) 같은 가변 인자 매크로와 _Pragma("pack(1)")과 같은 전처리 연산자를 통해 표현력과 활용 범위가 확장되었다.
4. C언어 버전
4.1. C90 (ANSI C, ISO C90)
- C90은 1989~1990년에 표준화된 최초의 공식 C 언어 표준이다.
- 기본 자료형, 제어문, 함수, 전처리기 등 C 언어의 핵심 문법과 구조를 확립하였다.
4.2. C99
- C99는 1999년에 제정된 표준으로, 표현력과 실용성 확장에 초점을 두었다.
- 불리언 타입, 복소수,
inline, 가변 인자 매크로, 한 블록 내부 선언 등 현대적인 프로그래밍 기능이 추가되었다.
4.3. C11
- C11은 2011년에 제정되어 멀티코어, 병렬 환경 대응을 목표로 발전하였다.
_Thread_local,_Atomic, 정렬 제어, 컴파일 타임 검사 등 시스템 프로그래밍 강화 기능이 도입되었다.