C, Java, Python ...

어떤 관광지에 관람객을 모집한다고 할 때, 안내판을 작성하는 회의를 하고 있습니다.

  1. 많이 오는 국가순으로 그 국가의 언어로 추가로 작성합니다.
    화장실 toilet
    化粧室 トイレ
  2. 공용어(이를테면 영어)만 추가로 작성합니다.
    화장실
    toilet
  3. 안내판마다 QR코드를 삽입해서 어플을 가지고 있는 사람들이라면 빠르게 적응하도록 합니다.
    화장실  ▦
No. 장점 단점 스타일
1 빠르다. 대부분이 대응된다. 모두 대응하기 어렵다. C: 해당 기계어로 바로 번역
2 영어만 하면, 빠르고, 모두 대응된다. 영어가 쉽지 않다. java: JVM으로 해석가능하도록 번역
3 모두 대응된다. 느리다. 번거롭다. python: 번역하지 않고, 실행시 툴로 번역

어느 관광지를 가든, 상황에 맞춰서 대응할 수 있습니다. C는 빠르기 때문에 주로 기계제어에 쓰이지만 원한다면 대형 어플리케이션도 얼마든지 가능합니다.
즉, 언어의 선택은 환경의 문제에 달린 것이지 어느 언어가 더 우수하다고 보기 어렵습니다.

 임베디드 환경(가전등에 들어가는 MPU)개발을 경험해보지 않은 개발자의 경우, C도 어차피 runtime library가 들어가지 않느냐는 생각을 할지도 모르겠습니다. 실제로도 내가 작성한 C 프로그램이나 게임이 타인의 컴퓨터에서 수행되기 위해서는 Redistribution Code나 .Net Framework가 설치되어야 수행되니 말입니다. (수Gbyte에 이릅니다. 십지어 버전별로 따로 설치해야합니다.)
 비유를 들어 설명하다보면 이런 디테일이 망가지는 것은 어쩔 수 없나봅니다.

 아마도 이런 이유에서 Java나 python에서는 이럴바에 vertual machine을 넣어버리자는 생각을 하게된 것이 아닌가 합리적인 의심이 듭니다.

프로그래밍 관련 썰

용어

용어 의미
코드(code) 인간이 알아볼 수 있는 프로그램 언어
순수 기계어는 binary code(또는 바이너리, bin)으로 구분
컴파일러(compiler) 코드를 바이너리로 번역해주는 도구
크로스 컴파일러(Cross Compiler)는 컴파일 머신과 타겟 머신의 언어가 다를 때, 사용되는 컴파일러
편집기(editor) 코드를 작성하기 위한 도구. 메모장(notepad), emacs, vi, notepad++, ultraeditor, source insight, vscode 등.
MSVS(Micosoft Visual Studio), eclipse, IntelliJ IDEA, Xcode 등 통합개발환경(IDE)을 제공하는 에디터도 다수 존재
통합개발환경 IDE(Integrated Development Environment)는 편집기, 디버거, 컴파일러, 빌드시스템, 버전관리 도구 등을 지원
디버깅(Debug) 예상되지 않은 동작(오류)을 수정하는 행위
runtime(수행 중)발견되므로 문법 오류(syntax error)를 디버깅이라 하지 않음(문법 오류는 실행이 되지 않음)
어셈블리(assembly) 기계어를 인간의 언어로 1:1 메칭한 낮은(직관적인) 단계의 코드
C파일(.c) -> 어셈블리(.s) -> 오브젝트(.o) -> 아카이브(.a, 옵션) -> 실행파일(.exe)

다음은 아래 코드를 어셈블리로 변경한 예제입니다.

C 코드
#include 

int main()
{
    printf("Hello World!\n");
}
컴파일 명령어(option=S(대문자))
gcc -S 1_01_HelloWorld.cpp -o 1_01_HelloWorld.cpp
결과
  .file	"1_01_HelloWorld.cpp"
  .text
  .def	__main;	.scl	2;	.type	32;	.endef
  .section .rdata,"dr"
.LC0:
  .ascii "Hello World!\0"
  .text
  .globl	main
  .def	main;	.scl	2;	.type	32;	.endef
  .seh_proc	main
