C언어 - 프로그래밍 언어의 문법

1. 언어의 문법

  • 인간이 사용하는 언어에는 매우 다양한 문법이 존재하며, 이를 익히는 데에는 많은 시간이 필요하다.
    • 명사, 동사, 시제, 어순 등 매우 많은 문법을 익혀야 한다.
  • 프로그래밍 언어는 컴퓨터에게 무엇을 어떻게 할지 지시하기 위한 명확한 목적을 가진 언어이다.
    • 비교적 적은 수의 문법 요소만으로도 의미의 표현과 실행이 가능하다.
  • 사람이 쓰는 언어와 달리 프로그래밍 언어는 몇 가지 핵심 문법만 이해하면 바로 사용이 가능하다.

2. C언어 문법

프로그래밍 언어는 다음과 같이 다섯 가지로 구성되어 있다.

  1. 변수 - 값을 저장한다.
  2. 연산 - 값을 계산한다.
  3. 문장 - 내용을 실행한다.
  4. 제어 - 실행 순서를 변경한다.
  5. 함수 - 여러 문장을 하나로 묶는다.

이 다섯 가지만의 문법만 이해해도 프로그램의 기본 구조를 이해할 수 있다.

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, 정렬 제어, 컴파일 타임 검사 등 시스템 프로그래밍 강화 기능이 도입되었다.

이 블로그의 인기 게시물

실행 파일은 파일은 어떻게 동작하는가

게이트 회로로 이해하는 컴퓨터 연산