main:
.LFB133:
  pushq	%rbp
  .seh_pushreg	%rbp
  movq	%rsp, %rbp
  .seh_setframe	%rbp, 0
  subq	$32, %rsp
  .seh_stackalloc	32
  .seh_endprologue
  call	__main
  leaq	.LC0(%rip), %rax
  movq	%rax, %rcx
  call	puts
  movl	$0, %eax
  addq	$32, %rsp
  popq	%rbp
  ret
  .seh_endproc
  .ident	"GCC: (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders) 12.2.0"
  .def	puts;	.scl	2;	.type	32;	.endef

C 작업 환경설정

다른 언어와 비교

언어 컴파일 동작
C cl.exe(또는 gcc.exe)로 수행 결과물 직접 실행
Java javac.exe로 수행 java.exe를 통해 실행
python py.exe로 실행

앞으로 이 두가지 목표를 수행하면 C를 개발/실습할 수 있는 환경이 준비가 끝납니다.

컴파일러를 구하기 앞서서 컴파일러에 대해서 간단하게 알아봐야 합니다.

칩의 언어를 각각 대응한다는 말은 칩셋 제조사마다 C언어 번역기(컴파일러)가 있어야 한다는 의미입니다. 다행히 C언어는 매우 간단한 언어이기 때문에 거의 모든 제조사는 칩셋을 구매하는 고객에게 컴파일러를 제공합니다. 앞으로 다룰 주제가 범용PC에서 Windows를 설치하고 그 위에 돌아가는 프로그램을 만들어야 하기 때문에 이에 적합한 컴파일러를 구해야합니다.


외국 자료에는 이 프로그램이 이런 기능을 하고, 이 행위를 왜 하는지에 대한 설명을 자세히 기술한 문서가 종종 눈에 띄는 반면, 국내 문서들은 일단 따라해보자는 취지가 많은 것 같습니다.
 APM(apache + php + mySQL)이나, eclipse, Visual Studio와 같이 통합환경을 제공하는 툴은 왜 라는 질문을 할 이유가 없었던 것 같습니다. 오픈마켓형태인 Visual Studio Code환경을 만들면서, 해야 할 것들이 늘어난건 아쉬운 일입니다. 게다가 그냥 문자나 디엠을 쓰면 되는데 카톡을 왜 설치해야하는지도 설명해야하지 않습니까?

컴파일러

C컴파일러인 gcc컴파일러는 Linux OS를 타겟으로 하기 때문에, Windows환경에서 컴파일러를 따로 설치해 주어야 합니다. 아래사이트는 minGW(minimalist for GCC for Windows)를 다운로드 받을 수 있는 사이트입니다.

https://winlibs.com/#download-release

최신버전의 UCRT 64bit 7-Zip(용량이 작은)을 다운로드 받습니다. 압축을 해제하면 mingw64폴더가 나옵니다. C:\mingw64폴더에 넣는 예제도 있습니다. 선택입니다. 저는 C:\program files\mingw64에 넣었습니다.

시스템 환경 변수 편집

mingw64이하 bin폴더의 gcc.exe와 같은 프로그램을 수행하는 것이 목표이기 때문에 path에 해당 폴더를 등록하면 앞으로 편하게 사용할 수 있습니다.
제 경우 Path에 다음 경로를 추가하였습니다.

Path
C:\Program Files\mingw64\bin
정상적으로 설정되었는지 확인하는 방법은:
C:\Users\iseoh>gcc --version
gcc (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

컴파일러 버젼과 C++표준은 다릅니다. 다음은 c++표준을 정리한 것입니다.

C++ 표준 발행 연도 -std 옵션 주요 변경 사항
C89 1989 c89 프로토타입 부재, "void"부재, '//'주석 미포함
C99 1999 c99, C++98 한줄 주석 지원, 가변길이 배열(VLA)추가 등
C++11 2011 c11, c++11 자동 형식 추론(auto), 오른 값 참조(Rvalue Reference, &&), 초기화 리스트(Initializer Lists) 등
C++14 2014 c++14 제네릭 람다 표현식(Generic Lambda Expressions), 이진 리터럴(Binary Literals), 유니코드 문자열 리터럴(Unicode String Literals)등 *MSVS default
C++17 2017 c17, c++17 구조화 바인딩(Structured Bindings), 표현식 평가 순서 변경(Evaluation Order of Expressions), 파일 시스템 라이브러리(Filesystem Library)등*GDB default
C++20 2020 c2x, c++20 개선된 모듈 시스템(Improved Modules), 공식적인 코루틴 지원(Coroutineds), 레인지 기반 for 루프(Range-based for Loop)확장 등
C++23 2023 latest (support?) 표준라이브러리 지원(import std), 코루틴 지원 등

에디터

VS Code를 사용합니다. VS Code는 범용 에디터이기 때문에 C용 환경설정을 추가로 해주어야 합니다.

C/C++ Extension Pack

이 확장팩은 실질적으로 컴파일러를 제공하지는 않고, 컴파일러 명령으로 나온 결과물을 VSCode의 환경에 맞게 출력하는 기능을 도와준다. 아래 페이지는 참조를 위한 페이지이고, 툴에서 Ctrl + shift + X로 검색해서 설치하면 된다.

https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools-extension-pack

.json 설정

json은 VSCode가 체택한 데이터 관리기법입니다. Excel파일과 같이 데이터를 저장하는 약속 중 하나입니다. 리스트는 []로, MAP은 {}로 표현하는 방식으로 기술됩니다.

작업디렉토리 이하 .vscode폴더에 아래와 같은 파일을 생성(또는 자동생성됨)하면 VSCode가 알아서 읽어가는 방식입니다.

참고: https://code.visualstudio.com/docs/cpp/config-mingw
파일명 설명
c_cpp_properties.json 컴파일러 경로와 IntelliSense(자동완성)을 기술합니다.
launch.json 디버거 조건을 기술합니다.
tasks.json 컴파일 조건을 기술합니다.


다음은 각 설정 예시입니다.

c_cpp_properties.json
{
  "configurations": [
      {
          "name": "Win32",
          "includePath": [
              "${workspaceFolder}/**"
          ],
          "defines": [
              "_DEBUG",
              "UNICODE",
              "_UNICODE"
          ],
          "compilerPath": "C:\\Program Files\\mingw64\\bin\\gcc.exe",
          "cStandard": "c17",
          "cppStandard": "gnu++17",
          "intelliSenseMode": "windows-gcc-x64"
      }
  ],
  "version": 4
}
tasks.json
{
  "tasks": [
      {
          "type": "cppbuild",
          "label": "C/C++: gcc.exe build active file",
          "command": "C:\\Program Files\\mingw64\\bin\\gcc.exe",
          "args": [
              "-fdiagnostics-color=always",
              "-g",
              "${file}",
              "-lstdc++", 만약, C++ 표준 라이브러리를 추가하려면 이 옵션을 추가합니다.
              "-o",
              "${fileDirname}\\${fileBasenameNoExtension}.exe"
          ],
          "options": {
              "cwd": "C:\\Program Files\\mingw64\\bin"
          },
          "problemMatcher": [
              "$gcc"
          ],
          "group": {
              "kind": "build",
              "isDefault": true
          },
          "detail": "Task generated by Debugger."
      }
  ],
  "version": "2.0.0"
}

C++표준라이브러리를 추가하지 않고 namespace를 사용하면, Error "undefined reference to 'std::cout'"에러가 발생합니다.

앞으로 간단한 프로그램을 작성하고 F5를 눌러 실행해 볼 수 있습니다.
int main() {
  printf("Hello World");
}

MSVS(Visual Studio 2022)

에디터를 VScode를 설치했다면, 설치하지 않아도 됩니다. Visual Studio는 용량이 크고, 회원가입이 필요합니다. 컴파일러를 내장하고 있기 때문에(All-in-one)설정이 간편합니다.
https://visualstudio.microsoft.com/ko/

UTF-8

Visual Studio와 command(windows) 기본적으로 EUC-KR을 사용합니다. 다만, EUC-KR은 다국어 지원에서 불리한 코딩방법이고, 따라서 공유와 배포를 위해 UTF-8을 사용하는 것이 좋습니다. 따라서 UTF-8로 세팅하는 방법을 안내합니다.

cmd

chcp는 코드 페이지(code page)를 확인/변경하는 명령어입니다. default setting은 euc-kr(949)입니다. 변경을 위해서:

1회 사용하는 방법
chcp 65001
영구 변경하는 방법
\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\Autorun "chcp 65001"

만약 autorun이 없다면, "우클릭" > 새로만들기 > 문자열 값(S) > "Autorun" 생성 > "chcp 65001" 입력

Visual Studio Setting

"메뉴" > "디버그" > "... 속성 페이지" > "C/C++" > "명령줄" > "추가 옵션(D)"에 다음을 추가
/source-charset:utf-8

예제코드 다운로드

코드는 https://github.com/iseohyun/C-tutorial에서 확인 할 수 있습니다. git clone주소는:
https://github.com/iseohyun/C-tutorial.git